主要应对异步通讯
比如单片机间串口通讯
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)==SET)
{
u16 temp=0;
last_len=data_len+last_len;
if(last_len>rx_len)
last_len=0;
__HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除串口空闲中断
/*当检测到空闲总线时,该位被硬件置位。如果USART_CR1中的IDLEIE为1,产生中断。由
软件序列清除该位(先读USART_SR,然后读USART_DR)上下两两方式都可以,使用一个*/
// temp=huart1.Instance->SR;//读取后清除
// temp=huart1.Instance->DR;//读取后清除
HAL_UART_DMAStop(&huart1);//暂停接收数据
temp=hdma_usart1_rx.Instance->NDTR;//得到当前还剩多少字节
data_len=rx_len-temp;//总自己减去剩余的得到已经接收的字节数
for(u16 num=0;num<data_len;num++)
{
receive_buf_now[last_len+num]=receive_buf[num];
}
USAR_UART_IDLECallback(&huart1);
}
/* USER CODE END USART1_IRQn 1 */
}
要加入全局变量
__IO u8 receive_buf[rx_len]={0}; //DMA接收的缓存
__IO u8 receive_buf_now[rx_len]={0};//由DMA接收的缓存得到的数据,可以手动清空
__IO u16 data_len=0;//接收到数据的字节数
__IO u16 last_len=0;//指定receive_buf_now[]数据上次接收的地位,可以实现多次空闲中断数据的接收处理
//u8 rec_log=0;
其中
#define rx_len 512//缓存大小
在中断处理函数前要加入
void USAR_UART_IDLECallback(UART_HandleTypeDef *huart)
{
printf("\r\n------------------------\r\n");
HAL_UART_Transmit(&huart1,receive_buf_now,data_len+last_len,0x200);//打印接收数据,用于调试
//printf("%x",receive_buf_now[0]);
rec_log=0;
printf("\r\n========================\r\n");
HAL_UART_Receive_DMA(huart, (uint8_t*)receive_buf, rx_len);//重新使能DMA中断
}
在主函数串口处理函数中,要进行的操作
memset(receive_buf_now,0,last_len+data_len);//清空receive_buf_now[]数组
last_len=0;//清空,因为receive_buf_now开始接收新的数据
data_len=0;//清空,因为receive_buf_now开始接收新的数据
完成,至此一个串口接收流程完成,多用于at指令类的模块,测试ok
别人工程下串口接收函数
void UART0_IRQHandler(void)
{
uint32_t intsrc, tmp;
uint8_t dat;
intsrc = UART_GetIntId(UART_0);
tmp = intsrc & UART_IIR_INTID_MASK;
if (tmp == UART_IIR_INTID_RDA)
{
dat= UART_ReceiveByte(UART_0);
if(!recvFinish)
{
if(recvBegin)
{
recvBuf[recvCnt++] = dat;
if(recvCnt==64)
{
recvBegin = 0;
recvFinish = 1;
}
}
else if(dat==0XAA)
{
recvCnt = 0;
recvBuf[recvCnt++] = dat;
}
else if(dat==0X55&&recvCnt==1)
{
recvBuf[recvCnt++] = dat;
recvBegin = 1;
}
}
}
}