赞
踩
串口通信我相信很多小伙伴已经或多或少有所了解,但我相信大多数小伙伴仍然停留在只做C/V工程师。在这里我想说,在串口通信中除了串口中断服务函数外你都可以不去深究,但一定要会写会分析串口中断服务函数!!!!
串口中断服务函数是在串口通信中处理接收数据的重要部分。
注意:当你不了解 中断标志位,FIFO,串口协议等
USART_RX_STATE
)来跟踪接收状态,如接收是否完成、是否接收到特定字符等。参考文章中的代码示例(如USART1_IRQHandler
函数)展示了串口中断服务函数的基本结构和运行逻辑。在实际应用中,开发人员可以根据具体需求对中断服务函数进行定制和优化,这也证明了串口中断服务函数的定制性!接下来我们从代码开始学习。
- // RXState 用于变量标志位
- // pRxPacket 指示接收到的数据包的位数
- void USART1_IRQHandler(void)
- {
- static uint8_t RxState = 0;
- static uint8_t pRxPacket = 0;
- if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
- {
- uint8_t RxData = USART_ReceiveData(USART1);
- if (RxState == 0)
- {
- if (RxData == 'A' && Serial_RxFlag == 0)
- {
- RxState = 1;
- pRxPacket = 0;
- }
- }
- else if (RxState == 1)
- {
- if (RxData == 'D')
- {
- RxState = 2;
- }
- else
- {
- Serial_RxPacket[pRxPacket] = RxData;
- pRxPacket ++;
- }
- }
- else if (RxState == 2)
- {
- if (RxData == '\n')
- {
- RxState = 0;
- Serial_RxPacket[pRxPacket] = '\0';
- Serial_RxFlag = 1;
- }
- }
- USART_ClearITPendingBit(USART1, USART_IT_RXNE);
- }
- }

首先你需要记住并学会使用的便是RxState(用于变量标志位)pRxPacket(指示接收到数据位的包数)RxData(记录串口接收的数据)。在日后或今天你凡是在写串口中断服务函数便会用到!
if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
- if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
- {
- // 从USART1的接收数据寄存器中读取数据
- uint8_t RxData = USART_ReceiveData(USART1);
- }
首先解释 USART_GetITStatus(USART1, USART_IT_RXNE)。当我们串口1接收到信息后,检查接收缓冲区非空中断被触发------>接收到的信息被存入接收缓冲区------->再通过data将缓冲区的数据读取出来。这样它即实现了检验串口是否接收到信息,还可以实现将数据读出来储存起来。
接下来我们将学习通过RxState的状态来处理接收到的数据。
if (RxState == 0) // 如果当前状态为0
{
// 检查接收到的数据是否为'A',并且Serial_RxFlag是否为0(避免重复处理)
这样我们就成功将包头设置为A。
if (RxData == 'A' && Serial_RxFlag == 0)
{
// 如果条件满足,将RxState设置为1,表示开始接收数据包
RxState = 1;
// 重置接收数据包的索引为0
//这样子表示我们接收到的数据重新计算,开始接收数据。
pRxPacket = 0;
}
}
if (RxState == 1) // 如果当前状态为1
{
// 检查接收到的数据是否为'D'
if (RxData == 'D')
{
// 如果条件满足,将RxState设置为2,开始进入数据整合过程。
//并出现包尾D
RxState = 2;
}
else
{
// 但如果不是'D',则将接收到的数据存储在Serial_RxPacket数组中
Serial_RxPacket[pRxPacket] = RxData;
// 增加接收数据包的索引,以便存储下一个字节
//这样子便实现了记录我们发送数据的内容。一直循环直到出现包尾D
pRxPacket ++;
}
else if (RxState == 2) // 如果当前状态为2
//但是在很多时候我们所发送的数据中包含D,这样子会导致我们的串口发送提前结束,所以我们引入二次确认,即再加一个包尾的包格式。
{
//在满足检测到D后
// 检查接收到的数据是否为换行符'\n'
if (RxData == '\n')
{
// 如果条件满足,将RxState重置为0,表示数据包接收完成
RxState = 0;
// 在数据包末尾添加空字符'\0',以便后续处理
Serial_RxPacket[pRxPacket] = '\0';
// 设置Serial_RxFlag为1,表示数据包已准备好供其他函数处理
Serial_RxFlag = 1;
}
}
USART_ClearITPendingBit(USART1, USART_IT_RXNE); 一定要记得加这一句
最用非常的大:清除USART1的接收数据寄存器非空中断标志位
在读取数据寄存器后完成,以确保不会立即触发另一个中断
这就是全部过程了,你是否已经掌握,快上手试试吧!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。