void  USART1_IRQHandler (void)函数是串口1的中断响应函数,当串口1 发生了相应的中断后,就会跳到该函数执行。

函数设计思路:

变量:USART_RX_BUF[],保存接受到的数据

           USART_RX_STA  ,接收状态寄存器实现对串口数据的接收管理

          USART_REC_LEN ,USART_RX_BUF 的大小由其决定

USART_RX_STA  寄存器状态定义表:

bit15 bit14 bit0~13
接受完成标志 接受到0X0D标志 接收到的有效数据个数

当接收到从电脑发过来的数据,把接收到的数据保存在 USART_RX_BUF 中,同时在
接收状态寄存器(USART_RX_STA)中计数接收到的有效数据个数,当收到回车(回车的
表示由 2 个字节组成:0X0D 和 0X0A)的第一个字节 0X0D 时,计数器将不再增加,等待
0X0A 的到来,而如果 0X0A 没有来到,则认为这次接收失败,重新开始下一次接收。如
果顺利接收到 0X0A,则标记 USART_RX_STA 的第 15 位,这样完成一次接收,并等待该
位被其他程序清除,从而开始下一次的接收,而如果迟迟没有收到 0X0D,那么在接收数
据超过 USART_REC_LEN 的时候,则会丢弃前面的数据,重新接收。中断相应函数代码
如下:

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;
                            //接收数据错误,重新开始接收
                }
            }
        }
    }
#if SYSTEM_SUPPORT_OS //如果 SYSTEM_SUPPORT_OS 为真,则需要支持 OS

    OSIntExit();

#endif
}

 假设第一次接收数据,数据为abcd。

1,在第一次进入串口中断处理函数,判断是否因为USART1接受到了数据产生的中断

if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)

如果是,将USART1接收到的一位数据(a)存入变量Res里(Res=“a")

2,然后判断数据是否接收完

if((USART_RX_STA&0x8000)==0)//接收未完成

这个时候USART_RX_STA其值仍然为0,和0x8000相与以后为0,则进入其内层函数的if函数

3,再次判断是否接收完

if(USART_RX_STA&0x4000)//接收到了 0x0d

即判断USART_RX_STA第十四位是否为1.但在此还有b,c,d没有接收,USART_RX_STA还为零,其与0x4000相与为0,该判断语句为假,执行下面的else。

4.具体赋值操作

else
                {
                USART_RX_BUF[USART_RX_STA&0X3FFF]=Res;   //0x3FFF=0011 1111 1111 1111

                USART_RX_STA++;

                if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;
                            //接收数据错误,重新开始接收
                }

这里USART_RX_STA的值为0,USART_RX_STA&0X3FFF为0.则USART_RX_BUF[0]中存放着Res的数据。并且USART_RX_STA自增1。这样下一次USART_RX_STA&0X3FFF的值将为1.则将b存放在USART_RX_BUF[1]中。一直循环下去,直到接收到0x0d。

接收到0x0b时,运行到如下代码:

else //还没收到 0X0D
            {
            if(Res==0x0d)USART_RX_STA|=0x4000;

USART_RX_STA|=0x4000,即0000 0000 0000 0100 | 0100 0000 0000 0000 = 0100 0000 0000 0100 ,我们可以清晰的看到bit13~0位是4,代表接收到了4个数据(a,b,c,d),第14位为1,是因为接收到了数据0x0d,也和最上面给的表对上了,然后程序向下执行,接收到了0x0d(回车),那下一个就是接收0x0a(换行)了。

此时USART_RX_STA=0100 0000 0000 0100

if(USART_RX_STA&0x4000)//接收到了 0x0d
            {
            if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始

            else USART_RX_STA|=0x8000; //接收完成了
            }

USART_RX_STA&0x4000=0100 0000 0000 0100&0100 0000 0000 0000=0100 0000 0000 0000.符合条件,进入if语句,执行else USART_RX_STA|=0x8000; //接收完成了。即0100 0000 0000 0100 | 1000 0000 0000 0000 = 1100 0000 0000 0100。到了这一步,就说明这一串数据已经完完全全的接收完了USART_RX_STA = 1100 0000 0000 0100,最高位为1:代表接收到了0x0a,第十四位为1:代表接收到了0x0d,第0位到第13位为4,代表接收到了4位有效数据(a、b、c、d)

 

 

物联沃分享整理
物联沃-IOTWORD物联网 » USART1_IRQHandler 函数

发表回复