关于串口通信中断接收数据的代码

本文详细描述了USART1中断服务程序中如何处理串口接收到的数据,包括奇偶校验、溢出错误、帧错误检测,以及数据帧的解析和CRC校验的过程。
摘要由CSDN通过智能技术生成

中断代码 


u8 rec,crc_flag;
u16 receivecount=0,num = 0,len = 0;
static u8 recv_state = 0;
void USART1_IRQHandler(void)                	//串口1中断服务程序
{
//	u8 Res;
	volatile u8 a=0;
	if (USART_GetFlagStatus(USART1, USART_FLAG_PE) != RESET)//奇偶校验位
 {
		 USART_ReceiveData(USART1);
	 USART_ClearFlag(USART1, USART_FLAG_PE);
 }
	
 if (USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET)//溢出错误位
 {
		 USART_ReceiveData(USART1);
	 USART_ClearFlag(USART1, USART_FLAG_ORE);//
 }
	
	if (USART_GetFlagStatus(USART1, USART_FLAG_FE) != RESET)//帧错误位
 {
		 USART_ReceiveData(USART1);
		USART_ClearFlag(USART1, USART_FLAG_FE);
 }
				 
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)//接收数据寄存器非空位
	{	 
		/*
		初始状态,判断帧头,判断到了22,第0个开始 ,切换状态进入数据状态
		数据状态,接收数据到第2位,字节长度,接收字节长度为x-5的数据,切换状态进入结尾状态
		结尾状态,读第一位和第二位,记录起来,将前面的字节全部计算校验对不对数据,然后置零重新开始接收下一包
		
		
		*/
			rec = USART_ReceiveData(USART1);
			switch(recv_state)
			{
				case 0:
				{
					if(rec == 0x22)
					{
						recv_state = 1;
						recbuffer[receivecount] = rec;
						receivecount =1;
						
					}
				}break;
				
				case 1:
				{
					
					recbuffer[receivecount] = rec;
					
					if(receivecount == 2)//是长度
					{
						len = rec;
					}
					receivecount++;
					if(receivecount >= len - 1 && len != 0)
					{
						recv_state = 2;
					}
				}break;		
				
				case 2:
				{//需要第二次发数据才会进来
					recbuffer[receivecount] = rec;
					
					receivecount++;
						crc_flag = CheckCRC16(recbuffer ,len);
//							crc_flag = 0;
						if(crc_flag == 0)
						{
							
							//确认帧头:
							if(recbuffer[0] == 0x22 && recbuffer[1] == 0x11 && rec_flag == 0)
							{
								a = recbuffer[2];
								//校验CRC
								for(int j = 0; j < recbuffer[2] ; j ++)
								{
									user_buffer[j] = recbuffer[j];
								}
								crc_1 = user_buffer[a-2];
								crc_2 = user_buffer[a-1];						
							}							
							rec_flag = 1;
							recv_state = 0;	
							len = 0;
							receivecount = 0;							
						}
						else
						{
							receivecount = 0;
							recv_state = 0;	
							len = 0;							
						}
				}break;
			}
		

		USART_ClearFlag(USART1, USART_FLAG_RXNE);
	}
} 

CRC校验 

/********************************************************* 
* 函数功能:CRC校验 
* 输入:data--待检验数据;len待检验数据长度
* 输出:无 
* 函数返回值:0--代表检验通过;1--代表检验不通过 
*********************************************************/ 
u8 CheckCRC16(u16 *data ,u16 len) 
{ 
	u8 tansbyte; 
	u16 i; 

	hibyte=0xff; 
	lobyte=0xff;	
	for(i=0;i<(len-2);i++) 
	{ 
		tansbyte=hibyte^*data++; 
		hibyte=lobyte^crch[tansbyte]; 
		lobyte=crcl[tansbyte]; 
	} 

	if((lobyte == data [len - 1]) && ((hibyte == data [len - 2]))) 
	{
			return 0; 	
	}
	else
	{
        	return 1; 		
	}

} 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值