红外解码程序(带详细注释)

合集下载

最简单详细的红外解码程序

最简单详细的红外解码程序

#include<reg52.h> //包含头文件名sbit IRIN=P3^2; //定义红外接收头的外部接口,即外部中断0sbit BEEP=P1^5; //定义蜂鸣器接口,我的在P1^5unsigned char IRCOM[7]; //定义数组,用来存储红外接收到的数据void delay(unsigned char x){ //延时子程序unsigned char i; //延时约x*0.14mswhile(x--) //不同遥控器应设置不同的参数{for(i=0;i<13;i++){}} //参数的选择咱们先不管,先看这个}void beep(){unsigned char i; //蜂鸣器发声子程序for(i=0;i<100;i++){delay(4); //这个得看你的蜂鸣器内部是否有振荡源BEEP=~BEEP;} //如果没有振荡源就应该输入脉冲信号BEEP=1;}void IR_IN() interrupt 0 using 0 //外部中断0程序{unsigned char j,k,n=0; //先定义变量,记住n=0EX0=0; //禁止中断,以免再次进入中断delay(15); //延时0.14ms*15=2.1msif(IRIN==1) //如果在这期间有高电平说明{ //信号不是来自遥控的,返回主程序EX0=1;return;}while(!IRIN){delay(1);} //死循环,等待9ms前导低电平信号的结束for(j=0;j<4;j++) //一共有4组数据{for(k=0;k<8;k++) //每组数据有8位{while(IRIN){delay(1);} //死循环,等待4.5ms前导高电平的结束while(!IRIN){delay(1);} //等待0.56ms低电平的结束,准备采集数据,while(IRIN) //开始采集数据{delay(1); //延时0.14ms,每过0.14ms时n就加1n++; //用n记录一共有多少个0.14msif(n>=30) //如果超过0.14ms*30=4.2ms{ //说明是乱码,放弃不要EX0=1;return;}}IRCOM[j]=IRCOM[j]>>1; //右移1位,xxxx xxxx变成0xxx xxx//我们先认为这一位数据是0,现在已经送入一位数据了/*你肯定知道_cror_(x,1)和x>>1的区别吧*/if(n>=8){IRCOM[j]=IRCOM[j]|0x80;}//但是如果不是0呢,//0xxx xxxx和0x80相或后变成了1xxx xxxx//这样这一们数据就被记录为1了/*想一下这里为什么是8呢,0.14ms*8=1.12ms,知道了吧*//*这样反复执行8次,8位数据就存在IRCOM[j]中了*//*外层再循环4次,4*8=32位数据码全都在IRCOM[0],IRCOM[1],IRCOM[2],IRCO M[3]中了*/n=0; //n计数后一定要记得清0,否则下一次就不能准确计数了}}if(IRCOM[2]!=~IRCOM[3]) //这里我们判断数据码和数据反码是不是相反{ //因为相反才是正确的,否则就放弃EX0=1;return;}beep();EX0=1; //记得开中断,你可以去掉这句话试一试}void main(){IE=0x81;TCON=0X01;BEEP=1;IRIN=1;while(1);}怎么样,你看懂了吗?作者:任杰。

(完整word版)红外编码解码程序(word文档良心出品)

(完整word版)红外编码解码程序(word文档良心出品)

红外编码解码程序,我写的是:发送模块通过按键,发送出相应键值的编码,接收模块接收到信号后解码该键值,并点亮相应的状态灯(新手,高手勿喷)//************************* 单片机红外发射******************************* #include<reg52.h> sbit ir=P 1人3;sbit k1= P2A5;sbit k2=P2M;sbit k3=P2A3;sbit k4=P2A2;sbit k5=Pil;unsigned int count, set_count; bit irflag,keyflag; unsigned char irsys[]={0x00,0xff}; unsigned char irdata,ircode;void delay(unsigned int a){unsigned char i;while(--a!=0) for(i=300;i>0;i--);}void keyscan(){/*if(k1==0){delay(10);if(k1==0){keyflag=1;while(!k1);irdata=0x01;}*/ if(k2==0) {delay(10); if(k2==0) {keyflag=1;while(!k2); irdata=0x02;}{delay(10); if(k3==0) {keyflag=1;while(!k3); irdata=0x03;} if(k4==0){delay(10); if(k4==0) {keyflag=1;while(!k4); irdata=0x04;} if(k5==0){delay(10); if(k5==0) {keyflag=1;while(!k5); irdata=0x05;void ir_sendbyte() // 红外发送一个字节数据{ unsigned char i; for(i=0;i<8;i++) //发送8 位数据{set_count=43; //发送编码中的0.56ms 高电平irflag=1;count=0;TR0=1; while(count<set_count);TR0=0;if(ircode&0x01) set_count=130; // 判断红外编码最低位,若为 1 则 1.69ms 的低电平else set_count=43; // 为0 则0.565ms 的低电平irflag=0;count=0;TR0=1; while(count<set_count);TR0=0; ircode=ircode>>1;}}void ir_send(){set_count=346; //发送编码中的引导码(4.5ms高电平+4.5ms低电平)irflag=1;count=0;TR0=1;while(count<set_count);set_cou nt=346; //发送编码中的 4.5ms低电平irflag=0;count=0;TR0=1;while(count<set_count);TR0=0; ircode=irsys[0];ir_sendbyte();ircode=irsys[1];ir_sendbyte();ircode=irdata; //发送8 位数据码ir_sendbyte();ircode=~irdata; // 发送8 位数据反码ir_sendbyte();set_count=43; //发送编码中的0.56ms高电平irflag=1;count=0;TR0=1;while(count<set_count);TR0=0;irflag=0;/*delay(23); //延时23ms (编码中的23ms低电平)set_count=346; //发送编码中的引导码(4.5ms高电平+4.5ms低电平) irflag=1;count=0;TR0=1; while(count<set_count);TR0=0; set_count=346; irflag=0;count=0;TR0=1;while(count<set_count);TR0=0;*/ set_count=43;irflag=1;count=0;TR0=1;while(count<set_count);TR0=0;irflag=0;delay(23);}void timer0_init(){EA=1;TMOD=0x02;//定时0 8 位自动重装模式ET0=1;TH0=0xe6; //定时13us,38K 红外矩形波,晶振24M TL0=0xe6; }void main(){timer0_init();count=0;ir=0;irflag=0;while(1){keyscan(); if(keyflag) {delay(10); ir_send(); delay(500); keyflag=0;delay(100);}}}void timer0() interrupt 1 {count++;if(irflag==1)ir=~ir; // 有发射标志,则发射38khz 的矩形波elseir=0;红外接收**************************** //*************************#include<reg52.h>#define uchar unsigned char #define uint unsigned intsbit led仁P2A1;sbit led2=卩2人2;sbit led3=卩2人3;uchar irtime;uchar startflag;uchar irdata[33];uchar bitnum;uchar irreceok;uchar ircode[4]; uchar irprosok;void display();void timer0init(){TMOD=0x02;TH0=0x00;TL0=0x00;ET0=1;EA=1;TR0=1;void int0init(){IT0=1;EX0=1; EA=1;}}void irpros(){uchar k,i,j;uchar value;k=1;for(j=0;j<4;j++){for(i=0;i<8;i++){ value=value>>1; if(irdata[k]>6){value=value | 0x80;}k++;if(k>33)k=1;}ircode[j]=value;}irprosok=1;}void main(){ timer0init(); int0init(); while(1) { if(irreceok) { irpros(); irreceok=0;} display();}void display()switch(ircode[2]){case 0x05:led1=1; led2=1; led3=1; break;case 0x02:led1=0;led2=1; led3=1; break;case 0x03:led2=0; led1=1; led3=1; break;case 0x04:led3=0;led1=1;led2=1; break;//case 0x01: 备用}void timer0 () interrupt 1 { irtime++;}void int0 () interrupt 0 {if(startflag){if(irtime>32) // 检测引导码{bitnum=0;}irdata[bitnum]=irtime;irtime=0;bitnum++;if(bitnum==33){bitnum=0;irreceok=1;startflag=0;}else{startflag=1; irtime=0;}}。

红外解码程序

红外解码程序

注:主函数由读者自己编写,本程序只用于解码,最终得出的按键码存于变量Key_Temp中。

本人习惯写某个器件的程序的时候,习惯创建.c和.h文件,因为这样方便移植,在新建的程序中只需添加.C文件和include .h文件就行了,很方便。

