STM32串口发送数据的一段代码理解(纯属个人理解,如有不对,敬请指出)
本人是一位单片机的初学者,最近研究串口发送数据时对以下代码不能理解,通过几天的思考,有所顿悟,特将自己的理解写下来,希望能帮到像我这样的初学者。 代码如下:
void USART2_send_byte(uint8_t byte)
{
while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET);
USART_SendData(USART2,byte);
}
1.理解上述代码时需要的基础知识
(1) 在USART2的发送端有两个寄存器,一个是跟程序对接的USART_DR(数据寄存器,该寄存器包两部分,数据发送寄存器TDR和数据接收寄存器RDR,本帖只讨论发送数据,故只牵扯到TDR);另一个是不跟程序对接的TSR(移位寄存器)负责将数据按位移至TX数据线。 (2)USART_SR(串口状态寄存器)中的两个标志位: 一个是TXE(发送数据寄存器为空):当TDR寄存器的内容已经传输到移位寄存器时,该位由硬件置1。如果 USART_CR1 寄存器中 TXEIE 位 = 1,则会生成中断。 另一个是TC(发送完成):如果已完成对包含数据的帧的发送并且 TXE 置 1,则该位由硬件置 1。如果 USART_CR1 寄存器中 TCIE = 1,则会生成中断。该位由软件序列清零(读取 USART_SR 寄存器,然后写入USART_DR 寄存器)。
2.起初本人对这段代码不理解(误解)之处: (1)如果要发送一段数据,发送数据之前默认标志位TC=1,那么执行 while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET); 这段代码,while后的判断条件为假,程序执行到USART_SendData(USART2,byte); 向串口2发送一段数据,此时数据没有发送完,且根据上面基础知识部分提到的
TC位由软件序列清零(读取 USART_SR 寄存器,然后写入USART_DR 寄存器)。
这一内容,TC将会被清零(TC=0),如果还要接着发送数据,此时While中的判断条件为真,那么程序将会卡死在while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET); 无法执行到USART_SendData(USART2,byte); ,就无法继续发送数据。 (2)如果一开始TC为就默认为0,那么while中的判断条件为真,程序在While处死循环,那不就直接GG?
3.最终对这段程序能够捋得通的理解 首先,在发送数据前,TDR(发送数据寄存器)为空,TSR(移位寄存器)也为空,那么**硬件(此处的硬件不是指MCU)**自动将USART_SR的TC位置1;
其次,发送数据前MCU执行while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET); 这段代码,While中的条件为假,执行下一段程序USART_SendData(USART2,byte); ,此时,MCU向TDR中写入一字节数据,且将TC位清零,MCU做完这些事后执行while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET); 这一段代码,因为while中条件为真,MCU一直在此处循环执行该段程序(等待后面硬件将TC位置1)。
接着,数据写入TDR中以后,由硬件(不是MCU) 接着这一字节数据被移至TSR(移位寄存器)中同时将TXE位置1,随后TSR按位将数据发送至TX数据线,这一字节数据全部发送至TX数据线之后,硬件将TC位置1。
最后,MCU执行程序时检测到TC=1,while中判断条件为假,执行USART_SendData(USART2,byte); 这一段代码,重新向TDR中写入一字节数据,重复上述过程。 纯属个人理解,难免有误,见谅!
|