编程实现:
1、这段代码主要实现了在接收到回车符时判断是否接收到换行符,并标志接收完成。在没有接收到回车符的情况下,根据接收到的字符是否为回车符来更新接收状态和保存接收到的数据。最后,重新开启中断以继续接收。
2、UART1_RX_STA & 0x8000) == 0
表示接收未完成。这是通过检查 UART1_RX_STA
寄存器的最高位(bit15)来确定的。在这个条件中,如果最高位为0,就表示接收未完成。因为在这段代码中,接收完成时会将最高位设置为1(UART1_RX_STA |= 0x8000
),因此如果最高位为0,就说明接收还未完成。
3、回车(Carriage Return)的作用是将打印头(或打印滚轴)移回行首,而换行(Line Feed)的作用是将纸上移一行。这两个操作通常结合在一起使用,即先回车再换行,以实现光标的移动到下一行开头。
在计算机系统中,回车符和换行符的概念被继承并广泛应用。而回车符对应的 ASCII 码就是0x0D。
4、UART1_RX_STA = 0;
的作用是将接收状态寄存器 UART1_RX_STA
的所有位都清零,相当于将其重置为初始状态。在这段代码中,这行语句的位置是在接收到回车符(0x0D)但还未接收到换行符(0x0A)的情况下,表示重新开始接收数据。
具体而言,UART1_RX_STA
是一个16位的寄存器,用于记录串口接收的状态。在这个代码中,UART1_RX_STA
的各个位的含义如下:
- bit15(最高位):接收完成标志,如果为1,表示接收已完成。
- bit14:接收到回车符(0x0D)标志,如果为1,表示已经接收到回车符。
- bit13~0:接收到的有效字节数目,记录当前接收到的字节数。
当接收完成时,将 UART1_RX_STA
的最高位设置为1,表示接收完成。而在接收到回车符时,将 UART1_RX_STA
的 bit14 设置为1。当需要重新开始接收时,将 UART1_RX_STA
清零,重新初始化接收状态。这样的设计可以有效地控制串口数据的接收过程。
5、为什么如果没有接收到换行符,可能是接收错误,重新开始?
在串口通信中,通常约定了一种结束符(end-of-line),用于表示一条完整的数据。在这段代码中,回车符(Carriage Return,0x0D
)被视为结束符。
如果接收到的字符不是回车符,那么有可能是接收到了错误的数据或者接收的数据不符合约定的格式。为了确保接收的数据是完整的、正确的,程序选择在没有接收到回车符的情况下将接收状态重置,重新开始接收。
else
{
// 将接收到的数据保存在缓冲区中,使用 UART1_RX_STA 低14位作为索引
UART1_RX_Buffer[UART1_RX_STA & 0X3FFF] = buf;
// 增加接收状态中记录的有效字节数
UART1_RX_STA++;
// 如果接收的数据大于 UART1_REC_LEN(200字节),则重新开始接收
if (UART1_RX_STA > UART1_REC_LEN - 1)
UART1_RX_STA = 0;
}
6、具体步骤:
-
UART1_RX_Buffer[UART1_RX_STA & 0X3FFF] = buf;
:将接收到的数据buf
存储在缓冲区UART1_RX_Buffer
中,使用UART1_RX_STA
的低14位作为索引。这是为了将数据按顺序存储在缓冲区中。 -
UART1_RX_STA++;
:增加接收状态UART1_RX_STA
中记录的有效字节数。这是为了跟踪接收的字节数。 -
if (UART1_RX_STA > UART1_REC_LEN - 1) UART1_RX_STA = 0;
:如果接收的数据字节数超过了缓冲区的大小(UART1_REC_LEN
),则将接收状态UART1_RX_STA
重置为0,重新开始接收数据。这是为了防止缓冲区溢出。
这些步骤的目的是将接收到的数据存储在缓冲区中,并在必要时重新开始接收,以保持缓冲区的有效性。
7、假设我们有一个缓冲区 UART1_RX_Buffer
,长度为10(UART1_REC_LEN
等于10),初始时 UART1_RX_STA
为0。
-
接收到第一个字节(假设是'A'):
UART1_RX_STA
增加到1。UART1_RX_Buffer[0]
被赋值为'A',因为(UART1_RX_STA & 0X3FFF)
等于0。
-
接收到第二个字节(假设是'B'):
UART1_RX_STA
增加到2。UART1_RX_Buffer[1]
被赋值为'B',因为(UART1_RX_STA & 0X3FFF)
等于1。
-
接收到第三个字节(假设是'C'):
UART1_RX_STA
增加到3。UART1_RX_Buffer[2]
被赋值为'C',因为(UART1_RX_STA & 0X3FFF)
等于2。
-
...重复这个过程直到缓冲区满:
UART1_RX_STA
依次增加到7,8,9。UART1_RX_Buffer
依次填充为'D'、'E'、'F'、'G'、'H'、'I'、'J'。
-
再接收一个字节(假设是'K'):
UART1_RX_STA
增加到10。- 由于超过了缓冲区长度,根据代码,
UART1_RX_STA
会被重新设置为0。 UART1_RX_Buffer[0]
被赋值为'K',因为(UART1_RX_STA & 0X3FFF)
等于0。
这样,UART1_RX_Buffer
中的数据被循环写入,确保缓冲区不会溢出。
8、HAL_UART_Receive_IT
函数是在使用 HAL 库时用于启动 UART 中断接收的函数。下面是这个函数的参数解释:
-
&huart1
: 这是指向UART_HandleTypeDef
结构体的指针,表示你要配置的 UART 外设。huart1
应该是你配置的 UART1 的实例,其类型为UART_HandleTypeDef
。 -
&buf
: 这是一个指向缓冲区的指针,用于存储接收到的数据。在这个例子中,buf
是一个变量,&buf
取得了这个变量的地址,所以 UART 接收到的数据将会存储到buf
所在的内存位置。 -
1
: 这是期望接收的字节数。在这里,设置为1表示每次接收一个字节。如果你期望接收更多的字节,可以调整这个参数的值。
此函数的作用是启动 UART 中断接收,使 UART 在接收到数据后触发中断,并将接收到的数据存储到指定的缓冲区中。函数参数 &huart1
和 &buf
就是用来传递这些信息的。
9、在这个主循环中,通过检查 UART1_RX_STA
的最高位(bit15),判断是否接收完成。如果接收完成,就打印收到的数据,然后通过串口发送出去。在等待发送完成的过程中,阻塞等待 huart1.gState
变为 HAL_UART_STATE_READY
,确保上一次的发送已经完成。最后,将 UART1_RX_STA
重置为0,准备开始下一次的接收。
如果接收未完成,会执行其他操作,比如打印 "hello liangxu" 和延时1秒。
这个循环将不断运行,周期性地进行串口接收和其他操作。主要的思路是在串口接收完成后进行处理,然后重新开始下一次接收。