本人用芯片是15W4K32S4。

自己用这块芯片做有开发板,平时写程序都用它。

也可用一般的51单片机,但要注意定时器的时间和外部中断的端口头文件(.h文件)#ifndef __IR_H__#define __IR_H__sfr INT_CLKO = 0x8f;sbit IR = P3^6; //外部中断2的端口在P3.6口extern Byte Long_Press;extern Byte Key_Temp;void Init_IR();#endif以下是(.C文件)#include <15W4K32S4.h> //也可以用reg52.h ,一般的编译器没有<15W4K32S4.h>这个头文件,因为这是我个人添加进编译器里面的#include "IR.h"/******************************************************************* 时间计算:时间由定时器计的定时值来决定,本程序设定工作频率是24MHz,但定时器是12T模式。

故一个定时脉冲时间为0.5us。

实际定时所得时间应为((TH0<<8)|TL0)*0.5 ,单位us。

本程序由:河池学院-物电学院-XXX编写,*******************************************************************/bit IR_Error = 0; //超时错误标志,解码过程中,每个高电平或低电平的时间都不会//超时,也就是定时器不会被记满,如若定时器记满,向CPU申请了中断,那便可认//为是解码失败也就无需再等待高电平结束或低电平结束Byte Long_Press; // 长按计数,若用到长按功能Byte Key_Temp;Word IR_table[4];void Init_IR() //初始化函数,初始化定时器和外部中断{INT_CLKO |= 0x10; //使能外部中断2(不固定,用哪个外部中断都行:下降沿触发)AUXR &= 0x7F; //定时器时钟12T模式,此句可以不写,//因为单片机的定时器上电默认是12T,写是为了方便日后了解TMOD = 0x01; //设置定时器0为不可重装模式,从零开始定时TR0 = 0; //定时器不定时,也可不写,上电默认不启动ET0 = 1; //允许定时器中断,解码超时时进入定时器中断,以方便结束解码EA = 1; //打开总中断}void IR_Rec() interrupt 10{Byte IR_cnt;Byte IR_cnt1;Word L_Time; //定义低电平时间Word H_Time; //定义高电平时间INT_CLKO &= 0xEF; //关闭外部中断2TH0 = 0; //清零定时器的值TL0 = 0;TR0 = 1; //开始定时while(!IR&&!IR_Error); //等待低电平结束if(IR_Error)//若计时超过正常红外时间{IR_Error = 0;TR0 = 0; //关闭定时器TH0 = 0;TL0 = 0;INT_CLKO |= 0x10; //使能外部中断2return; //返回:即结束整个中断服务,退出当前中断服务}TR0 = 0; //关闭定时器L_Time = (TH0<<8)|TL0; //获取定时器的值L_Time = L_Time*0.5; //计算出时间TH0 = 0;TL0 = 0;TR0 = 1;while(IR&&!IR_Error); //等待高电平结束if(IR_Error)//若计时超过正常红外时间{IR_Error = 0;TR0 = 0; //关闭定时器TH0 = 0;TL0 = 0;INT_CLKO |= 0x10; //使能外部中断2return;}TR0 = 0;H_Time = (TH0<<8)|TL0;H_Time = H_Time*0.5;if((L_Time>8000)&&(L_Time<10000)&&(H_Time>4000)&&(H_Time<5000))//判断是否为起始码{//若为起始码,则进行解码//一共接收到四个字节,第一个字节为用户码,第二个字节为用户码反码//第三个字节为按键码,第四个字节为按键码的反码//红外遥控是先发低电平,所以接收时候数据是右移,左移或右移,都是自动补零,//故只用判断高电平Long_Press = 0;//长按计数清零for(IR_cnt=0;IR_cnt<4;IR_cnt++){for(IR_cnt1=0;IR_cnt1<8;IR_cnt1++){Key_Temp >>= 1; //先右移一位TH0 = 0;TL0 = 0;TR0 = 1; //启动定时器while(!IR&&!IR_Error); //等待低电平结束if(IR_Error)//若计时超过正常红外时间{IR_Error = 0;TR0 = 0; //关闭定时器TH0 = 0;TL0 = 0;INT_CLKO |= 0x10; //使能外部中断2return;}TR0 = 0; //关闭定时器L_Time = (TH0<<8)|TL0; //获取低电平时间L_Time = L_Time*0.5; //计算时间(us)TH0 = 0; //定时器清零TL0 = 0;TR0 = 1; //启动定时器while(IR&&!IR_Error); //等待高电平结束if(IR_Error)//若计时超过正常红外时间{IR_Error = 0;TR0 = 0; //关闭定时器TH0 = 0;TL0 = 0;INT_CLKO |= 0x10; //使能外部中断2return;}TR0 = 0;H_Time = (TH0<<8)|TL0;H_Time = H_Time*0.5;if((L_Time<220)||(L_Time>700)) //若低电平时间异常{INT_CLKO |= 0x10; //使能外部中断2return; //停止解码}if((H_Time>1400)&&(H_Time<1800)) //若高电平时间在“1”的范围{Key_Temp |= 0x80;}else if((H_Time<200)&&(H_Time>2000)) //若高电平时间异常{INT_CLKO |= 0x10; //使能外部中断2return; //停止解码}}IR_table[IR_cnt] = Key_Temp;}if(((IR_table[0]+IR_table[1])==0xFF)&&((IR_table[2]+IR_table[3])==0xFF))//验证接收到的数据是否正确,原码加反码等于全1,也就是FF{Key_Temp = IR_table[2]; //将存储的按键值赋给Key_Temp,}else Key_Temp = 0; //若验证的数据有误,则赋0}elseif((L_Time>8000)&&(L_Time<10000)&&(H_Time>1950)&&(H_Time<2350)) //长按{Long_Press++; //长按计数}INT_CLKO |= 0x10; //处理完毕,打开外部中断}void Time0() interrupt 1{IR_Error = 1;}。

一文教会你红外线遥控器软件解码程序

一文教会你红外线遥控器软件解码程序

一文教会你红外线遥控器软件解码程序
红外线一开始发送一段13.5ms的引导码,引导码由9ms的高电平和4.5ms的低电平组成,跟着引导码是系统码,系统反码,按键码,按键反码,如果按着键不放,则遥控器则发送一段重复码,重复码由9ms的高电平,2.25ms的低电平,跟着是一个短脉冲。

#includeat89x52.h
#defineNULL0x00//数据无效
#defineRESET0X01//程序复位
#defineREQUEST0X02//请求信号
#defineACK0x03//应答信号,在接收数据后发送ACK信号表示数据接收正确,
也位请求信号的应答信号
#defineNACK0x04//应答信号,表示接收数据错误
#defineBUSY0x05//忙信号,表示正在忙
#defineFREE0x06//空闲信号,表示处于空闲状态
#defineREAD_IR0x0b//读取红外
#defineSTORE_IR0x0c//保存数据
#defineREAD_KEY0x0d//读取键值
#defineRECEIVE0Xf400//接收缓冲开始地址
#defineSEND0xfa00//发送缓冲开始地址
#defineIR0x50//红外接收缓冲开始地址
#defineHEAD0xaa//数据帧头
#defineTAIL0x55//数据帧尾
#defineSDAP1_7
#defineSCLP1_6
unsigned char xdata *buf1;//接受数据缓冲。

红外解码加注释LCD显示解码

红外解码加注释LCD显示解码

