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)//接着高电平560usreturn 0;else if(Pulse_Width>=25&&Pulse_Width<=27) //接着高电平1.7msreturn 1;}return -1;}void pulse_deal()//接收地址码和命令码脉冲函数{int i; //0000 0000 1111 1101//执行 8 个 0for(i=0; i<8; i++){if(logic_value() != 0) //不是 0return;}//执行 6 个 1for(i=0; i<6; i++){if(logic_value()!= 1) //不是 1return;}//执行 1 个 0if(logic_value()!= 0) //不是 0return;//执行 1 个 1if(logic_value()!= 1) //不是 1return;//解析遥控器编码中的 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;}}//如果高电平持续时间不超过 100msTCNT1=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码应该是32位,是16位的地址+八位数据+八位数据反码,
至于程序里int i; //0000 0000 1111 1101,应该是 ...
百度 和 论坛资源里下载的教材里都写的:
NEC协议特点:8位地址和8位命令,为提高可靠性,地址和命令都传输2次。
所以说,NEC协议里面,地址位确实占了16bits,但是是把地址位的反码加在8bits地址位后面又发了一次。
但是0000 0000 的反码,不是 1111 1101 啊。。。
按照这里说的NEC原理--百度文库
个人理解应该是可以设置为反码,也可以不是,至于一定要是反码的规定,能贴个链接一起学习下吗?
Holiday 发表于 2014-2-8 23:27
按照这里说的NEC原理--百度文库
个人理解应该是可以设置为反码,也可以不是,至于一定要是反码的规定,能 ...
是的,可以是反码,也可以不是。
问题是我们买的是红外收发模块,并不知道发射端是怎么设置的,只能在接收端按照例程处理也不是个事儿啊。
如果我想和别的红外端配对,我就没办法配了啊。
页:
[1]