整整一个礼拜, 整了...大约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的红外控制的更多相关文章

  1. TI CC2541的LED控制

    现在终于进入到蓝牙SPI的环节了, 下面还要研究I2C, 所以第一步, 先点灯, 就是GPIO控制吧. 参考一下LEd的初始化: void HalLedInit (void){#if (HAL_LED ...

  2. 蓝牙(BLE)应用框架接口设计和应用开发——以TI CC2541为例

    本文从功能需求的角度分析一般蓝牙BLE单芯片的应用框架(SDK Framework)的接口设计过程,并以TI CC2541为例说明BLE的应用开发方法. 一.应用框架(Framework) 我们熟知的 ...

  3. IAR 9+ 编译 TI CC2541 出现 Segment ISTACK (size: 0xc0 align: 0) is too long for segment definition.

    IAR 9+ 编译 TI CC2541 出现 Segment ISTACK (size: 0xc0 align: 0) is too long for segment definition. Segm ...

  4. 树莓派 LED+蜂鸣+声音传感器+红外模块组合打造声控/红外控制LED

    昨天搞了控制LED,玩了第一个,剩下的就感觉很简单了,这里记录一下 先来几张照片 玩了蜂蜜模块才发现规律,一般这种模块,都会有三个针脚,VCC(3.3V或5V供电输出针脚).GNC(对应GPIO针脚的 ...

  5. 用Arduino对Apple手表进行远程红外控制

    描写叙述 用于控制随意红外设备的Apple手表及iPhone应用. IOS应用发送HTTP请求至一个或多个带有以太网插板的Arduino.Arduino正在解析http请求并发送红外信号.Arduin ...

  6. TI CC2541 BLE协议栈蓝牙MAC 地址

    在Flash中有一块只读区域,从地址0x780E开始,蓝牙的MAC以小端方式存放在里面. 在TI的Peripheral例程里面,添加一个特征值,只读属性,6字节长度(蓝牙MAC长度为48-bit,6字 ...

  7. TI CC2541的狗日的Key

    被突如其来的一个bug困扰了好几天, 起因是, 按键接的红外接收器, 结果发现, 一旦按下之后, IEN1, P0IE的标识位bit5, 被不知道特么的谁归0了, 也就是说, 按键只能被按下一次, 再 ...

  8. TI CC2541的整体目标

    1. App端会发送一定数量的byte过来蓝牙, 每2个byte是一个汉字的编码. 2. 拿到汉字编码之后, 统计字符数量, 然后通过SPI, 搜索编码 3. 收到的编码, 每个汉字字符有32个byt ...

  9. TI CC2541的中断优先级设置.

    实际看到的中断优先级设置是这样的:

随机推荐

  1. CSS样式优化

    一.css代码优化作用与意义 1.减少占用网页字节.在同等条件下缩短浏览器下载css代码时间,相当于加快网页打开速度2.便于维护.简化和标准化css代码让css代码减少,便于日后维护3.让自己写的cs ...

  2. 李洪强iOS经典面试题123

    1.static 关键字的作用: (1)函数体内 static 变量的作用范围为该函数体,不同于 auto 变量,该变量的内存只被分配一次, 因此其值在下次调用时仍维持上次的值; (2)在模块内的 s ...

  3. Java基础:继承,封装,多态,抽象类,接口

    只要是从事Java语言有关的开发工作,在面试中难念会被问到这几个东西. 博主学习java有两年多了,算是浅显的知道一些,抄写了一些解释分享一下. 1.什么是面向对象?(面对女朋友) 面向对象(Obje ...

  4. linux 有趣的命令

    input: echo ' > ..XXX. .XXX.. > .XXXXY.TXXXX. > XXXXXYXTXXXXX > .VXXVYXTVXXX. > `.TYX ...

  5. Oracle基础及三层分页查询

    一.数据库表空间和数据文件 解析:一个数据库下可以开N个表空间,一个表空间可以包含N个数据文件.表空间是逻辑概念. 二.关于listener.ora位置 修改该界面上的数据,会影响指定路径的监听配置文 ...

  6. PCL Show Point Cloud 显示点云

    在使用PCL库的时候,经常需要显示点云,可以用下面这段代码: #include <pcl/visualization/cloud_viewer.h> pcl::PointCloud< ...

  7. find exec 运用

    实例1:ls -l命令放在find命令的-exec选项中 : find . -type f -exec ls -l {} \;  实例2:在目录中查找更改时间在n日以前的文件并删除它们: find . ...

  8. html本地服务器

    html本地服务器 http://files.cnblogs.com/files/douxuyao/Aws.rar

  9. Android课程---布局管理器之相对布局(一)

    下面示例的是在父容器里如何设置按钮的位置,难度:***,重点是找到一个主按钮,设置它的id,然后根据它来设置其他按钮在父容器的位置. 代码示例: <?xml version="1.0& ...

  10. Android WebApp开发使用Genymotion连接Fiddler2/Charles代理调试

    1.       目的 在模拟器的浏览器或app hybrid开发中遇到chrome调试代码为线上代码或者混淆代码时,可以利用fiddler/charles为genymotion配置代理, 可以方便的 ...