红外解码加注释LCD显⽰解码/****************************************************************程序名称: 将遥控接收头接收到的按键编码通过数码管显⽰出来说明:能解码的遥控编码必须是NEC 的6221/6121/6222编码⽅式同时也可以解9012 9018编码⽅式注明: 单⽚机使⽤12M晶体*****************************************************************/#include#include#include#define uint unsigned int#define uchar unsigned char#define _Nop() _nop_()#define TURE 1#define FALSE 0/*端⼝定义*/sbit lcd_rs_port = P3^5; /*定义LCD控制端⼝*/sbit lcd_rw_port = P3^6;sbit lcd_en_port = P3^4;#define lcd_data_port P0///////////////////////////////////sbit WELA=P2^7; //数码管的位选信号void delay1 (void)//关闭数码管延时程序{int k;for (k=0; k<1000; k++);}////////////////////////////////////uchar code line0[16]={" user: "};uchar code line1[16]={" data: "};uchar code lcd_mun_to_char[16]={"0123456789ABCDEF"}; unsigned char irtime;//红外⽤全局变量bit irpro_ok,irok;unsigned char IRcord[4];unsigned char irdata[34];void ShowString (unsigned char line,char *ptr);//////////////////////////////////////////////void Delay(unsigned char mS);void Ir_work(void);void Ircordpro(void);/**************************************************************///红外部分void tim0_isr (void) interrupt 1 using 1//定时器0中断服务函数{irtime++;}void ex0_isr (void) interrupt 0 using 0//外部中断0服务函数{static unsigned char i; //接收红外信号处理static bit startflag; //是否开始处理标志位if(startflag){if(irtime<51&&irtime>45)//引导码 11.0592M晶振:T0按⽅式2,溢出⼀次277.8us,277.8us*39 = 10.8ms i=0; //277.8us*51 = 14.2ms ,277.8*43=11.9ms只要11.9ms~14.2ms时间内就可以确认开始接收红外码if(irtime<43&&irtime>=39){i=1;irdata[33]=irtime; //长按键时,的时间识别在10.8~11.9ms时间内则为发连续码}irdata[i]=irtime;//存储每个电平的持续时间,⽤于以后判断是0还是1irtime=0;i++;if(i==33){irok=1;i=1;}}else{irtime=0;startflag=1;}}void TIM0init(void)//定时器0初始化{TMOD=0x02;//定时器0⼯作⽅式2,TH0是重装值,TL0是初值TH0=0x00;//reload valueTL0=0x00;//initial valueET0=1;//开中断TR0=1;}void EX0init(void){IT0 = 1; // 外部中断0为边沿触发⽅式EX0 = 1; // 允许外部中断0中断EA = 1;}void Ircordpro(void)//红外码值处理函数{unsigned char i, j, k=1;unsigned char cord,value;for(i=0;i<4;i++){//处理4个字节for(j=1;j<=8;j++){ //处理1个字节8位cord=irdata[k];value=value>>1;if(cord>=7) value=value|0x80; //⼤于某值为1k++;}IRcord[i]=value;value=0;}irpro_ok=1;//处理完毕标志位置1}////////////////////////////////////////////*LCD1602 ⼦程序部分**************************************************************** lcd_system_reset() LCD1602 初始化 ** lcd_delay(uchar ms) LCD1602 延时 ** lcd_busy_wait() LCD1602 忙等待 ** lcd_command_write(uchar command) LCD1602 命令字写⼊ ** lcd_char_write(uchar x_pos,y_pos,lcd_dat) LCD1602 字符写⼊ * ****************************************************************/void lcd_delay(uchar ms) /*LCD1602 延时*/{uchar j;while(ms--){for(j=0;j<250;j++){;}}}//////////////////////////////////////////////void lcd_busy_wait() /*LCD1602 忙等待*/{lcd_rs_port = 0;lcd_rw_port = 1;lcd_en_port = 1;lcd_data_port = 0xff;_Nop();_Nop();_Nop();_Nop();while (lcd_data_port&0x80);lcd_en_port = 0;}///////////////////////////////////////////////void lcd_command_write(uchar command) /*LCD1602 命令字写⼊*/ {lcd_busy_wait();lcd_rs_port = 0;lcd_rw_port = 0;lcd_en_port = 0;lcd_data_port = command;_Nop();_Nop();_Nop();_Nop();_Nop();_Nop();lcd_en_port = 1;_Nop();_Nop();_Nop();_Nop();_Nop();_Nop();lcd_en_port = 0;}/////////////////////////////////////////void lcd_system_reset() /*LCD1602 初始化*/{lcd_delay(20);lcd_command_write(0x38);lcd_delay(100);lcd_command_write(0x38);lcd_delay(50);lcd_command_write(0x38);lcd_delay(10);lcd_command_write(0x08);lcd_command_write(0x01);lcd_command_write(0x06);lcd_command_write(0x0c);}//////////////////////////////////////////////////void lcd_char_write(uchar x_pos,y_pos,lcd_dat) /*LCD1602 字符写⼊*/ {x_pos &= 0x0f; /* X位置范围 0~15 */y_pos &= 0x01; /* Y位置范围 0~ 1 */if(y_pos==1) x_pos += 0x40;x_pos += 0x80;lcd_command_write(x_pos);lcd_busy_wait();lcd_rs_port = 1;lcd_rw_port = 0;lcd_en_port = 0;lcd_data_port = lcd_dat;_Nop();_Nop();_Nop();_Nop();_Nop();_Nop();lcd_en_port = 1;_Nop();_Nop();_Nop();_Nop();_Nop();_Nop();lcd_en_port = 0;}/**LCD1602⼦程序部分完******************************************************//* ~~~~~~~~~~~~~~~~~~~~~* ** ** 主函数 ** ** **~~~~~~~~~~~~~~~~~~~~~~*/void main(void){uchari;lcd_system_reset(); /* 初始化LCD1602 */lcd_data_port = 0xff;/*--------------------------------------------------------------*/P0=0XFF; /*数码管的关闭*/delay1(); /*数码管的关闭*/WELA=1; /*数码管的关闭,防⽌P0数据⼝⼲扰*/delay1(); /*数码管的关闭*/WELA=0; /*数码管的关闭*//*--------------------------------------------------------------*/// for(i=0;i<16;i++) lcd_char_write(i,0,line0[i]);// for(i=0;i<16;i++) lcd_char_write(i,1,line1[i]);EX0init(); // Enable Global Interrupt FlagTIM0init();while(1){//主循环if(irok){Ircordpro();irok=0;}// if(irpro_ok){ /*遥控成功接收*/lcd_char_write(2,0,lcd_mun_to_char[irdata[0]/10]);lcd_char_write(3,0,lcd_mun_to_char[irdata[0]%10]);for(i=5;i<13;i++)lcd_char_write(i,0,lcd_mun_to_char[irdata[i+12]%0x10]); // lcd_char_write(6,0,lcd_mun_to_char[irdata[2]%0x10]); lcd_char_write(14,0,lcd_mun_to_char[irdata[33]/10]); lcd_char_write(15,0,lcd_mun_to_char[irdata[33]%10]); lcd_char_write(2,1,lcd_mun_to_char[IRcord[0]/0x10]); lcd_char_write(3,1,lcd_mun_to_char[IRcord[0]%0x10]); lcd_char_write(5,1,lcd_mun_to_char[IRcord[1]/0x10]); lcd_char_write(6,1,lcd_mun_to_char[IRcord[1]%0x10]); lcd_char_write(8,1,lcd_mun_to_char[IRcord[2]/0x10]); lcd_char_write(9,1,lcd_mun_to_char[IRcord[2]%0x10]); lcd_char_write(11,1,lcd_mun_to_char[IRcord[3]/0x10]); lcd_char_write(12,1,lcd_mun_to_char[IRcord[3]%0x10]); }}}。

红外解码程序详解

红外解码程序详解

//此程序为网上下载后修改,要弄懂的话,可以去看看HT6221的时序图。

当然也欢迎在这里留言。

///C51的红外解码程序,可以根据需要自己修改://11.0592Mhz#include<reg51.h>//根据自己的接线来改sbit IRIN = P3^2; //红外接收器数据线sbit led = P3^7; //指示灯//////////////////////////////////////////////定义数组IRCOM,分别装解码后得到的数据//IRCOM[0] 低8位地址码//IRCOM[1] 高8位地址码//IRCOM[2] 8位数据码//IRCOM[3] 8位数据码的反码/////////////////////////////////////////////#define uchar unsigned char#define uint unsigned intuchar IRCOM[4]=0;bit flag=0;/********************/void delay014ms(unsigned char x); //x*0.14MSvoid IR_init(void);void delay014ms(unsigned char x) //x*0.14MS STC10F04延时约0.15MS {unsigned char i;while(x--){for (i = 0; i<125; i++) //13{;}}}/////////////////初始化////////////void IR_init(void){EA=1;EX0=1; //允许总中断中断,使能 INT0 外部中断IT0=1; //触发方式为脉冲负边沿触发IRIN=1; //I/O口初始化}////////////解码过程//////////////void IR_CODE(void) interrupt 0 //在外部中断子程序中解码{unsigned char j,k,N=0;EX0 = 0;delay014ms(15);if (IRIN==1){ EX0 =1;return;} //确认IR信号出现while (!IRIN) //等IR变为高电平,跳过9ms的前导低电平信号。

