9418| 5
|
Arduino入门套件的“红外接收程序” |
请教一个技术问题, 我从http://pan.baidu.com/s/17TJ9U 这里下载了Arduino入门套件的“红外接收程序”,里面的函数void pulse_deal(),说先解码地址码,再解码指令码,按照void pulse_deal()写的,默认地址码是0000 0000 1111 1101(低位在前),这16位bit的数据是怎么来的?按照NEC规则,这16bit应该是应该是地址码0000 0000+地址码反码1011 1111(高位在前),怎么不是呢? 谢谢 源代码如下: #define BUZZER 10//蜂鸣器 #define LED_RED 11//红灯 #define IR_IN 8 //红外接收 int Pulse_Width=0;//存储脉宽 int ir_code=0x00;//命令值 voidtimer1_init(void)//定时器初始化函数 { TCCR1A = 0X00; TCCR1B = 0X05;//给定时器时钟源 TCCR1C = 0X00; TCNT1 = 0X00; TIMSK1 = 0X00; //禁止定时器溢出中断 } voidremote_deal(void)//执行译码结果函数 { switch(ir_code) { case 0xff00://停止 digitalWrite(LED_RED,LOW);//红灯不亮 digitalWrite(BUZZER,LOW);//蜂鸣器不响 break; case 0xfe01://VOL+ digitalWrite(LED_RED,HIGH);//红灯亮 break; case 0xf609://VOLdigitalWrite(BUZZER,HIGH);//蜂鸣器响 break; } } char logic_value()//判断逡辑值“0”和“1”子函数 { while(!(digitalRead(8))); //低等待 Pulse_Width=TCNT1; TCNT1=0; if(Pulse_Width>=7&&Pulse_Width<=10)//低电平560us { while(digitalRead(8));//是高就等待 Pulse_Width=TCNT1; TCNT1=0; if(Pulse_Width>=7&&Pulse_Width<=10)//接着高电平560us return 0; else if(Pulse_Width>=25&&Pulse_Width<=27) //接着高电平1.7ms return 1; } return -1; } void pulse_deal()//接收地址码和命令码脉冲函数 { int i; //0000 0000 1111 1101 //执行 8 个 0 for(i=0; i<8; i++) { if(logic_value() != 0) //不是 0 return; } //执行 6 个 1 for(i=0; i<6; i++) { if(logic_value()!= 1) //不是 1 return; } //执行 1 个 0 if(logic_value()!= 0) //不是 0 return; //执行 1 个 1 if(logic_value()!= 1) //不是 1 return; //解析遥控器编码中的 command 指令 ir_code=0x00;//清零 for(i=0; i<16;i++ ) { if(logic_value() == 1) { ir_code |=(1<<i); } } } voidremote_decode(void)//译码函数 { TCNT1=0X00; while(digitalRead(8))//是高就等待 { if(TCNT1>=1563) //当高电平持续时间超过100ms,表明此时没有按键按下 { ir_code = 0xff00; return; } } //如果高电平持续时间不超过 100ms TCNT1=0X00; while(!(digitalRead(8))); //低等待 Pulse_Width=TCNT1; TCNT1=0; if(Pulse_Width>=140&&Pulse_Width<=141)//9ms { while(digitalRead(8));//是高就等待 Pulse_Width=TCNT1; TCNT1=0; if(Pulse_Width>=68&&Pulse_Width<=72)//4.5ms { pulse_deal(); return; } else if(Pulse_Width>=34&&Pulse_Width<=36)//2.25ms { while(!(digitalRead(8)));//低等待 Pulse_Width=TCNT1; TCNT1=0; if(Pulse_Width>=7&&Pulse_Width<=10)//560us { return; } } } } void setup() { unsigned char i; pinMode(LED_RED,OUTPUT);//设置不红灯连接的引脚为输出模式 pinMode(BUZZER,OUTPUT);//设置不蜂鸣器连接的引脚为输出模式 pinMode(IR_IN,INPUT);//设置红外接收引脚为辒入 } void loop() { timer1_init();//定时器刜始化 while(1) { remote_decode(); //译码 remote_deal(); //执行译码结果 } } |
0-7bit 和8-15bit 应该互为反码,可是0000 0000 和1111 1101并不互为反码啊 |
NEC码应该是32位,是16位的地址+八位数据+八位数据反码, 至于程序里int i; //0000 0000 1111 1101,应该是遥控器的地址码,和遥控器本身有关 所以在识别接受的前16位是不是0000 0000 1111 1101后再将后十六位进行比较就可以了,在void remote_deal(void)//执行译码结果函数 这个函数里, switch的三个数是0xff00,0xfe01,0xf609,换算成二进制就是前八位和后八位是反码了,这里才是数据码。地址码在NEC规则里没有规定要使用反码的 错误之处,还请指正:P |
Holiday 发表于 2014-2-7 22:10 百度 和 论坛资源里下载的教材里都写的: NEC协议特点:8位地址和8位命令,为提高可靠性,地址和命令都传输2次。 所以说,NEC协议里面,地址位确实占了16bits,但是是把地址位的反码加在8bits地址位后面又发了一次。 但是0000 0000 的反码,不是 1111 1101 啊。。。 |
Holiday 发表于 2014-2-8 23:27 是的,可以是反码,也可以不是。 问题是我们买的是红外收发模块,并不知道发射端是怎么设置的,只能在接收端按照例程处理也不是个事儿啊。 如果我想和别的红外端配对,我就没办法配了啊。 |
© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed