一、开发环境
MCU型号:stm32l071cbtx
库:HAL库
IDE:stm32CubeMx、KEIL5
NB模组:BC95-B5
二、分析
在使用串口接收模组回复的AT指令时,遇到个问题就是AT命令响应格式为:
<CR><LF>+CMD1:<parameters><CR><LF>
<CR><LF>OK<CR><LF>
或者
<CR><LF><parameters><CR><LF>
<CR><LF>OK<CR><LF>
如果去判OD OA为帧头帧尾来接收的话会比较麻烦,并且有些指令响应的回复不止两条,出现多条时,缓冲区易被覆盖,数据不好处理。使用串口中断逐字节接收,然后通过进入空闲中断判断命令的响应接收完成即可轻松处理数据。
三、实现
1、开启中断
typedef struct
{
uint8_t Flg;
uint8_t Temp; //临时缓存
uint8_t Buf[256];
uint16_t LenA;
} UART_RX_TYPE_DEF;
UART_RX_TYPE_DEF gBc95Uart;
HAL_UART_Receive_IT(&huart2, &gBc95Uart.Temp, 1); //开启串口接收中断
__HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE); //开启串口空闲中断
2、接收处理
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart == &huart2)
{
Bc95_Uart_Rec(huart, &gBc95Uart);
}
}
void Bc95_Uart_Rec(UART_HandleTypeDef *huart, UART_RX_TYPE_DEF *Uart)
{
Uart->Buf[Uart->LenA] = Uart->Temp;
Uart->LenA ++;
while (HAL_UART_Receive_IT(huart, &Uart->Temp, 1) != HAL_OK);
}
3、空闲中断
//函数在stm32l0xx_it.c文件
//HAL_UART_IRQHandlerHAL库对于串口中断处理最终会调到HAL_UART_RxCpltCallback函数(该函数是虚函数用户可以重写)
void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
UsartReceive_IDLE(&huart2);
/* USER CODE END USART2_IRQn 0 */
HAL_UART_IRQHandler(&huart2);
/* USER CODE BEGIN USART2_IRQn 1 */
/* USER CODE END USART2_IRQn 1 */
}
void UsartReceive_IDLE(UART_HandleTypeDef *huart)
{
if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET))
{
__HAL_UART_CLEAR_IDLEFLAG(huart);
gBc95Uart.Flg = 1;
}
}
4、主循环取数据
if (gBc95Uart.Flg)
{
gBc95Uart.Flg = 0;
/*
*
*此处收到的是完整帧的回复,具体处理用户自定义
*
*
*/
}