红外遥控编程参考(单片机读取按键编码)
- 格式:doc
- 大小:29.00 KB
- 文档页数:9
/ 亲,此程序以经过测试,可直接使用!!!/#include <reg51.h>#define uchar unsigned char#define uint unsigned intvoid delay(uchar x);sbit IRIN = P3^2;uchar IRCOM[4];void main(){ IE = 0x81;TCON = 0x01;IRIN=1;/* 此处可以根据按键码自由编写程序/以下为3*7遥控按键码//(也可以应用与其他类型遥控,本程序只以3*7遥控为例)/ / 0x45 0x46 0x47 // 0x44 0x40 0x43 // 0x07 0x15 0x09 // 0x16 0x19 0x0d // 0x0c 0x18 0x5e // 0x08 0x1c 0x5a // 0x42 0x52 0x4a /例如:while(1){switch(IRCOM[2]){case 0x45: P2=0x7f; break;case 0x44: P2=0xbf; break;case 0x07: P2=0xdf; break;case 0x16: P2=0xef; break;case 0x0c: P2=0xf7; break;case 0x08: P2=0xfb; break;case 0x42: P2=0xfd; break;case 0x52: P2=0xfe; break;case 0x4a: P2=0xff; break;case 0x5a: P2=0x00; break;}} */while(1);} //end main/**********************************************************/ void IR_IN(void) interrupt 0 //外部中断服务程序{unsigned char j,k,N=0;EX0 = 0;delay(15);if (IRIN==1){ EX0 =1;return;}//确认IR信号出现while (!IRIN) //等IR变为高电平,跳过9ms的前导低电平信号。
文章编号:100622475(2000)0620108203红外遥控信号的编码方法与单片机译码程序的设计崔如春, 谭海燕(佛山科学技术学院计算机系,广东佛山 528000)摘要:介绍了两种常用的红外遥控信号的编码方法:脉冲占空比编码调制,脉冲宽度编码调制。
提出了用单片机对其进行识别译码的程序设计方法。
并给出了程序设计举例。
关键词:红外遥控;编码;译码;单片机中图分类号:T P 722.5 文献标识码:AEncod i ng M ethods and M icroprocessor D ecod i ng Programm i ngfor Rem ote Con trol Signa lCU I R u 2chun , TAN H ai 2yan(D epartm ent of Computer Science and T echno logy ,Fo shan U niversity ,Fo shan 528000,Ch ina )Abstract :In troduces tw o u sual remo te con tro l signal encoding m ethods :pu lse w idth modu lati on ,pu lse space rati o modu lati on .T he decoding p rogramm ing m ethod of m icrop rocesso r is p ropo sed w ith a p rogramm ing examp le .Key words :remo te con tro l ;encode ;decode ;m icrop rocesso r0 引 言 现在,有很多的电器产品(如一些家用电器)的操作控制都采用了红外遥控,一些遥控功能相对简单的电器产品,红外遥控信号的接收识别往往采用与编码调制芯片配套的译码芯片。
UPD6121G产生的遥控编码是连续的32位二进制码组,其中前16位为用户识别码,能区别不同的电器设备,防止不同机种遥控码互相干扰。
该芯片的用户识别码固定为十六进制01H;后16位为8位操作码(功能码)及其反码。
UPD6121G 最多额128种不同组合的编码。
遥控器在按键按下后,周期性地发出同一种32位二进制码,周期约为108ms。
一组码本身的持续时间随它包含的二进制“0”和“1”的个数不同而不同,大约在45~63ms之间,图4为发射波形图。
当一个键按下超过36ms,振荡器使芯片激活,将发射一组108ms的编码脉冲,这108ms发射代码由一个起始码(9ms),一个结果码(4.5ms),低8位地址码(9ms~18ms),高8位地址码(9ms~18ms),8位数据码(9ms~18ms)和这8位数据的反码(9ms~18ms)组成。
如果键按下超过108ms仍未松开,接下来发射的代码(连发代码)将仅由起始码(9ms)和结束码(2.5ms)组成。
代码格式(以接收代码为准,接收代码与发射代码反向)①位定义②单发代码格式③连发代码格式注:代码宽度算法:16位地址码的最短宽度:1.12×16=18ms16位地址码的最长宽度:2.24ms×16=36ms易知8位数据代码及其8位反代码的宽度和不变:(1.12ms+2.24ms)×8=27ms 所以32位代码的宽度为(18ms+27ms)~(36ms+27ms)1.解码的关键是如何识别“0”和“1”,从位的定义我们可以发现“0”、“1”均以0.56ms的低电平开始,不同的是高电平的宽度不同,“0”为0.56ms,“1”为1.68ms,所以必须根据高电平的宽度区别“0”和“1”。
如果从0.56ms低电平过后,开始延时,0.56ms以后,若读到的电平为低,说明该位为“0”,反之则为“1”,为了可靠起见,延时必须比0.56ms长些,但又不能超过1.12ms,否则如果该位为“0”,读到的已是下一位的高电平,因此取(1.12ms+0.56ms)/2=0.84ms最为可靠,一般取0.84ms左右均可。
STM32单片机红外遥控红外遥控接口电路STM32单片机红外遥控程序源代码#include "sys.h"#define LED_RED PBout(12) //红色发光二极管控制管脚初始化PB12 #define LED_GREEN PBout(13) //绿色发光二极管控制管脚初始化PB13 #define LED_YELLOW PBout(14) //黄色发光二极管控制管脚初始化PB14 #define LED_BLUE PBout(15) //蓝色发光二极管控制管脚初始化PB15 #define BEEP PBout(5) //蜂鸣器端口定义PB5#define RDATA PAin(1) //红外数据输入脚//红外遥控识别码(ID),每款遥控器的该值基本都不一样,但也有一样的//我们选用的遥控器识别码为0#define REMOTE_ID 0static u8 fac_us=0; //us延时倍乘数static u16 fac_ms=0; //ms延时倍乘数void delay_init(u8 SYSCLK);void delay_ms(u16 nms);void delay_us(u32 nus);void Led_Init(void); //发光二极管控制管脚初始化void Red_Led_Light(void); //点亮红色发光二极管void Green_Led_Light(void); //点亮绿色发光二极管void Yellow_Led_Light(void); //点亮黄色发光二极管void Blue_Led_Light(void); //点亮蓝色发光二极管void Red_Led_Goout(void); //熄灭红色发光二极管void Green_Led_Goout(void); //熄灭绿色发光二极管void Yellow_Led_Goout(void); //熄灭黄色发光二极管void Blue_Led_Goout(void); //熄灭蓝色发光二极管void Beep_Init(void);void Beep_Tweet(void);void Beep_Silent(void);extern u8 Remote_Cnt; //按键次数,此次按下键的次数extern u8 Remote_Rdy; //红外接收到数据extern u32 Remote_Odr; //命令暂存处u32 Remote_Odr=0; //命令暂存处u8 Remote_Cnt=0; //按键次数,此次按下键的次数u8 Remote_Rdy=0; //红外接收到数据void Remote_Init(void); //红外传感器接收头引脚初始化u8 Remote_Process(void); //红外接收到数据处理u8 Pulse_Width_Check(void); //检查脉宽extern u8 USART_RX_BUF[64]; //接收缓冲,最大63个字节.末字节为换行符extern u8 USART_RX_STA; //接收状态标记//如果想串口中断接收,请不要注释以下宏定义//#define EN_USART1_RX //使能串口1接收void uart_init(u32 pclk2,u32 bound);/*************************************************************开发板上电后,用红外遥控器对着开发板上的红外接收头。
//51单片机做的红外遥控实验(C语言)#include<reg51.h>#define u8 unsigned char#define u16 unsigned int#define ID 0x00 //本遥控器的ID号sbit ir=P3^3;code u8 seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //0-9的段码code u8 s[]={1,0x40,0x48,0x04,0x02,0x05,0x54,0x0A,0x1E,0x0E}; u8 buf[4];bit ir_f=0;u8 nu;void delay(u16 x){while(x--);}void show(u16 x){u8 i=0,k=0;u8 s[4];kk:s[i]=x%10;if((x/10)>=1){x=x/10;i++;goto kk;}k=i+1;for(i=0;i<k;i++){P0=seg[s[i]];P2=~(8>>i);delay(300);P0=0XFF;P2=0XFF;}}void timer0_init(){TH0=0;TL0=0;TMOD|=0x01;TR0=0;}u16 low_test(){u16 t;TR0=1;while((ir==0)&&((TH0&0X80)!=0X80));TR0=0;t=TH0;t<<=8;t|=TL0;TH0=0;TL0=0; //t=(TH*256+TL0);//机器周期数return t;}u16 high_test(){u16 t;TR0=1;while((ir==1)&&((TH0&0X80)!=0X80));TR0=0;t=TH0;t<<=8;t|=TL0;TH0=0;TL0=0;return t;}/*u16 time_test(bit x){}*/u8 receive_8bit(){u8 d,i;u16 t;for(i=0;i<8;i++){t=low_test();t=high_test();d>>=1;if((t>=2750)&&(t<=3100)){d|=0x80;}}return d;}void ir_decode(){u16 t;u8 i;if(ir==0)//有遥控信号{t=low_test();//8295-9000us,倍频的是16590-18000if((t>=14500)&&(t<=18000))//检查引导码低电平时间{t=high_test();if((t>=8000)&&(t<=9000))//检查高电平{for(i=0;i<4;i++){buf[i]=receive_8bit();}if(buf[0]==(~buf[1]))//检查系统码是否正确{if(buf[0]==ID){if(buf[2]==(~buf[3])){//具体按键处理ir_f=1; //遥控有效}}}}}}}/*void key(){if(buf[2]==0x40){P1^=(1<<0);}if(buf[2]==0x48){P1^=(1<<1);}}*/void ir_execuse(){if(ir_f==1){switch(buf[2]){case 0x40:P1^=(1<<0);break;case 0x48:P1^=(1<<1);break;case 0x04:P1^=(1<<2);break;case 0x02:P1^=(1<<3);break;case 0x05:P1^=(1<<4);break;case 0x54:P1^=(1<<5);break;case 0x0A:P1^=(1<<6);break;case 0x1E:P1^=(1<<7);break;}ir_f=0;}}void show_d(){u8 j;for(j=0;j<10;j++){if(s[j]==buf[2]){nu=j;break;}}show(nu);}void isr_init(){EA=1;EX1=1;//外部中断,一直看3.3有没有下降沿。
程序可以用来查看每个遥控按键的编码,以便于开发利用遥控每一个按键。
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit en=P3^4;
sbit rs=P3^5; //用于控制1602
sbit rw=P3^6;
sbit dula=P2^6;
sbit wela=P2^7; //用于控制晶体管
sbit IRIN=P3^2; //红外接收器数据线IO 口
uchar IRCOM[4]=0;
//定义数组IRCOM,分别装解码后得到的数据//IRCOM[0] 低8位地址码
//IRCOM[1] 高8位地址码
//IRCOM[2] 8位数据码
//IRCOM[3] 8位数据码的反码
uchar code table[]="MAKE BY HEIQISHI"; uchar code table1[]="The code is 0x";
uchar code table2[]="0123456789abcdef";
//////////////显示程序///////////////////
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=112;y>0;y--); //大约是1ms,因为单片机的时钟周期为11.0592mhz。
}
void Write_com(uchar com)
{
rs=0; //指令
P0=com; //写指令函数
delay(5);
en=1;
delay(5);
en=0;
}
void Write_data(uchar dat)
{
rs=1; //数据
P0=dat; //写指令函数
delay(5);
en=1;
delay(5);
en=0;
}
void _1602Init()
{
wela=0;
dula=0; //用于关闭晶体管,因为都是用P0
en=0; //初始时使能为0
rw=0;
Write_com(0x38); //显示屏模式设置为1602方案
Write_com(0x0c); //显示开关/光标设置
Write_com(0x06);
Write_com(0x01); //清屏
Write_com(0x80); //指针置零
}
/////////////////////////////////////////////////////
/////////////////解码程序///////////////////
void delay014ms(uchar x) //x*0.14MS STC10F04延时约0.15MS
{
uchar i;
while(x--)
{
for(i=0;i<15;i++) //13
;
}
}
//////////////初始化////////////
void IR_init(void)
{
EA=1;
EX0=1; //允许总中断中断,使能INT0 外部中断
IT0=1; //触发方式为脉冲负边沿触发IRIN=1; //I/O口初始化
}
////////////解码过程//////////////
void IR_CODE(void) interrupt 0 //在外部中断子程序中解码
{
uchar j,k,N=0,shi,ge;
EX0=0; //防止干扰
delay014ms(15); //延时2.1ms
if (IRIN) //2.1ms能够检测出各种错误信号
{
EX0 =1;
return;
} //确认IR信号出现while(!IRIN); //等IR变为高电平,跳过9ms的前导低电平信号。
delay014ms(18); //2.25ms~4.5ms之间能够检测出引导码信号
if(!IRIN)
{
EX0 =1;
return;
}
//////高电平后开始检测高电平持续的时间以确定是0还是1/////
for(j=0;j<4;j++) //收集四组数据{
for(k=0;k<8;k++) //每组数据有8位
{
while (IRIN); //等IR 变为低电平,跳过4.5ms的前导高电平信号。
//引导码检验结束
while (!IRIN); //等IR 变为高电平开始检测
while (IRIN) //计算IR高电平时长
{
delay014ms(1);
N++;
if (N>=30)
{
EX0=1;
return;
} //0.14ms计数过长自动离开
} //高电平计数完毕
IRCOM[j]=IRCOM[j] >> 1; //数据最高位补"0"
if (N>=8)
{
IRCOM[j] = IRCOM[j] | 0x80;
} //数据最高位补"1"
N=0;
}
}
if (IRCOM[2]!=~IRCOM[3]) //不等的话表示解码失败
{
IRCOM[4]=0;
EX0=1;
return;
}
shi=IRCOM[2]/16;
ge=IRCOM[2]%16;
Write_com(0xce);
Write_data(table2[shi]);
Write_data(table2[ge]);
EX0=1;
P1=~IRCOM[2];
return;
}
/////////////////////////////////////////////////////
void main()
{
uchar i;
IR_init();
_1602Init();
for(i=0;i<16;i++)
Write_data(table[i]);
Write_com(0xc0);
for(i=0;i<14;i++)
Write_data(table1[i]); while(1);
}。