正点原子STM32-串口中断服务函数USART1_IRQHandler关于USART_RX_STA的学习笔记

目录

USART1_IRQHandler 中断服务函数代码

介绍 函数USART_GetITStatus 每个状态描述

USART_RX_STA 接收状态标记的思考

USART1_IRQHandler 中断服务函数代码

u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15,	接收完成标志
//bit14,	接收到0x0d
//bit13~0,	接收到的有效字节数目
u16 USART_RX_STA=0;       //接收状态标记	

//上面一段注释很重要
void USART1_IRQHandler(void)                	//串口1中断服务程序
{
	u8 Res;
#if SYSTEM_SUPPORT_OS 		//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
	OSIntEnter();    
#endif
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾) 
	{
		Res =USART_ReceiveData(USART1);//(USART1->DR);	//读取接收到的数据
		
		if((USART_RX_STA&0x8000)==0)//接收未完成
		{
			if(USART_RX_STA&0x4000)//接收到了0x0d
			{
				if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
				else USART_RX_STA|=0x8000;	//接收完成了 
			}
			else //还没收到0X0D
			{	
				if(Res==0x0d)USART_RX_STA|=0x4000;
				else
				{
					USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
					USART_RX_STA++;
					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收	  
				}		 
			}
		}   		 
  } 

介绍 函数USART_GetITStatus 每个状态描述

正点原子STM32-串口中断服务函数USART1_IRQHandler关于USART_RX_STA的学习笔记_第1张图片

USART_RX_STA 接收状态标记的思考

u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
//接收状态:

bit15 bit14 bit13~0
接收完成标志  接收到0x0d 接收到的有效字节数

u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节,可以自行定义
//bit15,    接收完成标志
//bit14,    接收到0x0d
//bit13~0,    接收到的有效字节数目

u16 USART_RX_STA=0;       //接收状态标记    

USART_RX_STA 的作用就是一个接收状态标记

..

用单步调试的思想来假设一下串口接收时候,接收数据的状态。假设接收的数据为12345。
 在第一次进入串口中断处理函数,我们先判断是否接是因为USART1接收到了数据产生的中断
   if(USART_GetFlagStatus(USART1, USART_IT_RXNE) != RESET) // RXNE //接收中断       

   Res =USART_ReceiveData(USART1);//(USART1->DR);    //读取接收到的数据                                                                  
  首先,USART1接受到的一位数据 1  存入变量Res里,这时候会继续判断是否还有数据需要接收,还有 2345 没有接收
   if((USART_RX_STA&0x8000)==0) //接收未完成

          USART_RX_STA&0x8000 赋值为0后进入内层if语句里

USART_RX_STA 这个变量的值仍然为0,和0x8000相与以后为0,那么执行该if语句的内层函数。

 进入if(USART_RX_STA&0x4000)  进行条件判断  //接收到了0x0d 

                注意://0x0d是回车的ASCLL码,0x0a是换行的ASCLL码

这里判断USART_RX_STA的第14位是否为1,假设接收到了回车,即0x0d那么USART_RX_STA的第14位会置1。

但是 USART_RX_STA和0x400相与为0,该判断语句就为假,执行下面的else语句。

 if(Res==0x0d)USART_RX_STA|=0x4000;  

此时还是没有收到0x0d 即回车,继续执行下一个else语句

 ⑥   else{
                    USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
                    USART_RX_STA++;
                    if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0; 
//接收数据错误,重新开始接收      
                }         

                if(Res!=0x0a)USART_RX_STA=0;  //接收错误,重新开始
                else USART_RX_STA|=0x8000;    //接收完成了 


USART_RX_STA的bit0~bit13代表的是接收到的有效数据个数,这里USART_RX_STA值仍为0,USART_RX_STA & 0X3FFF = 0 ,然后USART_RX_BUF[USART_RX_STA&0X3FFF]=Res,意思就是将Res里的数据存放到USART_RX_BUF[0]里了,并且USART_RX_STA自增1。

此时USART_RX_STA = 1这样在接收到下一个数据后USART_RX_STA&0X3FFF = 1

将后面的数据存入到了USART_RX_BUF[1]里,

直到我们接收到了0x0d(Res = 0x0d)。

第一篇学习笔记,还请大家多多指教!!!

你可能感兴趣的:(stm32单片机,stm32,单片机,嵌入式硬件,mcu,arm)