串口中断通信寄存器即库函数配置编写实例
目录
常用的串口相关寄存器:
USART_SR状态寄存器
USART_DR数据寄存器
USART_BRR波特率寄存器
USART_CR控制寄存器
串口操作相关库函数(省略入口参数)
Void USART_Init(); //串口初始化:波特率,数据字长,奇偶校验,硬件流控以及收发使能
Void USART_Cmd();//使能串口
Void USART_ITConfig();//使能相关中断
Void USART_SendData();//发送数据到串口,DR
Uint16_USART_ReceiveData();//接受数据,从DR读取接受到的数据
FlagStatus USART_GetFlagStatus();//获取状态标志位
Void USART_ClearFlag();//清除状态标志位
ITStatus USART_GetITStatus();//获取中断状态标志位
Void USART_ClearITPendingBit();//清除中断状态标志位
波特率计算方法:
上式中,ƒPCLKx是给串口的时钟(PCLK1用于USART2、3、4、5,PCLK2用于USART1);
USARTDIV是一个无符号定点数。我们只要得到USARTDIV的值,就可以得到串口波特率寄存器USART1->BRR的值,反过来,我们得到USART1->BRR的值,也可以推导出USARTDIV的值。但我们更关心的是如何从USARTDVI的值得到USART->BRR的值,因为一般我们知道的是波特率,和PCLKx时钟,要求的就是USART_BRR的值。
如何通过USARTDIV得到串口USART_BRR寄存器的值。假设我们的串口1要设置为115200的波特率,而PCLK2的时钟为72M。这样,我们根据上面的公式有:
USARTDIV=72000000/(115200*16)=39.0625
那么得到:
DIV_Fraction=16*0.0625=1=0X01;//小数部分
DIV_Mantissa=39=0X27; //整数部分
这样,我们就得到了USART1->BRR的值为0X0271。只要设置串口1的BRR寄存器值为0X0271就可以得到115200的波特率。
USART_InitTypeDef结构体详解:
Typedef struct
{
uint32_t USART_BaudRate; //波特率
uint16_t USART_WordLength;//字长(8bit或9bit位)
uint16_t USART_StopBits;//停止位
uint16_t USART_Parity; //奇偶校验位
uint16_t USART_Mode;//使能发送或使能接受或使能发送接受
uint16_t USART_HardwareFlowControl;//硬件流控制
}USART_InitTypeDef;
串口配置一般步骤:
1.串口时钟使能,GPIO时钟使能:RCC_APB2PeriphCmd();
2.串口复位:USART_DeInit();这一步不是必须的
3.GPIO端口模式设置:GPIO_Init();模式设置为GPIO_Mode_AF_PP
4.串口参数初始化:USART_Init();
5.开启中断并且初始化NVIC(需要开中断的情况下)NVIC_Init(); USART_ITConfig();
6.使能串口:USART_Cmd();
7.编写中断处理函数:USARTx_IRQHandle();
8.串口数据收发:
Void USART_SendData();//发送数据到串口DR寄存器里
Uint16_t USART_ReceiveData();//接受数据,从DR寄存器接受到的数据
9.传输状态获取:
FlagStatus USART_GetFlagStatus(USART_TypeDef * USARTx, uint16_t USART_FLAG);//获取状态
Void USART_ClearITPendingBit(USART_TypeDef * USARTx, uint16_ USART_IT);
调试助手发数据UART1返回接收数据实验源码:
int main(void)
{
/*配置系统中断分组为2位抢占2位响应*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/*RCC配置*/
Rcc_config();
/*GPIO初始化*/
Gpio_Init();
/*USART1初始化*/
Uart1_Init();
/*死循环*/
while(1);
}
/*!
\brief RCC配置
\param[in] none
\param[out] none
\retval none
*/
void Rcc_config(void)
{
/*使能GPIOA时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
/*使能UART1时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
}
/*!
\brief GPIO初始化函数
\param[in] none
\param[out] none
\retval none
*/
void Gpio_Init(void)
{
/*GPIO结构体*/
GPIO_InitTypeDef GPIO_InitTypeDefstruct;
/*UART1发送引脚配置*/
GPIO_InitTypeDefstruct.GPIO_Mode = GPIO_Mode_AF_PP;//推挽复用输出
GPIO_InitTypeDefstruct.GPIO_Pin = GPIO_Pin_9;
GPIO_InitTypeDefstruct.GPIO_Speed = GPIO_Speed_10MHz;
/*写入结构体到GPIOA*/
GPIO_Init(GPIOA,&GPIO_InitTypeDefstruct);
/*UART1接收引脚配置*/
GPIO_InitTypeDefstruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_InitTypeDefstruct.GPIO_Pin = GPIO_Pin_10;
GPIO_InitTypeDefstruct.GPIO_Speed = GPIO_Speed_10MHz;
/*写入结构体到GPIOA*/
GPIO_Init(GPIOA,&GPIO_InitTypeDefstruct);
}
/*!
\brief UART1初始化
\param[in] none
\param[out] none
\retval none
*/
void Uart1_Init()
{
/*UART结构体*/
USART_InitTypeDef USART_InitTypeDefstruct;
/*NVIC结构体*/
NVIC_InitTypeDef NVIC_InitTypeDefstruct;
/*UART结构体配置*/
USART_InitTypeDefstruct.USART_BaudRate = 115200; //波特率
USART_InitTypeDefstruct.USART_HardwareFlowControl =USART_HardwareFlowControl_None; //不使用硬件流
USART_InitTypeDefstruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//发送接收使能
USART_InitTypeDefstruct.USART_Parity = USART_Parity_No; //不使用奇偶校验
USART_InitTypeDefstruct.USART_StopBits = USART_StopBits_1; //1个停止位
USART_InitTypeDefstruct.USART_WordLength = USART_WordLength_8b; //8个数据位
/*写入USART1*/
USART_Init(USART1,&USART_InitTypeDefstruct);
/*使能串口1*/
USART_Cmd(USART1,ENABLE);
/*中断配置*/
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //UART1接收缓冲区非空中断,接收中断
NVIC_InitTypeDefstruct.NVIC_IRQChannel= USART1_IRQn; //USART1中断通道
NVIC_InitTypeDefstruct.NVIC_IRQChannelCmd = ENABLE; //使能USART1中断
NVIC_InitTypeDefstruct.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级
NVIC_InitTypeDefstruct.NVIC_IRQChannelSubPriority = 1;//子优先级
/*写入NVIC中*/
NVIC_Init(&NVIC_InitTypeDefstruct);
}
/*!
\brief UART1中断服务函数
\param[in] none
\param[out] none
\retval none
*/
void USART1_IRQHandler(void)
{
uint8_t Receive;
/*判断是否是接收缓冲区非空中断标志位置位*/
if(USART_GetFlagStatus(USART1,USART_IT_RXNE))
{
/*接收数据*/
Receive = USART_ReceiveData(USART1);
/*发送数据*/
USART_SendData(USART1,Receive);
}
}