红外解码程序

红外解码程序

红外解码程序本篇介绍红外解码的原理和程序的写法。

下面来看一下,红外线是如何编码的。

下面来具体说一下,解码的原理,每按一下遥控器的一个按键,遥控器就会发出32个“0”“1”代码(当然是通过高低电平的占空比来判断是0还是1的),具体是0,1是如何编码的上面图片中有介绍,和一个引导码,引导码的作用是告诉处理器,接下来将要开始发送代码,我们在编写程序时,当检测到引导码时,就应该准备接受数据了。

32位代码中的前16位是用户识别码,不同的遥控器不相同,防止互相干扰的,后16是8为数据码,和8位数据反码。

接下来开始介绍如何解码程序的编写。

程序中用到了两个中断,一个是定时器中断,一个是外部中断。

定时器中断用来准确计时,判断接受的代码是0还是1,外部中断用来准确确定定电平到来的时刻,然后开始计时。

/*********************************************************函数功能:红外解码,用八位数码管显示红外线的按键码,便于红外控制测试环境:hot 51学习板编译环境:keil4整理人:张家越QQ:435835181整理时间:2011-04-03************************************************************/#include<reg51.h>#define uchar unsigned char#define uint unsigned intuchar code seg_du[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0 x6f,0x77,0x7c,0x39,0x5E,0x79,0x71 };//0-f的段选码unsigned char code seg_we[]={0,1,2,3,4,5,6,7};uchar irtime,startflag,bitnum,irreceok;uchar irdata[33];uchar irprosok;uchar display[8];uchar ircode[8] ;sbit led1=P0^1;sbit led2=P0^2;/******************************************************************** ****函数功能:延时函数,在数码管显示时使用,不需要很精确********************************************************************* ****/void delay_50us(uint t){uchar j;for(;t>0;t--)for(j=19;j>0;j--);}/******************************************************************** ******函数的功能:定时器0的初始化********************************************************************* *****/void timer0init(){TMOD=0x02; //设置定时器工作在方式2TH0=0x00; //TL0=0x00; //设置定时器的初值ET0=1; //开定时器中断TR0=1; // 打开定时器EA=1; //开总中断}/******************************************************************** ****外部中断1的初始化********************************************************************* **/void int1init(){IT1=1; //设置触发方式为上升沿EX1=1; //开外部中断1EA=1; //开总中断}/******************************************************************** **定时器0的功能函数,每中断一次irtime++,用于计时********************************************************************* **/void timer0() interrupt 1{irtime++; //定时器中断一次irtime++,用于计时}/******************************************************************** ***外部中断0的处理函数,每当有低电平数据过来时,中断一次,(使用次中断的前提是,信号线必需接在外部中断0上面,也就是P3^2口),函数功能是,把信号从高低电平变成时间的代码放入irdata【】中********************************************************************* ***/void int1() interrupt 2{if(startflag){if(irtime>32) //一组代码检测完毕{bitnum=0;}irdata[bitnum]=irtime; //把检测到的时间送到数组irdata【】中去irtime=0;bitnum++;if(bitnum==33) //如果检测到bitnum=33,说明32位用户码已经检测完毕{bitnum=0; //将bitnum清零以便重新计数irreceok=1; //接收完毕标志位置一}}else //(此函数先进入else语句,跳过引导码的检测){startflag=1; //将开始标志位置一irtime=0; //设置时间初值为零irreceok=1; //接收完毕标志位置一}}/******************************************************************** *****函数功能:把irdata【】中的时间代码转换成二进制代码存放在ircode【】中********************************************************************* *****/void irpros(){uchar k=1,value,j,i;for(j=0;j<4;j++){for(i=0;i<8;i++){value=value>>1; //右移7次(第一次是00,相当于没有移位)if(irdata[k]>6) //循环8次{value=value|0x80;}k++;}ircode[j]=value;}irprosok=1;}/******************************************************************** ********函数的功能是:将ircode【】中的二进制代码转换成为16进制代码便于在数码管上显示******************************************************************* ********/void irwork(){display[0]=ircode[0]/16;display[1]=ircode[0]%16;display[2]=ircode[1]/16;display[3]=ircode[1]%16;display[4]=ircode[2]/16;display[5]=ircode[2]%16;display[6]=ircode[3]/16;display[7]=ircode[3]%16;}/******************************************************************** ****函数功能:用数码管显示解码结果********************************************************************* ***/void display1(){uchar i;for(i=0;i<8;i++){P2=seg_we[i];P0=seg_du[display[i]];delay_50us(40);}}void main(){timer0init(); //定时器初始化int1init(); //外部中断初始化while(1){if(irreceok) //判断数据接收完毕(数组中存储的是高低电平的时间){irpros(); //执行处理函数,将高低电平时间转化成16进制的0,1代码,存放在数组中irreceok=0; //标志清零}if(irprosok) //处理函数执行完毕,{irwork(); //将存储的16进制代码分离,便于数码管显示irprosok=0; //标志清零}display1();}}//在最后我再分析一下程序的编写思路,便于大家理解,一旦有按键按下,接受管接收到引导码,进入外部中断,并将高低电平的时间放入irdata【】数组中,接受完毕标志位置一,判断接受标志位,为1,进行处理函数,将高低电平转换成16进制数,处理标志位置一,判断处理标志位,为1,执行分离函数,将16进制数分离,便于数码管显示,分离完毕后显示。

51单片机红外遥控解码,很详细(汇编语言,C语言等)

