- /*
- YOCO 红外遥控数字显示器
- 功能:用红外遥控模块控制数码管显示0-9十个数字;每按动一次,数码管闪灭一次,同时蜂鸣器叫一声
- 红外接受头输出端接到Arduino的数字口D8。
- 遙控器功能键的键值:
- 紅色电源开关 0xba45
- MODE 0xb946
- 静音 0xb847
- ←← 0xbb44
- →→ 0xbf40
- ‖ 0xbc43
- VOL- 0xf807
- VOL+ 0xba15
- EQ 0xf609
- 100+ e609
- return 0xf200
- */
- /********************************设置变量********************************/
- #define IR_IN 8 //红外接收:D8
- int Pulse_Width=0;//存储脉宽
- int ir_code=0x00;//命令值,十六进制值
-
- //设置控制各段的数字I/O脚
- int a=16;//模拟口的A2,以下同
- int b=17;
- int c=4;
- int d=3;
- int e=2;
- int f=15;
- int g=14;
- int dp=5;
-
- //以下用数组给数码管管脚、0-9十个数字赋值,简洁
- byte segs[7] = { a, b, c, d, e, f, g };//除了小数点的7笔划段
- byte seven_seg_digits[10][7] = { { 1,1,1,1,1,1,0 }, // = 0
- { 0,1,1,0,0,0,0 }, // = 1
- { 1,1,0,1,1,0,1 }, // = 2
- { 1,1,1,1,0,0,1 }, // = 3
- { 0,1,1,0,0,1,1 }, // = 4
- { 1,0,1,1,0,1,1 }, // = 5
- { 1,0,1,1,1,1,1 }, // = 6
- { 1,1,1,0,0,0,0 }, // = 7
- { 1,1,1,1,1,1,1 }, // = 8
- { 1,1,1,1,0,1,1 } // = 9
- };
- /***************************定时器初始化函数*****************************/
- void timer1_init(void)
- {
- TCCR1A = 0X00;
- TCCR1B = 0X05;//给定时器时钟源
- TCCR1C = 0X00;
- TCNT1 = 0X00;
- TIMSK1 = 0X00;//禁止定时器溢出中断
- }
- /**************************译码输出子函数******************************/
- //执行译码结果函数,输出用灯光、数码管显示,必要可以加蜂鸣器
- void remote_deal(void)
- {
- switch(ir_code)
- {
- case 0xba45: //左上角的电源开关按键
- init_wire();//数码管熄灭
- buzzer_led();//蜂鸣器鸣叫
- break;
- //以下显示所按的数字
- case 0xE916://显示0
- lightSegments(0);
- break;
- case 0xF30C://1
- lightSegments(1);
- break;
- case 0xE718://2
- lightSegments(2);
- break;
- case 0xA15E://3
- lightSegments(3);
- break;
- case 0xF708://4
- lightSegments(4);
- break;
- case 0xE31C://5
- lightSegments(5);
- break;
- case 0xA55A://6
- lightSegments(6);
- break;
- case 0xBD42://7
- lightSegments(7);
- break;
- case 0xAD52://8
- lightSegments(8);
- break;
- case 0xB54A://显示9
- lightSegments(9);
- break;
- }
- }
- /************************逻辑值“0”和“1”子函数****************************/
- char logic_value()
- {
- while(!(digitalRead(8))); //低等待
- Pulse_Width=TCNT1;
- TCNT1=0;
- if(Pulse_Width>=5&&Pulse_Width<=11)//低电平560us——放宽了原来的条件:6-10
- {
- while(digitalRead(8));//红外接收管输出的是负脉冲,无信号保持高,高就等待
- Pulse_Width=TCNT1;
- TCNT1=0;
- if(Pulse_Width>=5&&Pulse_Width<=11)//如果Pulse_Width满足该条件,则脉冲持续高电平560us
- return 0;
- else if(Pulse_Width>=19&&Pulse_Width<=30) //如果Pulse_Width满足该条件,则脉冲持续高电平1.7ms
- return 1;
- }
- return -1;
- }
- /*********************接收地址码和命令码脉冲子函数***********************/
- void pulse_deal()
- {
- int i;
- //执行8个0
- for(i=0; i<8; i++)
- {
- if(logic_value() != 0) //不是0
- return;
- }
- for(i=0; i<8; i++)
- {
- if(logic_value() != 1) //不是1
- return;
- }
-
- //解析遥控器编码中的command指令
- ir_code=0x00;//清零
- for(i=0; i<16;i++ )
- {
- if(logic_value() == 1)
- {
- ir_code |=(1<<i);//从i的值写出键码值,十六进制
- }
- }
- }
- /***************************译码子函数******************************/
- void remote_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>=130&&Pulse_Width<=150)//9ms——修改了原来的条件:140-141
- {
- while(digitalRead(8));//是高电平就等待
- Pulse_Width=TCNT1;
- TCNT1=0;
- if(Pulse_Width>=60&&Pulse_Width<=79)//4.5ms——放宽了原来的条件
- {
- pulse_deal();
- return;
- }
- else if(Pulse_Width>=28&&Pulse_Width<=40)//2.25ms
- {
- while(!(digitalRead(8)));//低电平等待
- Pulse_Width=TCNT1;
- TCNT1=0;
- if(Pulse_Width>=5&&Pulse_Width<=12)//560us
- {
- return;
- }
- }
- }
- }
- /***************************初始化设置函数******************************/
- void setup()
- {
- unsigned char i;
- for(i=2;i<=19;i++)
- {
- pinMode(i,OUTPUT);//设置2~19引脚为输出模式
- }
- //pinMode(LED_RED,OUTPUT);//设置与红灯连接的引脚为输出模式
- pinMode(IR_IN,INPUT);//设置红外接收引脚为输入
- digitalWrite(9,LOW);//为红外接收头的接地端,节省连接的导线
- digitalWrite(10,HIGH);//为红外接收头的+端,节省连接的导线
- digitalWrite(18,HIGH);//A4,为蜂鸣器-
- digitalWrite(19,HIGH);//A5,为蜂鸣器-,蜂鸣器可接在A4、A5中的任何一个
- Serial.begin(9600);//在计算机的串口窗口里面观察键码值,需要打开串口窗口
- }
- /***************************主函数(循环)******************************/
- void loop()
- {
- timer1_init();//定时器初始化
- while(1)
- {
- remote_decode(); //译码
- remote_deal(); //执行译码结果
- //以下是观察键码值的程序:
- Serial.println("ir_code");
- Serial.println(ir_code, DEC);//显示十进制
- }
- }
- /***********************熄灭数码管全部笔画子函数************************/
- void init_wire()
- {
- for (int i=0;i<7;i++)
- {
- digitalWrite(segs[i], HIGH);
- }
- digitalWrite(dp,HIGH);
- }
- /************************点亮对应数字的数码管0-9*************************/
- void lightSegments(int x)
- {
- for (int i=0;i<7;i++)
- {
- digitalWrite(segs[i], 1-seven_seg_digits[x][i]);
- }
- buzzer_led();//蜂鸣器函数,数码管眨眼
- for (int i=0;i<7;i++)
- {
- digitalWrite(segs[i], 1-seven_seg_digits[x][i]);
- }
- }
- /********************蜂鸣器函数,同时数码管眨眼**********************/
- void buzzer_led()
- {
- delay(20);//数码管亮
- init_wire();//数码管熄灭
- digitalWrite(18,LOW);//蜂鸣器响
- digitalWrite(19,LOW);//蜂鸣器响
- delay(80);//响持续时间
- digitalWrite(18,HIGH);//蜂鸣器停
- digitalWrite(19,HIGH);
- }
复制代码
【效果】最终效果图如下