码迷,mamicode.com
首页 > 其他好文 > 详细

TI CC2541的红外控制

时间:2016-11-30 19:57:25      阅读:221      评论:0      收藏:0      [点我收藏+]

标签:jsb   中间   dcl   fzu   scn   gae   sky   msu   val   

整整一个礼拜, 整了...大约40个小时吧, 最少..

下面是结果, 只能做一个delay延时.:

unsigned char Time;
unsigned char IrValue[6];
#pragma vector = P0INT_VECTOR
__interrupt void P0_ISR(void){
    unsigned char j,k;
    unsigned int err;
    if(P0IFG & 2){      //如果中断标识符的确是P0_1
        Time=0;                    
        ifr_delay_ms(1);   //等1ms
        if(IRIN==0)       //如果仍然是低电平, 排除掉    
        {    
          //P0_3Low();      //拉低P0_3
          
          err=1000;        //做一个错误计数器, 避免程序卡死                                          
          while((IRIN==0)&&(err>0))       //等待P0_1回到高电平, 根据红外的特性,理论上要等9ms
          {            
            ifr_delay_100us(1);       //等待100us, 理论上, err只会--大约90次.
            err--;
          }
            
          if(IRIN==1)        //回到高电平后
          {
            //P0_3High();     //拉高P0_3
            err=500;        //一样未免卡死, 重新定义错误计数器
            while((IRIN==1)&&(err>0))    //等待P0_1的下降沿.                
            {                
              ifr_delay_100us(1);    //一次等100us
              err--;            
            }    
            //P0_3Low();
            for(k=0;k<4;k++)        //一共获取4个字节        
            {            
              for(j=0;j<8;j++)        //每个字节8个bit
              {                
                err=60;                    //err恢复计数
                while((IRIN==0)&&(err>0))        //等待P1_0的低电平过去                                   
                {  
                  //P0_3Low();
                  ifr_delay_100us(1);            //等100us, 理论上, 这个长度是560us, 大约5-6个周期                                      
                  err--;                                           
                }
                                            
                err=500;            //err恢复    
                while((IRIN==1)&&(err>0))                
                {    
                  //P0_3High();                  
                  ifr_delay_100us(1);       // 等100us, 这就有两种情况, 一种是bit为1, 高电平长度是1120us, 11个周期, 如果是bit 0, 就是560us, 5-6个周期.                     
                  Time++;                
                  err--;                
                  if(Time>30)              //如果等待得太长,就特么算了, 出错了.
                    {            
                      EA=1;                            
                      return;        
                    }                
                }
                                            
                IrValue[k]>>=1;            //做一个位移动, 因为红外是从低位开始传输的.
                if(Time>=8)            
                {                    
                  IrValue[k]|=0x80;       //大于8个周期, 基本确定是1
                }        
                Time=0;    
              }    
            }
          }
                    
          if(IrValue[2]!=~IrValue[3])   //这里是做了一个红外协议的校验,就是数据码是互补的, 如果不是互补的, 证明出错了.
          {
            return;
          }
        }
        key_nop();
      
        P0IFG &= ~(1 << 1);
        P0IF = 0;
        EA = 1;
    }else{
        P0IFG = 0;
        P0IF = 0;
    }
}

并且修改蓝牙连接配置:

// Minimum connection interval (units of 1.25ms, 80=100ms) if automatic parameter update request is enabled
#define DEFAULT_DESIRED_MIN_CONN_INTERVAL     240

// Maximum connection interval (units of 1.25ms, 800=1000ms) if automatic parameter update request is enabled
#define DEFAULT_DESIRED_MAX_CONN_INTERVAL     320

// Slave latency to use if automatic parameter update request is enabled
#define DEFAULT_DESIRED_SLAVE_LATENCY         4

// Supervision timeout value (units of 10ms, 1000=10s) if automatic parameter update request is enabled
#define DEFAULT_DESIRED_CONN_TIMEOUT          600

// Whether to enable automatic parameter update request when a connection is formed
#define DEFAULT_ENABLE_UPDATE_REQUEST         TRUE

// Connection Pause Peripheral time value (in seconds)
#define DEFAULT_CONN_PAUSE_PERIPHERAL         6

 

在simplePeripheral.c文件里面.

 

下面说说为什么要delay, 因为delay是看上去最傻逼的做法.

从头说起:

技术分享

这是红外的一个例子数据包:

实际抓到的是这样:

技术分享

嗯, 是反过来的, 因为发射跟接收是反的.

这不是重点.

下面才是重点.

OK, 我的第一个想法是, 起一个timer, 这个timer每隔大约10个或者100个us做一次计数, 然后每个上升沿或者下降沿比对上一个mark点的这个计数值, 就知道中间过了多久.

结果事与愿违的是, 我发现最后拿到的数据总是出错, 本来发的是4个byte分别是0x00,0xFF, 0x0C,0xF3, 但是出错几率高达20%,很多时候是00, e0, 0E什么的..

后来我将计数器timer做成能输出高低电平的,这样方便我观察, 真的发现, 计数器每个大约几十个ms, 就会有个gap, (忘了截图), 证明这个timer在这个gap中被人打断了, 打断得连timer中断都没进去.

接下来我就各种更改中断优先级.

要知道, 2541中断优先级, 只有4个等级, 0,1,2,3换成二级制是00, 01, 10, 11, 总之, RF的中断肯定是最高优先级, 广播吧, 大概.

总之, 修改中断优先级不解决任何问题.

 

最后, 还是delay吧...不过设置了

#define DEFAULT_DESIRED_SLAVE_LATENCY         4

相信断开连接的情况会好点儿?

 

测试中...

TI CC2541的红外控制

标签:jsb   中间   dcl   fzu   scn   gae   sky   msu   val   

原文地址:http://www.cnblogs.com/Montauk/p/6112773.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!