红外遥控编程参考(单片机读取按键编码)
51单片机红外解码资料+源代码
位地 8FH 8EH 8DH 8CH 8BH 8AH 89H 88H 址
源代码如下: #include<reg52.h> #define uchar unsigned char #define uint unsigned int sbit dula=P2^6; sbit wela=P2^7;
uchar irtime; //红外时间 uchar startflag; //启动接收 uchar irdata[33]; uchar bitnum; uchar irreceiveok; //红外接收完毕 uchar ircode[4]; uchar irprosok; uchar disp[8]; uchar code smg_du[]={
发射器发射的的信号为
接收器接收到的信号为
即 9ms 低电平后 4.5ms 高电平作为起始码,之后接受到两次 8 位客户码,一次八位数据码,和一次八位数据反码。
遥控器在按键按下之后周期性的发出同一种 32 位二进制编 码周期约为 108ms,一组码持续时间随本身的“0”“1”个数不同
而不同。大约在 45~63ms 之间,当一个键按下 36ms,振荡器使芯 片激活,将发射一组 108ms 的编码脉冲这 108ms 编码脉冲由一个 起始码(9ms),一个结束码(4.5ms),低八位地址码(9~18ms), 高八位地址码(9~18ms),八位数据码(9~18ms),和这八位数据 码反码(9~18ms),如果按下超过 108ms 仍未松开,接下来发射 的代码(连发代码)将仅有起始码(9ms)和结束码(2.5ms)组 成。
解码的关键是如何识别零和一: “0”和“1”都是以 0.56ms 低电平开始的,不同的是高电平 宽度不同,“0”为 0.56ms“1”为 1.168ms,所以必须根据高电平 宽度来区别“0”和“1”。 如果从 0.56ms 低电平过后,开始延时,0.56ms 后,若读到的 电平为低,说明该位为零,反之则为一,可靠其间,延时必须比 0.56ms'长一些,又不能超过 1.12ms,否则如果该位为零,读到的 已是下一位高电平,因此取(1.12+0.56)/2=0.84ms 最为可靠,一 般取 0.84ms 左右均可。根据码的格式,应该等待 9ms 起始码和 4.5ms 结束码完成后才能读码。 备注:定时器/计数器控制寄存器 TCON 位序 D7 D6 D5 D4 D3 D2 D1 D0 号 位符 TF1 TR1 TF0 IR0 IE1 IT1 IE0 IT0 号
c51、c52单片机红外线遥控接收解码c程序(可直接使用)
/ 亲,此程序以经过测试,可直接使用!!!/#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 引 言 现在,有很多的电器产品(如一些家用电器)的操作控制都采用了红外遥控,一些遥控功能相对简单的电器产品,红外遥控信号的接收识别往往采用与编码调制芯片配套的译码芯片。
红外遥控器按键编码
EA = 1;
//允许全局中断
EX0 = 1;
//允许 INT0 中断
PX0 = 0;
//INT0 的中断级别为低
IT0 = 0;
//设定 INT0 上升沿和下降沿都可以中断
/*初始化 T0:16 位自动重装填模式*/
{LED1=ON;LED2=OFF;LED3=OFF;LED4=OFF;LED5=OFF;}
if(temp==IR_2)
{LED1=OFF;LED2=ON;LED3=OFF;LED4=OFF;LED5=OFF;}
if(temp==IR_3)
{LED1=OFF;LED2=OFF;LED3=ON;LED4=OFF;LED5=OFF;}
break;
}
case IR_WordA: {
if((IR_Num%2)==0&&InfraredRayPin==1) {
TH0 = 0x00; TL0 = 0x00; TimeStart; break; } if((IR_Num%2)==1&&InfraredRayPin==0) { TimeStop; IR_Time=TH0; IR_Time<<=8; IR_Time|=TL0; IR_DataA<<=1; if(IR_Time<800) {
1
#define IR_WordB
2
#define IR_End
3
#define TimeStart (TR0=1)
#define TimeStop (TR0=0)
void InfraredRay_Init(void);
单片机红外遥控学习代码
count++;
if(irflag==1) //如果标志为1,则发送38KHZ载波
ir=~ir;
else ir=0; //否则一直为零
}
TR1=1; //启动定时器
while(count<set_count); //等待发送完
TR1=0; //关闭定时器
if(ircode&0x80) //判断红外编码最低位,若为1则1.69ms的低电平
}
}
else if(kb==0) //判断按键3是否按下
{
delay(10);
if(kb==0)
{
keyflag=1;
irdata=5; //若按键2按下,发送5
ET1=1; //定时器中断允许
TH1=0xf3; //初值
TL1=0xf3; //初值
}
//---------------------------------------------------------------------------
for(i=0;i<8;i++) //循环发送
{
set_count=16; //发送0.56ms的高电平
irflag=1; //启动红外发射二极管发送
count=0; //中断技计数清零
}
}
}
//---------------------------------------------------------------------------
void ir_sendbyte() //发送数据字节
{
uchar i;
红外遥控编码原理及C程序,51单片机红外遥控
case 0x19:j=1;//100+
break;
case 0x0d:k=1;//200+
break;
case 0x16:l=1;//0
break;
case 0x0c:m=1;//1
{
temp=temp>>1; //最先读出的是高位数据
dingshiqi();//定时器记高低电平时间,数据码
if((HighTime>300)&&(HighTime<900)) //说明该位是0
temp=temp&0x7f;
if((HighTime>1200)&&(HighTime<2200)) //说明该位是1
uchar code table1[]={"User Code:"};
void delay(uint x)
{
uint i,j;
for(i=x;i>0;i--)//i=xms即延时约xms毫秒
for(j=100;j>0;j--);
}
void write_com(uchar com)
{//写液晶命令函数
{
a=0;b=0;c=0;d=0;
e=0;f=0;g=0;h=0;
i=0;j=0;k=0;l=0;
m=0;n=0;o=0;p=0;
q=0;r=0;s=0;t=0;
u=0;
}
void init_1602()
{//初始化函数
uchar num;
lcden=0;
rs=0;
write_com(0x38);//1602液晶初始化
while(1)
红外遥控代码
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单片机红外遥控红外遥控接口电路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语言)
//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有没有下降沿。
c51红外遥控代码
EA=1;
EX0=1;
TCON=0x01;
}
void scan()interrupt 0
{
uint i,ti,lo,t=0;
uchar user=0,datai=0;
signal=1;
EX0=0;
for(lo=0;lo<36;lo++)
{
ti=0;
do
{
t=0;
js=1;
while(js)
{
t++;
{
if(key==hwc[i])
key=i;
}
if(t!=0)
signal=1;
EX0=1;
}
本程序只适用于本图所显示的遥控器以及stc12c5a60s2的单片机并且晶振是11.0592M的:
使用方法:
软件上将下列.c和.h加入c51工程,在主程序运行前加入红外初始化ini_hw()函数,然后运行程序的时候,如果signal=1,代表接收到按下的按键,用完后注意清零。读key就是红外按键的值(1,2,3······代表按键依次的按键值),读kr就是按键的键值。
_nop_();
for(i=0;i<80;i++)
_nop_();
if(t==255)
{
if(lo==0)
signal=0;
break;
}
if(!signal)
break;
}
if(t==255)
ti++;
if(ti==3)
break;
}while(t==255||t==0);
if(!signal)
break;
uchar pdata a[I*10],b[40],c[12]={0,128,64,32,16,8,4,2,1,0,0,0};
红外遥控解码完全资料LCD1602
红外遥控解码完全资料(LCD1602显示)本帖被一线工人执行置顶操作(2009-06-18)红外遥控解码实验一.实验目的1. 了解红外遥控编码并用单片机捕捉信号及解码2. 熟悉LCD1602的驱动二.红外遥控器编码遥控器编码分好几种,常见的32位编码码和42位编码码,目前我手中遥控器就是42位编码,如图1所示,当有按键时就会产一个9.12ms低电平和4.5ms高电平的起始码,紧接着是26位系统码,此系统码能区别不同的电器设备,防止不同机种遥控码互相干扰,接下来是8位数据码和8位数据反码,间隔23ms的高电平后,再发一个与启始码完全一样的结束码以脉宽为0.565ms、间隔0.56ms、周期为1.125ms的组合表示二进制的“0”;以脉宽为0.565ms、间隔1.685ms、周期为2.25ms的组合表示二进制的“1”,其波形如图2所示。
图2再回头看图1,大家不难看出,图1是遥控器按键1的一串编码三.硬件连接接收电咱我们使用一化红外接红外接收管1838,不需要任何外接无件,就能完成从红外线接收到输出与TTL电平信号兼容的所有工作,实物如图所示电路图如下:四.解码以上我们了解了红外遥控的编码及硬件连接,现在就对其进行解码,所谓解码就是能用单片机把以不同宽度的脉冲区别开来,一种比较好思路就是计算两次下降沿间隔时间,当单片机外部中断1口有下降沿时中断一次,并启动定时器,定时器定50us,当下次下降沿到来时我们计算定时器中断的次数,这样我们就能很好的区分不同宽度的脉冲了。
大家可能已经迫不急待的要开始解码了,别急,我们先把注意事项先讲一下,实际上,我们红外接收头收到的信号的是有毛刺的,放大后就如下图,所以在下降沿中断触发后,要做延时去抖处理*************************************以下是完整解码程序********************************/***********************************************项目:红外遥控解码(EE01学习板演示程序)**作者:一线工人**网站:电子工程师之家**本程序适合42位码遥控器,即26位系统码,16位数据码,如:57L5,55K2,54B4,KD-29,55K8,5Z26A,等型号的遥控器,转贴请保持代码的完整性*********************************************/#include<reg52.h>#define uint unsigned int#define uchar unsigned charsbit ir=P3^3;//红外端口sbit dm=P1^4;//数码管段码控制位sbit wm=P1^5;//数码管位码控制位sbit led_cs=P1^6;//LED控制位sbit rs=P3^5;//1602数据命令选择端sbit en=P3^4;//1602使能信号uchar num;uchar key_code=0;//遥控键值uchar new_code=0;//有无新按键uint buf_key_code=0;//键值暂存uchar key_bit_count=0;//键编码脉冲计数uint count=0;//定时中断次数计数uint buf_count=0;//定时中断计数暂存uchar common_code_count=0;//前导码脉冲计数uchar ir_status=0;//脉冲接收器所处的状态,0:无信号,1:系统码接收区,2:数据编码接收区uchar code table[]="EE01 DEMO:IR";uchar code table1[]="code:";uchar code table2[]={'0','1','2','3','4','5','6','7','8','9',};void delay_10us(unsigned char y)///延时子程序10us{unsigned char x;for(x=y;x>0;x--);}void delay_ms(uint z)//延时子程序1ms{uint x,y;for(x=z;x>0;x--)for(y=113;y>0;y--);}void init(void)/////初始化{ir=1; //红外端口写1led_cs=0; //关闭LEDEA=1; //开总中断TMOD=0x02; //定时器0,模式2,8位自动装载模式TH0=0Xd1; //定时50usTL0=0Xd1;IT1=1; //INT1下降沿触发ET0=1; //允许定时器中断EX1=1; //允许外部中断}/***********************************************定时器中断***********************************************/void time0() interrupt 1///定时器中断{count++;//定时器中断次数累加}/**********************************************外部中断,红外解码程序**********************************************/void int1() interrupt 2///外部中断{TR0=1;//开定时器中断if(count>12&&count<270)//如果信号合法,则放入buf_count,count清0,对下一个脉冲信号计时{buf_count=count;count=0;}delay_10us(10);//延时100us以消除下降沿跳变抖动if(ir==0)//INT1引脚稳定为低电平,则表法确实是信号,count重新计时,因上面延时了50us,故要补偿1次TO中断{count=2;}if(buf_count>12&&buf_count<270)//若收到的信号合法,则再进行信号分析{if(ir_status==0)//如果之前未收到引导码{if(buf_count>210&&buf_count<270)//判断是否引导码13.5ms{ir_status=1;//系统标记buf_count=0;//}}else if(ir_status==1)///收到引导码{if(common_code_count>=25)//若收完26个脉冲{ir_status=2;//数据解码标记common_code_count=0;//系统码计算清零buf_count=0;//中断计数暂存清0}else if((buf_count>40&&buf_count<70)||(buf_count>12&&buf_count<32)){buf_count=0;common_code_count++;//每收到一个信号自加1}}else if(ir_status==2)//进入数据编码接收{if(key_bit_count<8)//收到数据少于8位,则将收到的数据写入buf_key_code {if(buf_count>40&&buf_count<70){buf_count=0;buf_key_code>>=1;buf_key_code|=0x80;//收到1key_bit_count++;//数据脉冲累加}else if(buf_count>12&&buf_count<32)//收到0{buf_count=0;buf_key_code>>=1;//收到0key_bit_count++;}}else //若收完8位数据则做以下处理{ir_status=0;//接收状态返回到空闲key_code=buf_key_code;key_bit_count=0;buf_key_code=0;buf_count=0;TR0=0;new_code=1;}}}}/**********************************************1062驱动程序**********************************************/void wirte_cmd(uchar cmd)//写命令{rs=0;P0=cmd;en=1;delay_ms(5);en=0;}void wirte_data(uchar dat)//写数据{rs=1;P0=dat;en=1;delay_ms(5);en=0;}void wirte_string(const unsigned char *s)//在第二行第5个字开始写字符串{wirte_cmd(0x80+0x40+0x05);while(*s){wirte_data(*s);s++;}}void init_1602()///1602初始化{dm=0;wm=0;led_cs=0;wirte_cmd(0x38);delay_ms(5);wirte_cmd(0x0c);delay_ms(5);wirte_cmd(0x06);}/*************************************主程序*************************************/void main(){init(); ///初始化init_1602(); //1602初始化while(!new_code);//判断是否有新按键,如果有则执行下面程序,没有则一直循环wirte_cmd(0x01);//1602清屏delay_ms(5);wirte_cmd(0x80);//在第一行写入EE01 DEMO:IRfor(num=0;num<12;num++){wirte_data(table[num]);delay_ms(1);}wirte_cmd(0x80+0x40);//在第二行写入code:for(num=0;num<5;num++){wirte_data(table1[num]);delay_ms(1);}if(key_code<10)//如果按鍵小于10则写入相应的数字{wirte_data(table2[key_code]);delay_ms(2);}else if(key_code<50)//大于10则写入字符,与遥控器对应{switch(key_code){case 21:wirte_string("mute");break;case 28:wirte_string("power");break;case 10:wirte_string("-/--");break;case 14:wirte_cmd(0x80+0x40+0x05);wirte_data(0x7f);wirte_data(0x7e);break;//先写字符位置,然后写字符,case 25:wirte_string("SLEEP");break;case 19:wirte_string("P.P");break;case 15:wirte_string("TV/A V");break;case 30:wirte_string("VOL-");break;case 31:wirte_string("VOL+");break;case 27:wirte_string("P+");break;case 26:wirte_string("P-");break;case 16:wirte_string("MENU");break;case 24:wirte_string("A-MODE");break;case 13:wirte_string("SYS");break;case 12:wirte_string("GAME");break;case 20:wirte_string("DISP");break;delay_ms(2);}new_code=0;}}。
单片机红外线遥控器解码程序
单片机红外线遥控器解码程序
红外线遥控是目前使用最广泛的一种通信和遥控手段。
由于红外线遥控装
置具有体积小、功耗低、功能强、成本低等特点,因而,继彩电、录像机之后,在录音机、音响设备、空凋机以及玩具等其它小型电器装置上也纷纷采用红外
线遥控。
现在工业设备中,也已经广泛在使用。
1 红外遥控系统
通用红外遥控系统由发射和接收两大部分组成,应用编/解码专用集成电路芯
片来进行控制操作,如图1 所示。
发射部分包括键盘矩阵、编码调制、LED 红
外发送器;接收部分包括光、电转换放大器、解调、解码电路。
2 遥控发射器及其编码
遥控发射器专用芯片很多,根据编码格式可以分成脉冲宽度调制和脉冲相位
调制两大类,这里我们以运用比较广泛,解码比较容易的脉冲宽度调制来加以
说明,现以3310 组成发射电路为例说明编码原理。
当发射器按键按下后,即
有遥控码发出,所按的键不同遥控编码也不同。
这种遥控码具有以下特征:
采用脉宽调制的串行码,以脉宽为0.565ms、间隔0.56ms、周期为1.125ms 的组合表示二进制的“0”;以脉宽为0.565ms、间隔1.685ms、周期为2.25ms 的组合表示二进制的“1”
上述“0”和“1”组成的42 位二进制码经38kHz 的载频进行二次调制以提高发
射效率,达到降低电源功耗的目的。
然后再通过红外发射二极管产生红外线向
空间发射,
3310 产生的遥控编码是连续的42 位二进制码组,其中前26 位为用户识别码,能区别不同的红外遥控设备,防止不同机种遥控码互相干扰。
后16 位为8 位
的操作码和8 位的操作反码用于核对数据是否接收准确。
关于用PIC单片机红外遥控的编码与解码
关于用PIC单片机红外遥控的编码和解码一般常用的红外遥控器编码规则都差不多,基本上都同6221原理一样(可在网上找到)接收时:如果用54,57这类片子做的话有一定的难度(假如要做成实时控制的;比如说你还要驱动显示,驱动步进电机,在加上几个按键)原因就是这类片子没有中断例程如下(用来解6221;分频比为256)RF:BTFSC PORTB,2;;B2口用做接收口GOTO RF1BTFSS DOWNBIT;;检测下降沿标制CLRF RTCCOUNTBSF DOWNBIT;制下降沿标制BTFSS UPBIT;;检测上升沿标制RETLW 0BTFSC IDBIT;;检测码头标制GOTO RF3MOVLW 2AHSUBWF RTCCOUNT,0BTFSS STATUS,0GOTO RF2MOVLW 36HSUBWF RTCCOUNT,0 BTFSC STATUS,0 GOTO RF2BTFSC IDBITGOTO RF3MOVLW .8MOVWF LOOP MOVLW .3MOVWF LOOPCOUNT CLRF DATACOUNT BSF IDBITBSF DOWNBITBCF UPBITCLRF RTCCOUNT RETLW 0RF1:BTFSS DOWNBIT RETLW 0BSF UPBITRETLW 0RF2:BCF DOWNBITBCF IDBITCLRF RTCCOUNT RETLW 0 ;遥控接收RF3:MOVLW 02HSUBWF RTCCOUNT,0 BTFSS STATUS,0 GOTO RF4MOVLW 0CH SUBWF RTCCOUNT,0 BTFSS STATUS,0 GOTO RF4GOTO RF2RF4:MOVLW 08HSUBWF RTCCOUNT,0 BTFSC STATUS,0 BSF 3H,0MOVLW 07HSUBWF RTCCOUNT,0 BTFSS STATUS,0RLF DATACOUNT,1BSF DOWNBITBCF UPBITCLRF RTCCOUNTDECFSZ LOOP,1RETLW 0MOVLW .8MOVWF LOOPDECFSZ LOOPCOUNTRETLW 0BSF RFBIT;;制接收完标制BCF DOWNBITBCF UPBITBCF IDBITCLRF RTCCOUNTRETLW 0////////////////////////////////////////////////////////// TIME:BTFSC TIMEPD1GOTO TIME1MOVF RTCC,0;;(MOVWF TIMEONEBSF TIMEPD1RETLW 0 ;定时查寻TIME1:MOVF RTCC,0SUBWF TIMEONE,0BTFSC STATUS,2RETLW 0BCF TIMEPD1INCF RTCCOUNT,1RETLW 0////////////////////////////////////////////////在这里我是用查询的方式来定时的(RTCCOUNT)只是在解码时不需要去追求时间精度;我是去查RTCC 有没有发生跳变如有则表示时间过了256US---RTCCOUNT加一;这样做有一个好处---你不必去管RTCC 具体的值是多少,(RTCC去做精确的时钟定时;在这个查询的子程序中你可以去判断键扫,显示刷新,驱动步进电机等等)相应的C代码如下:unsigned char rfcount,loop,rftime,//查询定时器k;bit rfbit, //接收完标制lowbit1,lowbit2,downbit,rfgobit;unsigned char dispcount[5];//结果#define rfin RC6//////////////////////////////////////////////////////////////////////////////// rf( )//遥控接收{if(rfbit==0){if((lowbit1==0)&&(rfin==0)){downbit=1;rftime=0;lowbit1=1;return;if((lowbit1==1)&&(rfin==1)){lowbit2=1;return;}if((lowbit1==1)&&(lowbit2==1)&&(RC6==0)) {lowbit1=0;lowbit2=0;if((rftime>=40)&&(downbit==1))//遥控接收;{rfgobit=1;loop=0;rfcount=0;k=1;rftime=0;return;}rfcount=rfcount+1;loop=loop+1;if(rfcount>=31)rfgobit=0;downbit=0;rfcount=0;rfbit=1;loop=0;return;}if((rftime>=7)&&(rfgobit==1)) {dispcount[k]=dispcount[k]|0x80; rftime=0;if(loop==8){k=k+1;loop=0;return;}dispcount[k]=dispcount[k]>>1; return;}if((rftime<5)&&(rfgobit==1))dispcount[k]=dispcount[k]&0x7f;rftime=0;if(loop==8){k=k+1;loop=0;return;}dispcount[k]=dispcount[k]>>1;return;}}}}(查询子程序同汇编)假如用中断的话也可用时间查询的方法,只是接收口改用带中断的口线;RB4--RB7,CCP1,CCP2,都可以。
用单片机解码红外遥控器
用单片机解码红外遥控器遥控器使用方便,功能多.目前已广泛应用在电视机、VCD、DVD、空调等各种家用电器中,且价格便宜,市场上非常容易买到。
如果能将遥控器上许多的按键解码出来.用作单片机系统的输入.则解决了常规矩阵键盘线路板过大、布线复杂、占用I/O口过多的弊病。
而且通过使用遥控器,操作时可实现人与设备的分离,从而更加方便使用。
下面以TC9012编码芯片的遥控器为例。
谈谈如何用常用的51系统单片机进行遥控的解码。
一、编码格式1、0和1的编码遥控器发射的信号由一串O和1的二进制代码组成.不同的芯片对0和1的编码有所不同。
通常有曼彻斯特编码和脉冲宽度编码。
TC9012的O和1采用PWM方法编码,即脉冲宽度调制,其O码和1码如图1所示(以遥控接收输出的波形为例)。
O码由O.56ms低电平和0.56ms高电平组合而成.脉冲宽度为1.12ms.1码由0.56ms低电平和1.69ms高电平组合而成.脉冲宽度为2.25ms。
在编写解码程序时.通过判断脉冲的宽度,即可得到0或1。
2、按键的编码当我们按下遥控器的按键时,遥控器将发出如图2的一串二进制代码,我们称它为一帧数据。
根据各部分的功能。
可将它们分为5部分,分别为引导码、地址码、地址码、数据码、数据反码。
遥控器发射代码时.均是低位在前。
高位在后。
由图2分析可以得到.引导码高电平为4.5ms,低电平为4.5ms。
当接收到此码时.表示一帧数据的开始。
单片机可以准备接收下面的数据。
地址码由8位二进制组成,共256种.图中地址码重发了一次。
主要是加强遥控器的可靠性.如果两次地址码不相同.则说明本帧数据有错.应丢弃。
不同的设备可以拥有不同的地址码.因此。
同种编码的遥控器只要设置地址码不同,也不会相互干扰。
图中的地址码为十六进制的0EH(注意低位在前)。
在同一个遥控器中.所有按键发出的地址码都是相同的。
数据码为8位,可编码256种状态,代表实际所按下的键。
数据反码是数据码的各位求反,通过比较数据码与数据反码.可判断接收到的数据是否正确。
单片机红外遥控编码与解码
用电器、视听产品的普及,红外线遥控器已被广泛使用在各种类型的家电产品上(如遥控开关、智能开关等)。
其具有体积小、抗干扰能力强、功耗低、功能强、成本低等特点,在工业设备中也得到广泛应用。
一般而言,一个通用的红外遥控系统由发射和接收两大部分组成,如图1 所示:其中发射部分主要包括键盘矩阵、编码调制、红外发射管;接收部分包括光、电信号的转换以及放大、解调、解码电路。
举例来说,通常我们家电遥控器信号的发射,就是将相应按键所对应的控制指令和系统码( 由0 和1 组成的序列),调制在32~56kHz 范围内的载波上,然后经放大、驱动红外发射管将信号发射出去。
此外,现在流行的控制方法是应用编/ 解码专用集成电路芯片来实现。
不同公司的遥控芯片,采用的遥控码格式也不一样。
在此介绍目前广泛使用较普遍的两种,一种是NEC Protocol 的PWM( 脉冲宽度调制) 标准,一种是Philips RC-5 Protocol 的PPM( 脉冲位置调制) 标准。
NEC 标准(代表芯片WD6122):遥控载波的频率为38kHz( 占空比为1:3) ;当某个按键按下时,系统首先发射一个完整的全码,然后经延时再发射一系列简码,直到按键松开即停止发射。
简码重复为延时108ms,即两个引导脉冲上升沿之间的间隔都是108ms。
如图2所示即为完整的NTC编码。
对于NTC编码,由引导码、用户编码低位,用户编码高位、键数据编码、键数据编码五部分组成,引导码由一个9ms的载波波形和4.5ms的关断时间构成,它作为随后发射的码的引导,这样当接收系统是由微处理器构成的时候,能更有效地处理码的接收与检测及其它各项控制之间的时序关系。
编码采用脉冲位置调制方式(PPM)。
利用脉冲之间的时间间隔来区分“0”和“1”。
每次8位的码被传送之后,它们的反码也被传送,减少了系统的误码率。
数据0 可用“高电平0.56ms +低电平0.56ms”表示,数据1 可用“高电平0.56ms +低电平1.68ms”表示。
红外遥控编码学习程序
如果counterDDD=0 counterDDD=0 counterDDD=0 TMR1PWMH=45 counterTTT=4500 TMR1PWML=60 counterAAA=4500 counterBBB=4560 counterCCC=4560 counterWWW=2fcounterDDD=2f TMR1PWMH=27 counterTTT=200 TMR1PWML=cc counterAAA=200 counterBBB=2cc counterCCC=2cc counterWWW=1counterDDD=1 TMR1PWMH=24 counterTTT=200 TMR1PWML=d1 counterAAA=200 counterBBB=2d1 counterCCC=2d1 counterWWW=1counterDDD=1 TMR1PWMH=4f counterTTT=4f00 TMR1PWML=8f counterAAA=4f00 counterBBB=4f8f counterCCC=4f8f counterWWW=36counterDDD=36 counterDDD=0counterDDD=0 counterDDD=0 TMR1PWMH=0 counterTTT=0 TMR1PWML=20 counterAAA=0 counterBBB=20 counterCCC=20 counterWWW=0counterDDD=0 TMR1PWMH=20 counterTTT=200 TMR1PWML=ea counterAAA=200 counterBBB=2ea counterCCC=2ea counterWWW=1counterDDD=1 TMR1PWMH=23 counterTTT=300 TMR1PWML=95 counterAAA=300 counterBBB=395 counterCCC=395 counterWWW=2counterDDD=2 TMR1PWMH=18 counterTTT=1800 TMR1PWML=83 counterAAA=1800 counterBBB=1883 counterCCC=1883 counterWWW=10counterDDD=10counterDDD=0counterDDD=0counterDDD=0我们手上有一个红外遥控器,但是我们并不知道遥控器的红外编码是什么,那么我们就无法使用该遥控器,通过本程序则可以通过学习来获得未知遥控器的红外编码,本程序适用于NEC协议,其他常用协议尚未加上去,以后再努力完善,大伙在使用过程中遇到问题或者有什么建议可以跟我交流。
探索单片机解码红外遥控信号的简单编程
定 稿 日期 : 0 0 1- 2 2 1- 0 1
用 户码 高 8 、 户 码低 8 、 键 码 8 、 键 反码 8 。图 位 用 位 按 位 按 位
2 从 一体 化 红 外接 收 头输 出端 获取 的完 整 的遥 控码 波 形 图 。 是 无 红 外码 时 , 直 为 高 电 平 , 遥 控 码 输 出 时 , 先 是 9 的 一 有 首 ms 低 电平 ,接 着 是 4 的 高 电 平 ,以后 就 是 3 ms 2位 的 数 据脉 冲
ZH AN G —h En
( h n q gC t u y n o n o r u pyC . t. n a gC o g mg4 4 0 , h a C o g i i Y n a gC u t P we p l o, d Yu y n h n q 0 5 0c i ) n y y S L n
t og a ss pl d ay t nd rtn hepr r m i i m ea n e s O u esa d. I ie 2 bi ul o o ary y 8 tD e , n e s w n te LCD i ui rsa twrt s3 t p s c det ra b il a d t n ho i s e s h h l q d c ytl d s a o t rby he a e i a. iply m nio x d cm 1
Re e r h o h i p e tP o r m m i g o i g e Ch p s a c n t e S m ls r g a n fS n l i
M ir c m p e c d sI f a e m o e S g a coo ut r De o e n r r d Re t i n l
通过Arduino程序获取红外遥控器按键键值编码
通过Arduino程序获取红外遥控器按键键值编码一、以如下遥控器举例:二、检测按键键值的arduino程序:#include//红外遥控库文件网上存有,一般会通过百度账号给我帖子intrec_pin=11;//接收端插槽irrecvirrecv(rec_pin);decode_resultsresults;voidsetup(){serial.begin(9600);//键值在串口通信窗口中查看irrecv.enableirin();//红外接收端初始化}voidloop(){if(irrecv.decode(&results))//是否收到键值编码{serial.println(results.value,hex);//通过串口列印十六进制的键值delay(500);irrecv.resume();//接收下一个值}}1三、检测到的十六进制按键键值(在串口监视器中查看):按键(1)(4)(7)(*)(←)键值0xffa25d0xff22dd0xffe01f0xff68970xff10ef 按键(2)(5)(8)(0)(↑)(ok)(↓)键值0xff629d0xff02fd0xffa8570xff98670xff18e70xff38c70xff4ab5按键(3)(6)(9)(#)(→)键值0xffe21d0xffc23d0xff906f0xffb04f0xff5aa5四、arduino的红外遥控器掌控led例程:includeintrecv_pin=11;irrecvirrecv(recv_pin);decode_resultsresults;voidsetup(){serial.begin(9600);irrecv.enableirin();//初始化红外遥控pinmode(13,1);led初始化,照亮}voidloop(){if(irrecv.decode(&results)){if(results.value==0xffa25d)//确认接收到按键(1)的编码,此码是预先读出来的按键编码。
单片机红外遥控器解码例程源码新说
单片机红外遥控器解码例程源码新说这是第三次更改这个红外遥控解码的例程了。
之前的第一版是直接用51单片机的外部中断然后在里边加延时采集高低电平的长短来判断引导码和位1位0 的,这个当初不知是从哪看的,这种方式太误导人了,如果想用这种思路移植到stm32 上,还是趁早打住吧,stm32 这种高级处理器难道只用来红外遥控解码吗?不,肯定会有更高级的任务去等待他处理,外部中断加延时可以提高遥控的响应速度,但实际上这种方式很占资源,当cpu 在处理其他紧急任务的时候,突然来个按键,打断进程,并且一置占用进程,经测试过,遥控一个键码有50-90ms,这对单片机来说可是不小的时间啊。
所以,可以结合外部中断+定时器两种方式来解码。
外部中断开启上升和下降沿同时触发。
这样的话,我们在两次触发后,计算出高或低的点评时间看是否准确,就可以了。
可以采用状态机也就是状态变换的思路来解码。
引导码和用户码,分成两部分来解。
高电平和低电平分成两部分来解码。
又因为位1 和位0 之间区别在于高电平的时间不同,也就是位0 _||位1 _||两者的低电平的时间都是一样的,而后边的高电平长的为1 短的为0,有这个特点就特别好解决了。
可参考之前的文章,xiaovdiy/?post=138 源代码奉上if(EXTI_GetITStatus(EXTI_Line12)!= RESET) { if(RDATA()==0)//说明是下降沿到来{ TIM_Cmd(TIM4, ENABLE);if(lead_flg==0)//说明是第一次接收引导码{ TIM_SetCounter(TIM4,0);//TIM4- >CNT=0;(1)lead_flg=1; } else if(lead_flg==2) { ir_cnt= TIM_GetCounter(TIM4); TIM_SetCounter(TIM4,0); lead_flg=3; if((ir_cnt90))//测试表明为79 或80 { lead_flg=0; //超出范围退出return 0; } } else if(lead_flg==3)// 获得高电平时间{ ir_cnt= TIM_GetCounter(TIM4); TIM_SetCounter(TIM4,0); // 接收3 个字节24 位码high_cnt++;//加到24 位每8 次为1 个字节。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
程序可以用来查看每个遥控按键的编码,以便于开发利用遥控每一个按键。
#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);
}。