51单片机红外遥控解码,很详细(汇编语言,C语言等)
//k[i]=TH0;
//i++;
if(TH0<3)
b=1;
else b=0;
TH0=0;
TL0=0;
}
uchar hw_key()
{
uchar j,m;
//i=0;
hw_start(); //等待低电平到来
hw_pulse();
for(j=0;j<24;j++) //测试用户码脉冲宽度
{
hw_pulse();
}
for(j=0;j<8;j++) //测试键码脉冲宽度
{
hw_pulse();
if(b==1)
m=(m<<1)|1;
else
m<<=1;
}
return m; //键码
}
while(in==0); //高电平到了,
TR0=0; //关闭定+;
TH0=0;
TL0=0;
TR0=1; //高电平到了,启动定时器1,测试高电平宽度
while(in==1); //低电平到了,
TR0=0; //关闭定时器1,高电平宽度测试完
请注意甄别内容中的联系方式诱导购买等信息谨防诈骗
51单片机红外遥控解码,很详细(汇编语言,C语言等)
单片机源程序如下:
#include
#define hw_hs0038_ENTITY
#include "hw_hs0038.h"
sbit in=P3^2;
//uchar i=0;
//uchar k[2];
bit bdata b=0;
/*
void timer0(void) interrupt 1 using 1

51单片机红外解码、超声波测距程序(详细解释程序)

51单片机红外解码、超声波测距程序(详细解释程序)

// c51红外解码、超声波测距程序#include <reg52.h>#define uchar unsigned char#define uint unsigned int#define count 4uchar data IRcode[4]; //定义一个4字节的数组用来存储代码uchar table[4];uchar enled[4]={0x1f,0x2f,0x4f,0x8f};uchar CodeTemp,temp,tt; //编码字节缓存变量uchari,j,k,temp,timeH,timeL,succeed_flag,flag,h,h1,h2,a,key,key1,key2; //延时用的循环变量uint distance,distance1,time; //距离,timesbit IRsignal=P3^2; //HS0038接收头OUT端直接连P3.2(INT0)sbit come=P3^3;sbit d=P1^1;//发送码sbit BZ=P1^0;sbit s=P3^7;//38ksbit ss=P3^6;//38kuchar m;// 开关控制//sbit n=P2;//电机反转code unsigned charseg7code[10]={0xa0,0xbb,0x62,0x2a,0x39,0x2c,0x24,0xba,0x20,0x28}; //显示段码/**************************** 定时器0中断************************/void timer0() interrupt 1{TH0=(65536-count)/256;TL0=(65536-count)%256;s=~s;//产生38K信号ss=~ss;//tt++;//发送超声波个数}/**************************** 延时0.9ms子程序************************/void Delay0_9ms(void){uchar j,k;for(j=18;j>0;j--)for(k=20;k>0;k--);}/***************************延时1ms子程序**********************/void Delay1ms(void){uchar i,j;for(i=2;i>0;i--)for(j=230;j>0;j--);}/***************************延时4.5ms子程序**********************/ void Delay4_5ms(void){uchar i,j;for(i=10;i>0;i--)for(j=225;j>0;j--);}/**************************** 解码延时子程序************************/ void Delay(void){uchar i,j,k;for(i=100;i>0;i--)for(j=100;j>0;j--)for(k=3;k>0;k--);}/**************************** 显示延时子程序************************/ void ledDelay(unsigned int tc) //延时程序{unsigned int i,j;for(i=0;i<10;i++)for(j=0;j<tc;j++);}/************************************************ ****************///定时器1中断,用做超声波测距无回波void timer1() interrupt 3{TR1=0;ET1=0;EX1=0;TH1=0;TL1=0;}/***********************显示程序*********************/ void Led(int date) //显示函数{ int i;table[0]=date/1000;table[1]=date/100%10;table[2]=date/10%10;table[3]=date%10;date=0;for(i=0;i<120;i++){P2=enled[i%4]&m;//P2口高四位控制数码管,低位陪分控制继电器P0=seg7code[table[i%4]]; //取出千位数,查表,输出。

单片机的红外线解码程序

单片机的红外线解码程序
{
switch(inf_shuju)
{
case inf_code_0: inf_array[1]=30;
break;
case inf_code_1: inf_array[1]=1;
break;
case inf_code_2: infe inf_code_3: inf_array[1]=3;
TR1 = 1; //定时器1开始计数,由于晶振是24M
inf_shunxu++;
}
//#############################################################################
//函数名称:void inf_gongcuowu()
//功能:红外线错误子程序
break;
case inf_code_12: inf_array[1]=12;
break;
case inf_code_13: inf_array[1]=13;
break;
case inf_code_14: inf_array[1]=14;
break;
case inf_code_15: inf_array[1]=15;
//入口参数:无
//出口参数:无
//#############################################################################
void inf_gongcuowu(void)
{
inf_mode_cuowu = 1; //红外线接收出现错误
void T_1(void) interrupt 3 //参与红外线接收
{
TR1 = 0;

红外遥控器解码程序

红外遥控器解码程序

//===================================================================== //// 红外遥控器解码程序演示//// 本程序主要将现在比较常用TX1300遥控器进行解码,将解码后的数据通过P2端////口的数码管显示出来,为了更好的看到运行过程,特加了三个指示灯用来指示当////前运行状态.P10主要用来闪亮,表示程序正在运行,P11则用来表示接收到数据, ////P12表示触发内部的定时器操作.P13的闪亮表示正确接收完一个数据. //// 程序运行效果: 打开本机电源开关,可以看到P10不停的闪动,按下遥控器的数////字键,数码管则显示相应的数字键(1-9).可以看到P11,P12在显示后呈亮状态.则////可以接收下一个数据,在上面过程中可以看到P13闪亮了一下.表明上次正确接收////到数据. ////---------------------------------------------------------------------//// 开发日期: 2009/01/30 研发单位:上海腾芯实业有限公司//#include <reg52.h> //包含51单片机相关的头文件#define uint unsigned int //重定义无符号整数类型#define uchar unsigned char //重定义无符号字符类型uchar code LedShowData[]={0x03,0x9F,0x25,0x0D,0x99, //定义数码管显示数据0x49,0x41,0x1F,0x01,0x19};//0,1,2,3,4,5,6,7,8,9uchar code RecvData[]={0x07,0x0A,0x1B,0x1F,0x0C,0x0D,0x0E,0x00,0x0F,0x19};uchar IRCOM[7];static unsigned int LedFlash; //定义闪动频率计数变量unsigned char RunFlag=0; //定义运行标志位bit EnableLight=0; //定义指示灯使能位/***********完成基本数据变量定义**************/sbit S1State=P1^0; //定义S1状态标志位sbit S2State=P1^1; //定义S2状态标志位sbit B1State=P1^2; //定义B1状态标志位sbit IRState=P1^3; //定义IR状态标志位sbit RunStopState=P1^4; //定义运行停止标志位sbit FontIRState=P1^5; //定义FontIR状态标志位sbit LeftIRState=P1^6; //定义LeftIR状态标志位sbit RightIRState=P1^7; //定义RightIRState状态标志位/*************完成状态指示灯定义*************/sbit S1=P3^2; //定义S1按键端口sbit S2=P3^4; //定义S2按键端口/*************完成按键端口的定义*************/sbit LeftLed=P2^0; //定义前方左侧指示灯端口sbit RightLed=P0^7; //定义前方右侧指示灯端口/*************完成前方指示灯端口定义*********/sbit LeftIR=P3^5; //定义前方左侧红外探头sbit RightIR=P3^6; //定义前主右侧红外探头sbit FontIR=P3^7; //定义正前方红外探头/*************完成红外探头端口定义***********/sbit M1A=P0^0; //定义电机1正向端口sbit M1B=P0^1; //定义电机1反向端口sbit M2A=P0^2; //定义电机2正向端口sbit M2B=P0^3; //定义电机2反向端口/*************完成电机端口定义***************/sbit B1=P0^4; //定义话筒传感器端口sbit RL1=P0^5; //定义光敏电阻端口sbit SB1=P0^6; //定义蜂鸣端口/*********完成话筒,光敏电阻,蜂鸣器.端口定义**/sbit IRIN=P3^3; //定义红外接收端口/*********完成红外接收端口的定义*************/#define ShowPort P2 //定义数码管显示端口extern void ControlCar(uchar CarType); //声明小车控制子程序void delayms(unsigned char x) //0.14mS延时程序{unsigned char i; //定义临时变量while(x--) //延时时间循环{for (i = 0; i<13; i++) {} //14mS延时}}void Delay() //定义延时子程序{ uint DelayTime=30000; //定义延时时间变量while(DelayTime--); //开始进行延时循环return; //子程序返回}void IR_IN() interrupt 2 using 0 //定义INT2外部中断函数{unsigned char j,k,N=0; //定义临时接收变量EX1 = 0; //关闭外部中断,防止再有信号到达delayms(15); //延时时间,进行红外消抖if (IRIN==1) //判断红外信号是否消失{EX1 =1; //外部中断开return; //返回}while (!IRIN) //等IR变为高电平,跳过9ms 的前导低电平信号。

红外遥控解码程序

红外遥控解码程序

1./*************************************************************************2.** 红外遥控器解码程序(采用中断)----基于SM0038接收芯片3.**说明:采用P2.0口中断,可通过修改IR_IN和P2来切换中断口的选择.4.**使用方法: 当IR_FLAG==1时,表示有键按下,全局变量IR_KeyValue是键号.5.** IR_KeyValueN--按键非码;IR_KeyValueSB--遥控器识别码6.** IR_UK--用户自定义的键号7.** 使用此模块时应先执行 IR_Init()8.**使用示例: if(IR_FLAG==1)9.** {10.** IR_FLAG=0;//每次使用时须将标志位清零.11.** Display_Int(IR_KeyValue,0x90);12.** }13.*************************************************************************/14.15.16.#include "ir_key.h"17.#include "delay.h"18./**********************以下是本程序中使用到的全局变量********************/19.unsigned char IR_BitCnt=0;20.unsigned char IR_KeyValue=10; //按键码(始值不能为按键号中包含的值)21.unsigned char IR_UK=0; //用户定义的键号22.unsigned char IR_KeyValueN=0; //按键非码;按键码+按键非码=0xff23.long int IR_KeyValueSB=0; //遥控器识别码.24.unsigned char IR_FLAG = 0; //有键按下时此标志为125.26./*****************************************************************************27.**此结构休是为键号转换用,IR_KV为遥控器本身的键号,IR_UK为用户自定义的按键号28.*****************************************************************************/29. struct IR_KEY30.{31. unsigned char IR_KV;//遥控器自身键码32. unsigned char IR_UV;//user's value33.};34./*****************************************************************************35.**通过修改结构体数组中的值来设定遥控器的键号.36.*******************************************************************************/37.struct IR_KEY IR_UserKEY[IR_NUM]=38.{39. {68,1},{71,2},{14,3},{72,4},{73,5},{81,6},{10,7},{80,8},{74,9},{83,10},40. {18,11},{84,12},{78,13},{75,14},{3,15},{21,16},{86,17},{67,18},{2,19},{76,20},41. {82,21},{79,22},{70,23},{77,24},{69,25},{6,26},{66,27},{65,28},{64,29},{22,30},42. {85,31},{23,32},{9,33},{13,34},{87,35},{15,36},{8,37},{25,38},{24,39},{11,40},43. {0,41},{4,42},{16,43},{19,44},{5,45},{1,46},{17,47},{95,48},{94,49},{30,50},{26,51}44.};45.46.47./*************************************************************************48.**函数名称: IR_DELAY49.**功能描述: 用于延时.50.**调用模块: delay.h51.**全局变量: 无52.****************************************************************************/53.void IR_DELAY(unsigned int delayTime)54.{55. DELAY(delayTime);//延时8MS56.}57.58.59./*************************************************************************60.**函数名称: IR_Init61.**功能描述: 端口初始化设置,在main函数里面应先执行此函数62.**输入变量:无63.**返回值:无64.**调用模块:无65.**全局变量: IR_IN66.****************************************************************************/67.void IR_Init(void)68.{69. P2DIR &=~IR_IN; //端口设置为输入方向70. P2IE |= IR_IN; //使能中断71. P2IES |= IR_IN; //下降沿中断72. P2IFG &=~IR_IN; //为避免程序运行后直接进中断,此处需先将中断标志位清零73. _EINT();74.}75.76.77./*************************************************************************78.**函数名称: IR_getkey79.**功能描述: 读取遥控器键值,包括识别码,非码80.**输入变量: 无81.**返回值: 无82.**调用模块: IR_DELAY();83.**全局变量: IR_Delay_8MS,IR_Delay8MS,IR_IN84.****************************************************************************/85.void IR_getkey(void)86.{87. P2IFG &=~IR_IN;88. P2IE &=~IR_IN;89. /**********以下是判断中断是由按键引起的***************/90. IR_DELAY(IR_Delay_8MS); //延时0.8MS91. if(P2IN & IR_IN) goto IR_NXT;92. IR_DELAY(IR_Delay8MS); //延时8MS93. if(!(P2IN & BIT0)) goto IR_NXT;94. while(!(P2IN & IR_IN));//等待变高95. IR_DELAY(8900); //延时5MS左右96. if(P2IN & IR_IN) goto IR_NXT;97. IR_FLAG = 0;98. /********以下是读取16位识别码*******************/99. IR_KeyValueSB=0;100. for(IR_BitCnt=0;IR_BitCnt<16;IR_BitCnt++)101. {102. while(!(P2IN & IR_IN));//WAIT HIGH103. IR_KeyValueSB >>=1;104. IR_DELAY(IR_Delay_8MS);105. if(P2IN & IR_IN)106. IR_KeyValueSB |=0x80;107. else108. IR_KeyValueSB &=0x7f;109. while(P2IN & IR_IN);//WAIT LOW110. }111. /***********以下是读取8位的键码*******************/ 112. IR_KeyValue=0;113. for(IR_BitCnt=0;IR_BitCnt<8;IR_BitCnt++)114. {115. while(!(P2IN & IR_IN));//WAIT HIGH116. IR_KeyValue >>=1;117. IR_DELAY(IR_Delay_8MS);118. if(P2IN & IR_IN)119. IR_KeyValue |=0x80;120. else121. IR_KeyValue &=0x7f;122. while(P2IN & IR_IN);//WAIT LOW123.124. }125. /************以下是读取8位的非码****************/ 126. IR_KeyValueN=0;127. for(IR_BitCnt=0;IR_BitCnt<8;IR_BitCnt++)128. {129. while(!(P2IN & IR_IN));//WAIT HIGH130. IR_KeyValueN >>=1;131. IR_DELAY(IR_Delay_8MS);132. if(P2IN & IR_IN)133. IR_KeyValueN |=0x80;134. else135. IR_KeyValueN &=0x7f;136. while(P2IN & IR_IN);//WAIT LOW137.138. }139. for(unsigned char i=0;i<20;i++)140. IR_DELAY(IR_Delay8MS);141.IR_NXT:P2IFG &=~IR_IN;142.P2IE |=IR_IN;143.144.IR_FLAG=1;145.}146.147.148./********************************************************* ****************149.**函数名称: IR_getUK150.**功能描述: 根据得到的IR_KeyValue从IR_UserKEY表中查出对应的用户自定义的键值151.**输入变量: 无152.**返回值: 无153.**调用模块: 无154.**全局变量: IR_BitCnt,IR_NUM,IR_UserKEY,IR_KeyValue,IR_UK155.********************************************************** ******************/156.void IR_getUK(void)157.{158.159. for(IR_BitCnt=0;IR_BitCnt<IR_NUM;IR_BITCNT++) pre < **** *************************************************************** ********** **以下是SM0038输入信号引脚的中断函数. *********************************************************** ***************** } IR_UK="IR_UserKEY[IR_BitCnt].IR_UV;" if(IR_ BitCnt="=IR_NUM)" return; { if(IR_KeyValue="=IR_UserKEY[IR_BitC nt].IR_KV)">160.<SCRIPT src="/inc/gg_read2.js"></SCRIPT>。

单片机红外接受解码程序成功版

单片机红外接受解码程序成功版

单片机红外接受解码程序成功版1、效果图2、发射码格式3、38KH载波发射(完整的发射图)4、 0 与 1的区别5、载波6、小结7、代码发射码格式38KH载波发射(完整的发射)0与1的区别载波小结1、发射端发射出来的是高电平。

但是接收到的是低电平。

(接收到的数据与发射的相反)2、我这里用的外部下降沿触发的中断3、使用12M的晶振完4、整源码下载地址:代码#include <reg51.h>sbit IR=P3^2; //红外接口标志sbit dm = P2^2; //段码sbit wm = P2^3; //位码unsigned char hc[8]; //数码管显示缓存unsigned char DM[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0 x7c,0x39,0x5e,0x79,0x71};// 显示段码值0~Funsigned char WM[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //位码。

显示的位置unsigned char sj[33]; //接收脉冲时间数组char w=0; //数码管显示缓存指针(0~7)unsigned char i; //脉冲个数记录unsigned char mcsj; //脉冲时间(大于0.56ms小于1.125ms为0,大于1.125ms小于2.25ms)bit MC=0; //接收红外脉冲开始标志(0:脉冲已经结束,1:脉冲刚开始)bit JS=0; //脉冲接收结束标志位(1标志接收结束)bit JM=0; //解码完成标志位(1:解码完成)void Delay(unsigned char f);void dsq_0() interrupt 1 using 1 //定时器T0中断服务函数{mcsj++; //256}void wbzd_0() interrupt 0 //外部中断服务函数{if(MC){if(mcsj>32) //判断是不是引导码。

红外解码

红外解码

#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};void delay1(int ms);void delay(unsigned char x);void beep();sbit IRIN=P3^2; //红外接收sbit BEEP=P1^7; //蜂鸣器sbit RELAY=P1^4; //继电器sbit qj=P1^0;sbit ht=P1^1;sbit zz=P1^2;sbit yz=P1^3;sbit tz=P1^6;uchar IRCOM[7];uchar Y0;sbit LCD_RS = P2^6;sbit LCD_RW = P2^5;sbit LCD_EN = P2^7;uchar code cdis1[ ]={" red control cjr"};uchar code cdis2[ ]={" ir-xs: --H "};bit lcd_busy(){bit result;LCD_RS=0;LCD_RW=1;LCD_EN=1;delayNOP();result = (bit)(P0&0x80);LCD_EN = 0;return(result);}//****检查忙碌void lcd_wcmd(uchar cmd){while(lcd_busy());LCD_RS=0;LCD_RW=0;LCD_EN=0;_nop_();_nop_();P0 = cmd;delayNOP();LCD_EN = 1;delayNOP();LCD_EN = 0;}//****写指令到lcdvoid lcd_wdat(uchar dat){while(lcd_busy());LCD_RS=1;LCD_RW=0;LCD_EN=0;P0=dat;delayNOP();LCD_EN=1;delayNOP();LCD_EN=0;}//****写数据void lcd_init(){delay1(15);lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据delay1(5);lcd_wcmd(0x38);delay1(5);lcd_wcmd(0x38);delay1(5);lcd_wcmd(0x0c); //显示开,关光标delay1(5);lcd_wcmd(0x06); //移动光标delay1(5);lcd_wcmd(0x01); //清除LCD的显示内容delay1(5);}//****初始化lcdvoid lcd_pos(uchar pos){lcd_wcmd(pos | 0x80); //数据指针=80+地址变量}main(){ uchar m;qj=0;ht=0;zz=0;yz=0;IRIN=1; //I/O口初始化BEEP=1;RELAY=1;delay1(10); //延时lcd_init(); //初始化LCDlcd_pos(0); //设置显示位置为第一行的第1个字符m = 0;while(cdis1[m] != '\0'){ //显示字符lcd_wdat(cdis1[m]);m++;}lcd_pos(0x40); //设置显示位置为第二行第1个字符m = 0;while(cdis2[m] != '\0'){lcd_wdat(cdis2[m]); //显示字符m++;}IE=0X81;TCON=0X01;while(1);}//end mainvoid IR_IN() interrupt 0 using 0{uchar j,k,N=0;EX0=0;delay(15);if(IRIN==1){EX0=1;return;} //确认IR信号出现while(!IRIN){delay(1);}for(j=0;j<4;j++){for(k=0;k<8;k++){while(IRIN){delay(1);}while(!IRIN){delay(1);}while(IRIN){delay(1);N++;if(N>=30){EX0=1;return;}}IRCOM[j]=IRCOM[j]>>1;if(N>=8){IRCOM[j]=IRCOM[j]|0x80;}N=0;}}if(IRCOM[2]!=~IRCOM[3]){EX0=1;return;}IRCOM[5]=IRCOM[2]&0X0F;IRCOM[6]=IRCOM[2]>>4;if(IRCOM[5]>9){IRCOM[5]=IRCOM[5]+0X37;}elseIRCOM[5]=IRCOM[5]+0X30;if(IRCOM[6]>9){IRCOM[6]=IRCOM[6]+0x37;}elseIRCOM[6]=IRCOM[6]+0x30;lcd_pos(0x48);lcd_wdat(IRCOM[6]); //第一位数显示lcd_pos(0x49);lcd_wdat(IRCOM[5]); //第二位数显示switch(IRCOM[2]){case 0x18: Y0=0x01; break;case 0x52: Y0=0x02; break;case 0x08: Y0=0x03; break;case 0x5a: Y0=0x04; break;case 0x1c: Y0=0x05; break;case 0x1B: Y0=0x06; break;case 0x11: Y0=0x07; break;case 0x15: Y0=0x08; break;case 0x45: Y0=0x09; break;case 0x13: RELAY=1; break;case 0x14: RELAY=1; break;case 0x51: RELAY=0; break;}if(Y0==0x01){qj=1;ht=0;} //打开继电器else qj=0;if(Y0==0x02){ht=1;qj=0;}else ht=0; //关闭继电器if(Y0==0x03){zz=1;yz=0;}else zz=0;if(Y0==0x04){yz=1;zz=0;}else yz=0;if(Y0==0x05){yz=1;zz=1;qj=1;ht=1;};if(Y0==0x09)RELAY=0;else RELAY=1;beep();EX0 = 1;}void delay1(int ms){uchar y;while(ms--){for(y=0;y<250;y++){_nop_();_nop_();_nop_();_nop_();}}}//**********************void beep(){unsigned int i;for (i=0;i<50;i++){delay(4);BEEP=!BEEP; //BEEP取反}BEEP=1; //关闭蜂鸣器}void delay(unsigned char x) //x*0.14MS{unsigned char i; while(x--){for (i = 0; i<13; i++) {} }}。

红外解码程序

红外解码程序

/*程序说明:51单片机红外遥控解码程序单片机采用外部中断INTI管脚和红外接收头的信号线相连,中断方式为边沿触发方式。

并用定时器0计算中断的间隔时间,来区分前导码、二进制的1,0;8位操作码提取出来在数码管上显示。

解码值在Im[2]中,当IrOK=1时解码有效。

用遥控器对准红外接收头,按下遥控器按键,在数码管的两位上就会显示对应按键的编码*/#include <reg52.h>#define uchar unsigned charsbit dula=P2^6;sbit wela=P2^7;uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};uchar f;#define Imax 14000 //此处为晶振为11.0592时的取值,#define Imin 8000 //如用其它频率的晶振时,#define Inum1 1450 //要改变相应的取值。

#define Inum2 700#define Inum3 3000unsigned char Im[4]={0x00,0x00,0x00,0x00};uchar show[2]={0,0};unsigned long m,Tc;unsigned char IrOK;void delay(uchar i){uchar j,k;for(j=i;j>0;j--)for(k=125;k>0;k--);}void display(){dula=0;P0=table[show[1]];dula=1;dula=0;wela=0;P0=0xfd;wela=1;wela=0;delay(5);P0=table[show[0]];dula=1;dula=0;P0=0xfe;wela=1;wela=0;delay(5);}//外部中断解码程序void intersvr1(void) interrupt 2 using 1{Tc=TH0*256+TL0; //提取中断时间间隔时长TH0=0;TL0=0; //定时中断重新置零if((Tc>Imin)&&(Tc<Imax)){m=0;f=1;return;} //找到启始码if(f==1){if(Tc>Inum1&&Tc<Inum3){Im[m/8]=Im[m/8]>>1|0x80; m++;}if(Tc>Inum2&&Tc<Inum1){Im[m/8]=Im[m/8]>>1; m++; //取码}if(m==32){m=0;f=0;if(Im[2]==~Im[3]){IrOK=1;}else IrOK=0; //取码完成后判断读码是否正确}//准备读下一码}}/*演示主程序*/void main(void){unsigned int a;m=0;f=0;EA=1;IT1=1;EX1=1;TMOD=0x11;TH0=0;TL0=0;TR0=1;//ET0=1;while(1){if(IrOK==1){show[1]=Im[2] & 0x0F; //取键码的低四位show[0]=Im[2] >> 4;IrOK=0;}for(a=100;a>0;a--){display();}}}。

(完整)简单的红外解码程序

(完整)简单的红外解码程序

简单的红外解码程序(不用中断)#ifndef __IR_H__#define __IR_H__#include <reg52.h>#include ”delay。

h"#define uchar unsigned char//8位#define uint unsigned int//16位sbit IR_IN=P3^2;//信号接收IR_JS();//无线接收程序#endif#include "IR.h”uchar data dat_IR[3]; //写缓存//==========红外接收程序=================IR_JS()//{uchar r1,r2,dat,dat1,dat2;if(IR_IN!=0){return 0;}//无信号退出delay_ms(1);if(IR_IN!=0){return 0;}//干扰退出r2=0;while(IR_IN ==0)//等高电平{delay_ms(1);r2++;}if(r2〈5){return 0;}//检测是否有同步头//delay_ms(4);//跳过同步码的高电平do{delay_100us(1);r2++;if(r2〉20){return 0;}}//防卡死while(IR_IN ==1);//开始解码for(r1=0;r1〈8;r1++)//接收8位数(系统码1){r2=0;while(IR_IN ==0);delay_100us(6);dat=dat<〈1;if(IR_IN ==1)dat=dat+1; //读数据位,接收的数据位放入retc中do{delay_100us(1);r2++;if(r2>20){return 0;}}//防卡死while(IR_IN ==1);}for(r1=0;r1〈8;r1++)//接收8位数(系统码2){r2=0;while(IR_IN ==0);delay_100us(6);//dat1=dat1<<1;if(IR_IN ==1)dat1=dat1+1; //读数据位,接收的数据位放入retc中 do{delay_100us(1);r2++;if(r2>20){return 0;}}//防卡死while(IR_IN ==1);}for(r1=0;r1〈8;r1++)//接收8位数(键值){r2=0;while(IR_IN ==0);delay_100us(6);//dat2=dat2<<1;if(IR_IN ==1)dat2=dat2+1; //读数据位,接收的数据位放入retc中 do{delay_100us(1);r2++;if(r2〉20){;return 0;}}//防卡死while(IR_IN ==1);}for(r1=0;r1<8;r1++)//接收8位数(键值反码){r2=0;while(IR_IN ==0);delay_100us(6);//dat=dat<〈1;if(IR_IN ==1)dat=dat+1; //读数据位,接收的数据位放入retc中 do{delay_100us(1);r2++;if(r2〉20){return 0;}}//防卡死while(IR_IN ==1);}//接收完32位数据if(dat2!= ~dat){return 0;}//检测键值和键值反码,出错退出//解码完成,保存数据dat_IR[0]=dat;dat_IR[1]=dat1;dat_IR[2]=dat2;//P2显示数据P2=dat2;delay_ms(1000);//显示一秒P2=0xFF;return 1; //解码成功}。

红外解码程序(用1602显示码值)

红外解码程序(用1602显示码值)

红外解码程序(用1602显示码值)#include #define uchar unsigned char#define uint unsigned intsbit beep=P1;bit startflag; //定义一个扫描开始标志位bit irreceok;//红外接收OK 标志位bit irprosok;//红外接收处理OK 标志位uchar irdata[33];//定义一个存放编码的数组。

引导码1 位,客户码8 位,客户反码8 位,数据码8 位,数据反码8 位,共33 位uchar bitnum;//接收到的第几位数据的标志位uchar irtime;//定义红外扫描时间uchar ircode[4];//为四个码值定义一个数组存放,把四位码分开uchar disp[8];//四组数据,每组拆成高四位和低四位,共八个元素/**************1602 部分******************/sbit lcden=P1 ;sbitlcdrs=P1;sbitlcdrw=P1;/*cha r code Tab[]={0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F};*/char code Tab[]=“0123456789abcdef”;void delay(uint z) //延时子程序{ uint x,y; for(x=z;x>0;x--) for(y=220;y>0;y--);}void write_com(uchar com)//定义一个带参数的写命令子程序{lcdrs=0; //1602的rs 为0 时,接收命令,为1 时接收数据P0=com;//把void write_com(uchar com)中的COM 中的数据给P0 口delay(2);lcden=1;delay(2);lcden=0;delay(2);}void init_1602()//定义一个初始化子程序{lcden=0;lcdrw=0;write_com(0x38);//调用write_com 子程序并把0x38 赋给P0 口,显示模式打开write_com(0x0f);//调用write_com 子程序并把开显示,显示光标,光标闪烁指令码赋给P0 口write_com(0x06);//调用write_com 子程序并把地址指针加1,整屏不移动指令码赋给P0 口//write_com(0x80+0x10);//数据指针初始化,让指针指向可显示的最右端write_com(0x80);//数据指针初始化,让指针指向最左端,显示从第一行开始write_com(0x01);//调用write_com 子程序并把”清零指”令码赋给P0 口} void write_dat(uchar dat)//定义一个带参数的写数据子程序{lcdrs=1; //1602 的rs。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//假设晶振频率为11.0592MHZ,那么它的振荡周期是1/11.0592 us.12分频后晶振频率为11.0592MHZ/12,分频后
//的机器周期是12/11.0592 us.通过以上推理,我们可以得出机器周期=12/n(n指晶振频率,1/n指振荡周期)。
//单片机是一个机器周期产生一个计数脉冲,假设你要定时的时间为M ,那么定时次数为M/机器周期=定时次数
YKReset();
return;
}
YKtype = 2;
}
else if(YKcount == 14) //获取完commond bits, 共6位
{
YKtype = 3;
}
if(YKtype != 3) //将数据左移一位, 以便将一下位数据并于最低位
{
in = ~YKIn;
}
else
{
//加上这句的好处是可以过滤掉多余的脉冲,以免产生误导,这样会导致多定时一个周期,实际延时1位时间
//但是通过实际测试,延时1位,数据也收不完,导致出错,所有加入了第98行的判断,这样实现起来效果很好
TR0 = 0; //接收结束, 停止定时器0
//即在3/4位时间时, 判断该位是1还是0
//实际测试中, 位时间只在1.651ms(+- 1ms), 定时1/4位的时间:413us
//bit 位数:1 值域:0~1
//一般的接收头在接收到信号时是输出低电平的,也就是说接收头输出的波形正好和遥控芯片输出的相反
//一体化解码后, 有载频部分变为低电平, 即低电平实际为1, 高电平实际为0
/* 时间:2010-07-01 */
/* 最后修改时间:2010-07-01 */
/******************************************************************************/
void SP_TIMER0(void) interrupt 1
{
static bit in;
if(YKtype != 3)
ET0 = 0; //定时器0中断关闭
// TestCode(YKDatas[2]);
TR1 = 0;
ET1 = 0;
EX1 = 0;
DelayMs(20);
YKProcessing(YKDatas[2]);
return;
}
//第一次进入中断前, 定时1/4位的时间:445us, 以后则定时一位时间1.778ms
{
YKDatas[YKtype] <<= 1; //每读一次放入变量中的二进制的一个位,每次左移一位
}
return;
}
/******************************************************************************/
/* 作 者:*RICK* */
/* 函数功能:TIMER1中断处理 */
// TL0=131;
TL0 =256;
TR0 = 1; //启动定时器0,定时1/4周期
return;
}
/******************************************************************************/
void SP_INT0(void) interrupt 0
{
return;
}
/******************************************************************************/
/* 作 者:*RICK* */
//TH0=(65536-定时次数)/256;;TL0=(65536-定时次数)%256;
//根据文档上的说明,一个位周期为1.688ms,那么1/4位周期为0.422ms
//TH0=(65536-422/12/11.0592)/256=(65536-388.9152)/256=65147.0848/256=254.4808,四舍五入255;
/* 函数功能:INT0中断处理 */
/* 时间:2010-07-01 */
#include "Vars_Def.h"
#include "math.h"
/***************************************/
/* 作 者:*RICK* */
TH0 = 250;
// TL0=14;
TL0 = 1536;
YKDatas[YKtype] = YKDatas[YKtype] | in; //每次定时时间到读取输入端口数据,将数据放入最低位
YKcount ++;
if((YKcount == 1)||(YKcount == 2) )
/* 作 者:*RICK* */
/* 函数功能INT1中断处理 */
/******************************************************************************/
/*在等待第一次低电平到来后, 定时器开始第一次定时T1/4b时间, 然后到达第一次数据
的T3/4b时刻, 读取该位电平状态;以后定时器每次定时Tb时间, 这样到达对应每位的T3/4
if( ++ time == width)
{
HC595_OE = 0;
}
else if(time == period)
{
time = 0;
HC595_OE = 1;
/* 最后修改时间:2010-07-01 */
/******************************************************************************/
{
if(in == 0) //起始两位必须都为1
{
TR0 = 0;
ET0 = 0; //定时器0中断关闭
YKReset();
return;
}
}
if(YKcount == 3) //获取完Start bits 和control bit, 共3位
if(YKtype == 3) //等待最后1/4位时间结束, 实际延时1位时间
{
}
//设置定时器初值
//模式1: TH0 = (2^16 - (1651/1.085)) / 2^8 = (65536 - 1651/1.085) / 256 = 250;
//TL0 = (65536 - 1651/1.085) % 256 = 14
/* 函数功能:TIMER0中断处理,向74HC595发送数据 */
/* 时间:2010-07-01 */
/* 最后修改时间:2010-07-01 */
时刻, 并可读取该位电平状态
Tb = 1.778ms = 1.780ms (实际中测试为1.651ms)
T1/4b = 445us (实际中413ms)
T3/4b = 1.335ms (实际1.239ms) */
//TL0=(65536-422/12/11.0592)%256,四舍五入131;
ET0 = 1;//定时器0允许中断
//一位按1680um计算
TH0=255;
//模式1: TH0 = (2^16 - (410/1.085)) / 2^8 = (65536 - 410/1.085) / 256 = 255;
/*当有遥控信号触发中断以后, 首先关闭外部中断,禁止中断,然后开启定时器捕捉遥控信号 */
void SP_INT1(void) interrupt 2
{
EX1 = 0; //关闭外部中断1,因为这个时候开始接收数据后,不需要中断。接收完成后才需要中断
//其实很简单,不管你使用多大的晶振,使用51单片机,一般都是12分频出来,也就可以得出一个机器周期
//YKtye的取值范围就是0,1,2
//遥控码(一帧14位)
//YKDatas[0]: 0,1为start bits, 2 为control bit, YKtype=0
//YKDatas[1]: 3~7为system bits, YKtype=1
//YKDatas[2]: 8~13为command bits, YKtype=2
/* 时间:2010-07-01 */
/* 最后修改时间:2010-07-01 */
/******************************************************************************/
void SP_TIMER1(void) interrupt 3
{
ET1 = 1;
TH1 = 252;
TL1 = 1024;
{
YKtype = 1;
}
else if(YKcount == 8) //获取完system bits, 共5位
{
if(YKDatas[1] != 0) //系统码全为0才是正确的
{
TR0 = 0;
ET0 = 0; //定时器0中断关闭
相关文档
最新文档