整整一个礼拜, 整了...大约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. Android带侧滑菜单和ToolBar的BaseActivity

    写Android的时候,可能有多个界面.在风格统一的软件中,写Activity时会有很多重复.例如我所在软工课程小组的项目:Github链接 ,里面的TaskListActivity和TeacherL ...

  2. iPhone6的CSS3媒体查询

    @media only screen and (min-device-width: 375px) and (max-device-width: 667px) and (orientation : po ...

  3. 配置DNS实验一例

    1安装bind软件 2查看当前DNS服务 3修改配置文件 4测试

  4. 讨论一下hibernate如何动态注册一个动态生成的实体类

    如何动态生成实体类请参考这篇博文:http://www.cnblogs.com/anai/p/4269858.html 下面说说得到实体类后,如何能使用hibernate的接口来进行数据访问. 我们都 ...

  5. Canvas 唯美雨落代码实现

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  6. 根据backup-my.cnf来生成新的事务日志文件

    使用rpm包安装xtrabackup ## 安装依赖包yum -y install perl perl-devel libaio libaio-devel perl-Time-HiRes perl-D ...

  7. BizTalk开发系列(五) 属性字段

    在根据消息内容进行路由的时候经常使用的是可分辨字段和属性字段.属性字段可以在各个 BizTalk Server 组件(包括管道和业务流程)中进行访问.属性字段还可用于消息路由.如果需要在上下文(而不是 ...

  8. Harris角点检测算法优化

    Harris角点检测算法优化 一.综述 用 Harris 算法进行检测,有三点不足:(1 )该算法不具有尺度不变性:(2 )该算法提取的角点是像素级的:(3 )该算法检测时间不是很令人满意. 基于以上 ...

  9. 【iCore3 双核心板_FPGA】实验十四:FSMC总线通信实验——独立地址模式

    实验指导书及代码包下载: http://pan.baidu.com/s/1kVJBxJ5 iCore3 购买链接: https://item.taobao.com/item.htm?id=524229 ...

  10. 【iCore3 双核心板_FPGA】实验十六:基于SPI总线的ARM与FPGA通信实验

    实验指导书及代码包下载: http://pan.baidu.com/s/1hs6lDdi iCore3 购买链接: https://item.taobao.com/item.htm?id=524229 ...