这一部分学习STM32的通信协议之一USART
一.USART介绍
USART被称为通用同步异步收发器,可实现全双工数据交换。在USART串口通信中,TX引脚表示发送数据输出,RX表示接受数据输入引脚,剩余的是接地引脚和供电引脚。
在STM32F103C8T6中,具有USART1,USART2,USART3三个通信端口可用,这三种对应GPIO的不同端口,具体选择需要根据端口映射表确定,这在(一)中已经提到过了。
二.软件编写
本例的情景为收发双方使用USART通信。
1.打开时钟。和GPIO一样,USART也是挂载在APB2总线上的外设,因此需要开启APB2总线上的时钟。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
2.GPIO初始化。这在前面中已经讲过,这里不再赘述。
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
3.USART初始化。
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1, &USART_InitStructure);
类似于GPIO的初始化, 需要预先定义USART的指针,再对其结构体成员逐一赋值。
首先,波特率的类型很多,我们常默认为9600Baud即可;
第二,硬件流控制,这只有在硬件流控制模式下才有效,一般我们默认为不使用硬件流控制;
第三,USART的模式选择,因为USART可使用TX发送数据,也可使用RX接收数据,具体使用哪种需要结合实际,因为我们这里的情景是收发双方同时可以通信,故TX和RX引脚都需要用上;
第四,奇偶校验控制选择,由于传送的数据是以帧格式传送的,为保证传送的帧数据的正确率,常常在帧中加入校验位,具体可分为奇校验和偶校验;
第五,停止位设置,一般默认为使用1个停止位;
最后,数据帧的字长,如果使用了奇偶校验则数据帧长一般设置为9数据位,如果没有设置奇偶校验则数据帧长一般设置为8数据位。
4.中断源的配置
这一步与EXTI那一节的中断源配置类似,只不过EXTI的中断源是EXTI,而USART的中断源是USART,哈哈,这里说笑了,总而言之,就是调用的函数不同罢了。下面就是选择了USART1为中断源。
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
5.NVIC的配置
也与EXTI那一节类似,最终所有的中断控制都需要交由NVIC处理后,再进入CPU,所以下面的配置解释请回顾STM32学习(二)中EXTI的相关操作。
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);
6.开启中断源。在完成初始化、中断相关配置后,一定记得使能USART中断。
USART_Cmd(USART1, ENABLE);
7.在产生USART1的中断后,程序会自动跳转到中断入口函数执行相关中断。
在EXTI中本处忘记写了,请大家记住,中断产生后一定要首先判断中断标志位是否符合要求,符合要求才能响应中断,执行完中断后记得查看是否需要手动将中断标志位复位,有的需要手动,有的无需手动,具体可查看手册。
void USART1_IRQHandler(void)
{
if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
{
Serial_RxData = USART_ReceiveData(USART1);
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
}
void USART1_IRQHandler(void)该函数名是默认的,不允许更改,首先判断状态标志位是否被置位,如果被置位说明中断产生了,就可以接收数据了,接受数据后,根据手册,状态标志位自动复位,故无需手动置位,这里为了更加清楚的说明,还是选择了手动复位。