TI CC2541的红外控制
整整一个礼拜, 整了...大约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
相信断开连接的情况会好点儿?
测试中...