• CC2541的任务与事件,以及红外捕捉.


    因为红外遥控要占用的系统中断时间可能超过了80ms, 极有可能导致蓝牙断线, 特别是连续两次按键, 100%断线.

    后来根据蓝牙技术群里的哥们提示, 觉得不能在一个中断中delay得太久, 只能用任务跟事件的情势来实现了.

    首先原理是, 利用现有的SimpleBLEPeripheval的这个任务, 增加一个处理案件的事件.

    #define SBP_CATCH_IRF_EVT   0x0008

    接着写一个输入口的下降沿触发的中断:

    volatile unsigned char readingISR=0;
    #pragma vector = P0INT_VECTOR      
    __interrupt void P0_ISR(void)   
    {   
        key_nop();
        if(NOT_DISPLAYING==sysStatus)
        {
            if(Key_Check_Pin() == KEY_PRESS)   
            {         
            unsigned char IRCOM[7]={0,0,0,0,0,0,0};
            if(readingISR==0){
                readingISR=1;          
                readISROrigin(IRCOM);
                readingISR=0;
            }      
            }
        }  
        P0IFG &=~(1<<2);       //清除中断标志
        P0IF = 0;        //清除中断标志
        key_nop();
    }


    具体init的方法就不贴了.

    readISROrigin(IRCOM)其实输入是没用的.

    实际原本是在这个方法中捕捉输入的.

    但是不是延时太长会断蓝牙么, 在这儿仅仅判断一下起始条件:

    void readISROrigin(uint8* IRCOM)
    {
        //unsigned char j,k,N=0;
        //EA = 0;
        disableP02Int();
        key_delay_140us(15);
        if (IRIN==1)
        {
            //EA =1;
            enableP02Int();
            return;
        }
        while (!IRIN)  //等变高       
        {key_delay_140us(1);}
        
        osal_start_timerEx(11, 8, 1);

    }

    红框的后半部分, 等升高, 具体的红外的协议, 就是一开始一个9.38ms的一个低电平, 然后一个4.24ms高电平, 表示开始, 具体多久我不管了, 没空.

    总之捕捉到这个电平变换, 发送一个event, 这个event之前定义了是0x0008二进制数是从右边数第3个bit是1.

    osal_start_timerEx(11, 8, 1);

    其实正常的写法应该是用

    osal_start_timerEx(simpleBLEPeripheral_TaskID, SBP_CATCH_IRF_EVT, 1);

    最后内个1表示1ms后发消息.

    然后就是在simpleBLEPeripheval.c里面处理event的方法里面, 增加对SBP_CATCH_IRF_EVT的响应.

    uint16 SimpleBLEPeripheral_ProcessEvent( uint8 task_id, uint16 events )
    {

    ....

     if(events & SBP_CATCH_IRF_EVT){
          uint8 ircom=ISR_BLANK_CODE;
          ircom=readISRP0_2();
          if(ircom==0){
              osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_CATCH_IRF_EVT, 1 );
         
          }else if(ircom==0xFF){
              osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_CATCH_IRF_EVT, 1 );   
              
          }else if(ircom!=ISR_BLANK_CODE){
              handleRemoteButtonPressed(ircom);
          }
          
        
          return (events ^ SBP_CATCH_IRF_EVT);
      }

    ...

    }

    先捕捉第1个字节:

       if(ircom==0){
              osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_CATCH_IRF_EVT, 1 );
         ..

    接着捕捉第2个字节:

       }else if(ircom==0xFF){
              osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_CATCH_IRF_EVT, 1 );   
             

    第3个字节:

     }else if(ircom!=ISR_BLANK_CODE){
              handleRemoteButtonPressed(ircom);
          }

    第4个字节:

    第4个字节不管了.

    捕捉到第3个字节的时候, 就去比较是否是按键的红外编码:

    void handleRemoteButtonPressed(uint8 code){
        if(NOT_DISPLAYING==sysStatus){
            switch(code){
            case RemoteButton1:
                sysStatus=DISPLAYING;
                playSentence(1);
            break;
            
            case RemoteButton2:
                sysStatus=DISPLAYING;
                playSentence(2);
            break;

    ....

    }

    比较如果有合适的, 就播放对应的字符串.

  • 相关阅读:
    做了一些心理学的测试,分析下个人
    做了一些心理学的测试,分析下个人
    逆转一个整数
    打印九九乘法表
    计算两个日期相差多少天
    struct的使用
    Linux Vim替换字符串的一些方法小结
    CentOS里vim基本操作
    如何创建一个后台进程
    高中是个把人分类的机器(转)
  • 原文地址:https://www.cnblogs.com/Montauk/p/5920113.html
Copyright © 2020-2023  润新知