基于51单片机的万能红外遥控器的设计资料分享给51hei的朋友们
这个单片机选择的是STC15F2K60S2型高速单片机,这个遥控器主要分为两种模式
(1)遥控模式
在这个模式下这个遥控器可以遥控其他的红外设备,和正常的遥控器一样。
(2)学习模式
这个模式是获取其他遥控器的用户码以及键码,然后把获取的用户码和键码储存到单片机的EEPROM中,所以这个遥控器具有掉电不丢失的功能。
最后一点就是介绍一下遥控器的小灯的功能。小灯起的是指示的功能,在刚开机的时候,如果是遥控模式小灯闪两下,学习模式小灯闪三下。在遥控模式下按键按一下,小灯闪一下。在学习模式下,红外接收头接收到一帧数据小灯闪两下,连续接收两帧数据小灯闪四下。按键按一下小灯闪一下。
制作出来的实物图如下:
Altium Designer画的学习型红外遥控器原理图和PCB图如下:(51hei附件中可下载工程文件)
单片机学习型遥控器的源程序如下:
- /*
- 单片机型号STC15F2K60S2,晶振24MHZ
- */
- #include "config.h"
- #include "main.h"
- #include "keyboard.h"
- #include "PWM_Init.h"
- #include "EEPROM.h"
- #include "Infrared_Init.h"
- #include<intrins.h>
- uint8 IR_Send_Code[16][4];
- uint8 xdata IR_Send_Code2[16][4];
- uint8 Send_Flag[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
- uint16 timebyte;
- uint8 T0RH = 0; //T0重载值的高字节
- uint8 T0RL = 0; //T0重载值的低字节
- uint8 LED_Control = 0;
- bit irflag = 0; //"红外接收标志,收到一帧正确数据后置1"
- unsigned char ircode[4]; //"红外代码接收缓冲区"
- bit MODE = 1;
- volatile unsigned char CodeBuff=30;
- void main()
- {
- P1=0XFF;
- LED = 1;
- ConfigTimer2(); //定时器0 1KHZ
- EEPROM_Init(); //把所有的EEPROM中的数据读到缓存区中
- EA=1; //总中断打开
- if(Mode_CHO) //判断要使用什么模式
- {
- MODE = 1; //遥控模式
- PWM_Init(); //产生38K载波
- LED_Control = 2; //小灯闪烁2次 代表控制模式
- }
- else
- {
- MODE = 0; //学习模式
- InitInfrared(); //红外线接收初始化
- LED_Control = 3; //小灯闪烁2次 代表学习模式
- }
- while (1)
- {
- KeyDriver(); //按键驱动
- if(irflag&&(CodeBuff<16)) //irflag接收完成标志,
- {
- irflag=0;
- if(timebyte>=500)
- {
- IR_Send_Code[CodeBuff][0]=ircode[0]; //功能码
- IR_Send_Code[CodeBuff][1]=ircode[1]; //功能码反码
- IR_Send_Code[CodeBuff][2]=ircode[2]; //键码
- IR_Send_Code[CodeBuff][3]=ircode[3]; //键码反码
- Send_Flag[CodeBuff]=0;
- EEPROM_Write(); //接收第一个字节
- }
- if(timebyte<500) //在短时间内收到第二个字节则接收
- {
- IR_Send_Code2[CodeBuff][0]=ircode[0]; //功能码
- IR_Send_Code2[CodeBuff][1]=ircode[1]; //功能码反码
- IR_Send_Code2[CodeBuff][2]=ircode[2]; //键码
- IR_Send_Code2[CodeBuff][3]=ircode[3]; //键码反码
- Send_Flag[CodeBuff]=1;
- EEPROM_Write();
- LED_Control=5; //接收第二个字节
- }
- timebyte=0;//从接收到第一帧数据开始计时
- LED_Control += 2; //小灯闪烁2次 接收完成一次小灯闪烁两次
- }
- }
- }
- /* 配置并启动T0,ms-T0定时时间 */
- void ConfigTimer2()
- {
- // AUXR &= ~0x04; //定时器2为12T模式
- // T2L = 0X60; //初始化计时值
- // T2H = 0Xf0;
- // AUXR |= 0x10; //定时器2开始计时
- // IE2 |= 0x04;
- AUXR &= 0xFB; //?????12T??
- T2L = 0x30; //??????
- T2H = 0xF8; //??????
- AUXR |= 0x10; //???2????
- IE2 |= 0x04;
- }
- void InterruptTimer2() interrupt 12
- {
- static unsigned int i=0,j=0;
- i++;
- timebyte++;//计算字节之间的时间
- if(LED_Control)
- {
- if(!(i%50))
- {
- LED=!LED;
- i=0;
- j++;
- }
- if(j==(2*LED_Control))
- {
- LED_Control=0;
- LED=1;
- j=0;
- }
- }
- if(timebyte>600)
- timebyte=600;
- KeyScan(); //执行按键扫描
- }
- //中断服务程序
- void Interrupt38KPWM() interrupt 3 //中断入口
- {
- IR = !IR;
- // IE2 &= ~0x04; //若需要手动清除中断标志,可先关闭中断,此时系统会自动清除内部的中断标志
- // IE2 |= 0x04; //然后再开中断即可
- }
- /* "INT1中断服务函数,执行红外接收及解码 "*/
- void EXINT1_ISR() interrupt 2
- {
- unsigned char i, j;
- unsigned char byt;
- unsigned int time;
- // LED_Control=1;
- //"接收并判定引导码的9ms低电平"
- time = GetLowTime();
- if ((time<8500*2) || (time>9500*2)) //"时间判定范围为8.5~9.5ms," //((time<7833) || (time>8755))
- { //"超过此范围则说明为误码,直接退出 "
- IE1 = 0; //"退出前清零INT1中断标志"
- return;
- }
- //"接收并判定引导码的4.5ms高电平"
- time = GetHighTime();
- if ((time<4000*2) || (time>5000*2)) //"时间判定范围为4.0~5.0ms," //((time<3686) || (time>4608))
- { //"超过此范围则说明为误码,直接退出"
- IE1 = 0;
- return;
- }
- //"接收并判定后续的4字节数据"
- for (i=0; i<4; i++) //"循环接收4个字节"
- {
- for (j=0; j<8; j++) //"循环接收判定每字节的8个bit"
- {
- //"接收判定每bit的560us低电平 "
- time = GetLowTime();
- if ((time<340*2) || (time>780*2)) //"时间判定范围为340~780us, " //((time<313) || (time>718))
- { //"超过此范围则说明为误码,直接退出"
- IE1 = 0;
- return;
- }
- //"接收每bit高电平时间,判定该bit的值"
- time = GetHighTime();
- if ((time>340*2) && (time<780*2)) //"时间判定范围为340~780us," //((time>313) && (time<718))
- { //"在此范围内说明该bit值为0"
- byt >>= 1; //"因低位在先,所以数据右移,高位为0"
- }
- else if ((time>1460*2) && (time<1900*2)) //"时间判定范围为1460~1900us," //((time>1345) && (time<1751))
- { //"在此范围内说明该bit值为1"
- byt >>= 1; //"因低位在先,所以数据右移, "
- byt |= 0x80; //"高位置1"
- }
- else //"不在上述范围内则说明为误码,直接退出"
- {
- IE1 = 0;
- return;
- }
- }
- ircode[i] = byt; //"接收完一个字节后保存到缓冲区"
- }
- irflag = 1; //"接收完毕后设置标志"
- IE1 = 0; //"退出前清零INT1中断标志"
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
红外遥控.rar
(752.31 KB, 下载次数: 958)
|