目录:
1、串口1与串口2的相同与不同。
2、串口配置
(1)、GPIO配置
(2)、USART配置
(3)、NVIC配置
3、程序
串口中断配置
发送一个字节(8位数)
发送一个16位数
发送8位的数组
发送字符串
串口1中断服务程序
内容:
一、串口1与串口2的相同与不同
串口时钟不同,GPIO口不同,其他都相同(改成相对应的标志USART1 与USART2):
1、所以串口1与串口2之间相互修改只需要修改时钟和GPIO口:
(串口1):
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_1);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_1);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
(串口2):
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_1);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_1);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
2、void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState):
@param RCC_APB2Periph: specifies the APB2 peripheral to gates its clock.
* This parameter can be any combination of the following values:
* @arg RCC_APB2Periph_SYSCFG: SYSCFG clock
* @arg RCC_APB2Periph_ADC1: ADC1 clock
* @arg RCC_APB2Periph_TIM1: TIM1 clock
* @arg RCC_APB2Periph_SPI1: SPI1 clock
* @arg RCC_APB2Periph_USART1: USART1 clock
* @arg RCC_APB2Periph_TIM15: TIM15 clock
* @arg RCC_APB2Periph_TIM16: TIM16 clock
* @arg RCC_APB2Periph_TIM17: TIM17 clock
* @arg RCC_APB2Periph_DBGMCU: DBGMCU clock
3、void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState)
@param RCC_APB1Periph: specifies the APB1 peripheral to gates its clock.
* This parameter can be any combination of the following values:
* @arg RCC_APB1Periph_TIM2: TIM2 clock
* @arg RCC_APB1Periph_TIM3: TIM3 clock
* @arg RCC_APB1Periph_TIM6: TIM6 clock
* @arg RCC_APB1Periph_TIM14: TIM14 clock
* @arg RCC_APB1Periph_WWDG: WWDG clock
* @arg RCC_APB1Periph_SPI2: SPI2 clock
* @arg RCC_APB1Periph_USART2: USART2 clock
* @arg RCC_APB1Periph_I2C1: I2C1 clock
* @arg RCC_APB1Periph_I2C2: I2C2 clock
* @arg RCC_APB1Periph_PWR: PWR clock
* @arg RCC_APB1Periph_DAC: DAC clock
* @arg RCC_APB1Periph_CEC: CEC clock
二、串口配置:(用串口1为例)
(1)、GPIO配置
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);//
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_1);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_1);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//参考:
参数1:GPIO_Pin引脚: GPIO_Pin_9 - GPIO_Pin_10
参数2:GPIO_Mode模式: 输入GPIO_Mode_IN、输GPIO_Mode_OUT、GPIO_Mode_AF复用功能、GPIO_Mode_AN模拟功能
参数3:GPIO_Speed速度: 低速GPIO_Speed_2MHz、中速GPIO_Speed_10MHz、高速GPIO_Speed_50MHz
参数4:GPIO_OType输出类型(只对输出起作用):推完输出GPIO_OType_PP、漏极输出GPIO_OType_OD
参数5:GPIO_PuPd上下拉: 浮空GPIO_PuPd_NOPULL、上拉GPIO_PuPd_UP、下拉GPIO_PuPd_DOWN
(2)、USART配置
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate=115200;
USART_InitStructure.USART_WordLength=USART_WordLength_8b;
USART_InitStructure.USART_StopBits=USART_StopBits_1;
USART_InitStructure.USART_Parity=USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
USART_Init(USART1,&USART_InitStructure);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
USART_Cmd(USART1,ENABLE);
//参考:
通过结构体USART_InitTypeDef来确定。UART模式下的字段如下:
USART_BaudRate:波特率(每秒能传输的数据位),缺省值为9600。
USART_WordLength:字长
USART_StopBits:停止位
USART_Parity:校验方式(奇偶校验)
USART_HardwareFlowControl:硬件流控制
USART_Mode:单/双工,即收发状态。
最后通过USART_Init()来设置。
(3)、NVIC配置
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//参考:
STM32中断配置优先级,其作用是使能某条中断的触发通道。
STM32的中断有
至多两个层次,分别是抢占优先级(主优先级)和子优先级(从优先级),而整个优先级设置参数的长度为4位,因此需要首先划分抢占优先级位数和子优先级位数,通过NVIC_PriorityGroupConfig()实现;
特定设备的中断优先级NVIC的属性包含在结构体NVIC_InitTypeDef中;NVIC_IRQChannel包含了设备的中断向量,保存在启动代码中;
NVIC_IRQChannelPreemptionPriority为主优先级NVIC_IRQChannelSubPriority为从优先级,取值的范围应根据位数划分的情况而定;
最后NVIC_IRQChannelCmd字段是是否使能,一般置为ENABLE。最后通过NVIC_Init()来使能这一中断向量。
三、程序:
/*Usart.c*/
#include "Usart.h"
#include "stdio.h"
#include "stm32f0xx.h"
u8 server_usart=0;
#pragma import(__use_no_semihosting)
struct __FILE
{
int handle;
};
FILE __stdout;
//¶¨Òå_sys_exit()ÒÔ±ÜÃâʹÓðëÖ÷»úģʽ
void _sys_exit(int x)
{
x = x;
}
uint8_t USART_RX_BUF[USART_REC_LEN]; //½ÓÊÕ»º³å,×î´óUSART_REC_LEN¸ö×Ö½Ú.
u16 USART_RX_STA=0; //½ÓÊÕ״̬±ê¼Ç
void USART1_Configuration(void) //串口中断配置
{
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_1);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_1);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_InitStructure.USART_BaudRate=115200;
USART_InitStructure.USART_WordLength=USART_WordLength_8b;
USART_InitStructure.USART_StopBits=USART_StopBits_1;
USART_InitStructure.USART_Parity=USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
USART_Init(USART1,&USART_InitStructure);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
USART_Cmd(USART1,ENABLE);
}
/***************** 发送一个16位数 **********************/
void Usart_SendHalfWord(uint16_t ch)
{
uint8_t temp_h, temp_l;
/* 高八位 */
temp_h = (ch&0XFF00)>>8;
/* 低八位 */
temp_l = ch&0XFF;
/* 发送高八位 */
USART_SendData(USART1,temp_h);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
/* 发送低八位*/
USART_SendData(USART1,temp_l);
/* 等待发送完成 */
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
/****************** 发送8位的数组************************/
void Usart_SendArray( uint8_t *array, uint16_t num)
{
uint8_t i;
for(i=0; i<num; i++)
{
Usart_SendByte(array[i]);
}
/* 等待发送完成 */
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
}
/***************** 发送一个字节(8位数)**********************/
void Usart_SendByte( uint8_t ch)
{
USART_SendData(USART1,ch);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
/*****************发送字符串**********************/
void Usart_SendString(char *str)
{
unsigned int k=0;
do
{
Usart_SendByte( *(str + k) );
k++;
} while(*(str + k)!='\0');
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET)
{}
}
#if 1
void USART1_IRQHandler(void) //串口1中断服务程序
{
u8 Res;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //½ÓÊÕÖжÏ(½ÓÊÕµ½µÄÊý¾Ý±ØÐëÊÇ0x0D 0x0A½áβ)
{
Res =USART_ReceiveData(USART1);
if((USART_RX_STA&0x8000)==0)
{
if(USART_RX_STA&0x4000)//½ÓÊÕµ½ÁË0x0d //
{
if(Res!=0x0A)
{
USART_RX_STA=0;//½ÓÊÕ´íÎó,ÖØпªÊ¼
}
else
{
USART_RX_STA|=0x8000; //½ÓÊÕÍê³ÉÁË
server_usart = 1;
USART_RX_STA=0;
}
}
else //»¹Ã»ÊÕµ½0X0D
{
if(Res==0x0D)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//½ÓÊÕÊý¾Ý´íÎó,ÖØпªÊ¼½ÓÊÕ
}
}
}
}
USART_ClearITPendingBit(USART1,USART_IT_RXNE); //Çå³ýÖжϱêÖ¾
}
#endif
/*Usart.h*/
#ifndef __USART_H
#define __USART_H
#include "stm32f0xx.h"
#include "stdarg.h"
#include "Stdint2.h"
#define USART_REC_LEN 100 //接收最大字节数
#define EN_USART1_RX
#define RS485_1 GPIOA->BSRR=GPIO_Pin_8;
extern u16 USART_RX_STA; //接收状态标记
extern u8 server_usart;
extern uint8_t USART_RX_BUF[USART_REC_LEN]; //接收缓冲数组´óUSART_REC_LEN¸ö×Ö½Ú.Ä©×Ö½ÚΪ»»Ðзû
//ÅäÖô®¿Ú1
void USART1_Configuration(void);
void USART_Config(void);
void Usart_SendByte(uint8_t ch);
void Usart_SendString(char *str);
void Usart_SendHalfWord(uint16_t ch);
void Usart_SendArray( uint8_t *array, uint16_t num);
#endif