基于51单片机的红外遥控编码解码的C语言程序和电路
- 格式:doc
- 大小:108.50 KB
- 文档页数:7
基于51单片机红外无线遥控智能小车控制设计摘要:本文利用51单片机设计了一款具有红外无线遥控功能的智能小车控制系统。
该系统基于红外技术,实现了对智能小车的远程控制。
通过建立遥控信号传输模型和小车控制模块,实现了智能小车的实时运动控制,包括前进、后退、左转、右转等操作。
本文详细介绍了系统设计方案、硬件设计和软件设计,通过实验验证,证明该系统能够稳定地实现智能小车的远程控制,具有一定的应用价值和推广前景。
关键词:51单片机;红外无线遥控;智能小车控制;遥控信号传输模型Abstract:In this paper, a smart car control system with infrared wireless remote control function based on 51 single-chip microcomputer is designed. The system is based on infrared technology, which realizes the remote control of the smart car. By establishing the remote control signal transmission model and the car control module, real-time motion control of the smart car, including forward, backward, turning left and turning right, is realized. This paper introduces the system design scheme, hardware design and software design in detail. Through experiments, it is proved that the system can stably realize the remote control of the smart car, and has certain application value and promotion prospects.Keywords:51 single-chip microcomputer; infrared wireless remote control; smart car control; remote control signaltransmission model1. 引言智能小车控制系统是一种目前比较受关注的智能化系统,在智能出行和智慧交通中有着广泛的应用。
#include<reg52.h>sbit DQ=P3^2; //接收头的数据输出引脚sbit FM=P2^3; //蜂鸣器的控制端unsigned char dat[4]; //用于接收4个字节的红外数据unsigned char data_code; //用于保存按键值sbit L0=P1^0;sbit L1=P1^1;sbit L2=P1^2;sbit L3=P1^3;sbit L4=P1^4;sbit L5=P1^5;sbit L6=P1^6;sbit L7=P1^7;bit key_on; //定义一个按键闭合标志位,如果按键被按下了,该位置1/*--毫秒级延时函数,参数为多少则延时多少毫秒--*/void delay_ms(unsigned int t){unsigned int a,b;for(a=0;a<t;a++){for(b=0;b<113;b++){;}}}/*定时器0和中断0的初始化函数*/void init(){TMOD=0x01; //定时器0工作在方式1,为16位的定时器EX0=1; //开中断1IT0=1; //低电平触发中断0EA=1; //开总中断}/*对4个字节的红外遥控数据进行解码操作的函数这4个字节数据保存在了dat[i]的数组中返回值为dat[2],它是我们需要的的按键值如果解码成功,会返回正确的dat[2],如果解码失败那么返回的dat[2]=0 */unsigned char de_code(){unsigned char i,j;unsigned char temp; //用于暂存接收到的数据unsigned int high_time,low_time; //分别用于保存高低电平的时间值for(i=0;i<4;i++) //循环4次才能接收完毕4个字节的数据{for(j=8;j>0;j--) //循环8次才能接收完毕一个字节的数据{temp=temp>>1; //数据整体右移一位,用于接收一个位数据TL0=0x00; //定时器0赋初值0TH0=0x00;TR0=1; //打开定时器0,对低电平时间进行计数while(DQ==0) //如果为低电平就一直while语句中此循环{if(TH0>0x03) //如果低电平时间远超过0.56ms了,说明不是0或者1return dat[2]=0x00; //跳出中断并返回一个值为0的按键码,表明本次解码失败}TR0=0; //关闭定时器0low_time=TH0*256+TL0; //计算低电平时间TL0=0x00; //重新装初值0TH0=0x00;TR0=1; //开定时器0,对高电平时间进行计数while(DQ==1){if(TH0>0x08) //如果高电平时间远超过1.69ms了,说明不是0或者1return dat[2]=0xff; //跳出中断并返回一个值为0的按键码,表明本次解码失败}TR0=0; //关定时器0,计算高电平时间high_time=TH0*256+TL0; //计算高电平时间if((low_time<370)||(low_time>640)) //如果高电平时间不是0.56ms左右(远离这个区间)return dat[2]=0x00; //那么返回0,说明解码失败if((high_time>420)&&(high_time<620)) //如果高电平时间在0.56ms左右(在这个区间即可)temp=temp&0x7f; //说明这个位数据为0,保存数据0else if((high_time>1300)&&(high_time<1800)) //如果高电平时间在1.69ms左右(在这个区间即可)temp=temp|0x80; //说明这个位数据为1,保存数据1else return dat[2]=0x00; //如果高电平时间不是1.69ms左右,那么返回0,说明解码失败}dat[i]=temp; //每解码完成一个字节后,对这个字节进行保存}if(dat[2]==~dat[3]) //解码得到的按键值与按键值的反码取反后进行比较{ //如果一致,则说明解码成功FM=0; //蜂鸣器发声,播报解码成功key_on=1; //置1,表明按键被按下return dat[2]; //返回这个解码成功的按键值}else return dat[2]=0x00; //如果不一致,那么返回0,说明解码失败}void int0_ISR() interrupt 0{unsigned int high_time,low_time; //分别用于保存高低电平的时间值EX0=0; //关闭中断TL0=0x00; //装初值0TH0=0x00;TR0=1; //开定时器0while(DQ==0) //{if(TH0>0x25) //如果低电平时间远超过9ms了,说明不是引导码{EX0=1; //开中断0,准备下次中断return; //跳出此次中断}}TR0=0;low_time=TH0*256+TL0;TL0=0x00;TH0=0x00;TR0=1;while(DQ==1){if(TH0>0x20) //如果高电平时间远超过4.5ms了,说明不是引导码{EX0=1; //开中断0,准备下次中断return; //跳出此次中断}}TR0=0; //关定时器0,计算电平时间high_time=TH0*256+TL0; //计算高电平时间if((low_time>7800)&&(low_time<8800)&&(high_time>3600)&&(high_time<4700))//如果低电平在9ms左右,高电平在4.5ms左右,说明为引导码data_code=de_code(); //对引导码后面的32位数据进行解码接收,并获得按键值EX0=1; //解码接收完成后,开中断delay_ms(30); //延时30ms,让蜂鸣器发声30msFM=1; //停止发声}void main(){init();while(1){if(key_on==1) //如果按键被按下了,那么就执行相应按键的操作{key_on=0; //按键标志位清0switch(data_code){case 0x45: L0=~L0; break; //此按键被按下,就对L0进行控制case 0x46: L1=~L1; break; //此按键被按下,就对L1进行控制case 0x47: L2=~L2; break; //此按键被按下,就对L2进行控制case 0x44: L3=~L3; break; //此按键被按下,就对L3进行控制case 0x40: L4=~L4; break; //此按键被按下,就对L4进行控制case 0x43: L5=~L5; break; //此按键被按下,就对L5进行控制case 0x07: L6=~L6; break; //此按键被按下,就对L6进行控制case 0x15: L7=~L7; break; //此按键被按下,就对L7进行控制default:break;}}}}。
51单片机红外遥控格力空调程序#include <reg52.h>#define uchar unsigned char#define uint unsigned intsbit key1=P3^4;//按键控制开机sbit key2=P3^5;//按键控制关机sbit key3=P3^6;//按键控制温度+sbit key4=P3^7;//按键控制温度-sbit out=P1^5;//发送IO口uchar wd1[15]={0x00,0x08,0x04,0x0c,0x02,0x0a,0x06,0x0e,0x01,0x09,0x05,0x0d,0x03,0x0b,0x07};uchar wd2[15]={0x0a,0x06,0x0e,0x01,0x09,0x05,0x0d,0x03,0x0b,0x07,0x0f,0x00,0x08,0x04,0x0c};uchar x=12;//开机28度/************晶振11.0592MHz**************/ void delay(uint xms){uint i,j;for(i=xms;i>0;i--) //i=xms即延时约xms毫秒for(j=112;j>0;j--);}void delay560us(void) //560us延迟函数{uint j;for(j=63;j>0;j--);}void delay4500us(void) //4.5ms延迟函数{uint j;for(j=516;j>0;j--);}void khz_2(uint num) //38KHZ脉冲占空比1:2{for(;num>0;num--){out=~out;}}void send0_a(void) //发送0{khz_2(42) ;//khz_3(21) ;out=1;delay560us();}void send1_a(void) //发送1 {khz_2(42) ;out=1;delay560us();delay560us();delay560us();}void leadcode_a(void) //发送引导码{khz_2(690) ;out=1;delay4500us();}/***************************关机****************************/void close( uchar a,uchar b,uchar c,uchar d) {uint i;leadcode_a();send1_a();for(i=0;i<7;i++)send0_a();if(a)send1_a();elsesend0_a();if(b)send1_a();elsesend0_a();if(c)send1_a();elsesend0_a();if(d)send1_a();elsesend0_a();send0_a();send0_a();send0_a();for(i=0;i<5;i++)send0_a();send1_a();for(i=0;i<6;i++)send0_a();send1_a();send0_a();send1_a();send0_a();send0_a();send1_a();send0_a();khz_2(42) ;out=1;delay(20);}void close1(uchar e,uchar f,uchar g,uchar h ) {uchar i;for(i=0;i<13;i++)send1_a();send0_a();send0_a();for(i=0;i<12;i++)send0_a();if(e)send1_a();elsesend0_a();if(f)send1_a();elsesend0_a();if(g)send1_a();elsesend0_a();if(h)send0_a();elsesend1_a();khz_2(42) ;out=1;delay(1000);/*******************************************//****************开机************************/}void open(uchar a,uchar b,uchar c,uchar d ){uint i;leadcode_a();send1_a();send0_a();send0_a();send1_a();for(i=0;i<4;i++)send0_a();if(a)send1_a();elsesend0_a();if(b)send1_a();elsesend0_a();if(c)send1_a();elsesend0_a();if(d)send1_a();elsesend0_a();send0_a();send0_a();send0_a();send0_a();for(i=0;i<5;i++)send0_a();send1_a();for(i=0;i<6;i++)send0_a();send1_a();send0_a();send1_a();send0_a();send0_a();send1_a();send0_a();khz_2(42) ;out=1;delay(20);}void open1(uchar e,uchar f,uchar g,uchar h) {uchar i;for(i=0;i<13;i++)send0_a();send1_a();send0_a();send0_a();for(i=0;i<12;i++)send0_a();if(e)send1_a();elsesend0_a();if(f)send1_a();elsesend0_a();if(g)send1_a();elsesend0_a();if(h)send1_a();elsesend0_a();khz_2(42) ;out=1;delay(1000);}void keyscan(){uchar a,b,c,d,e,f,g,h;if(key1==0){delay(10);if(key1==0){while(!key1);if(wd1[x] & 0x08)a=1;elsea=0;if(wd1[x] & 0x04)b=1;elseb=0;if(wd1[x] & 0x02)c=1;elsec=0;if(wd1[x] & 0x01)d=1;elsed=0;if(wd2[x] & 0x08) e=1;elsee=0;if(wd2[x] & 0x04)f=1;elsef=0;if(wd2[x] & 0x02)g=1;elseg=0;if(wd2[x] & 0x01)h=1;elseh=0;open(a,b,c,d);open1(e,f,g,h);}}if(key2==0){delay(10);if(key2==0){while(!key2);if((wd1[x] & 0x08)) a=1;elsea=0;if((wd1[x] & 0x04))b=1;elseb=0;if((wd1[x] & 0x02))c=1;elsec=0;if((wd1[x] & 0x01))d=1;elsed=0;if((wd2[x] & 0x08))e=1;elsee=0;if((wd2[x] & 0x04))elsef=0;if((wd2[x] & 0x02))g=1;elseg=0;if((wd2[x] & 0x01))h=1;elseh=0;close(a,b,c,d);close1(e,f,g,h);}}if(key3==0){delay(10);if(key3==0){while(!key1);x++;if((wd1[x] & 0x08)) a=1;elseif((wd1[x] & 0x04))b=1;elseb=0;if((wd1[x] & 0x02))c=1;elsec=0;if((wd1[x] & 0x01))d=1;elsed=0;if((wd2[x] & 0x08)) e=1;elsee=0;if((wd2[x] & 0x04))f=1;elsef=0;if((wd2[x] & 0x02))g=1;elseg=0;if((wd2[x] & 0x01))h=1;elseh=0;open(a,b,c,d);open1(e,f,g,h);}}if(key4==0){delay(10);if(key4==0){while(!key1);x--;if((wd1[x] & 0x08))a=1;elsea=0;if((wd1[x] & 0x04))b=1;elseb=0;if((wd1[x] & 0x02))c=1;elsec=0;if((wd1[x] & 0x01))d=1;elsed=0;if((wd2[x] & 0x08)) e=1;elsee=0;if((wd2[x] & 0x04))f=1;elsef=0;if((wd2[x] & 0x02))g=1;elseg=0;if((wd2[x] & 0x01))h=1;elseh=0;open(a,b,c,d);open1(e,f,g,h);}}}void init(){key1=1;key2=1;key3=1;key4=1;out=1;}void main(){init();while(1){keyscan();}}。
红外线遥控解码接收程序-C语言.txt铁饭碗的真实含义不是在一个地方吃一辈子饭,而是一辈子到哪儿都有饭吃。
就算是一坨屎,也有遇见屎壳郎的那天。
所以你大可不必为今天的自己有太多担忧。
红外线遥控解码接收程序-C语言#include <regx51.h>#define uchar unsigned char#define uint unsigned int#define IR_RE P3_2bit k=0; //红外解码判断标志位,为0那么为有效信号,为1那么为无效uchar date[4]={0,0,0,0}; //date数组为存放地址原码,反码,数据原码,反码/*--------------------------延时1ms程子程序-----------------------*/delay1000(){uchar i,j;i=5;do{j=95;do{j--;}while(j);i--;}while(i);}/*---------------------------延时882us子程序-----------------------*/delay882(){uchar i,j;i=6;do{j=71;do{j--;}while(j);i--;}while(i);}/*--------------------------延时2400us程子程序-----------------------*/delay2400(){uchar i,j;i=5;do{j=237;do{j--;}while(j);i--;}while(i);}//**************************************************************//**************************************************************/*----------------------------------------------------------*//*-----------------------红外解码程序(核心)-----------------*//*----------------------------------------------------------*/void IR_decode(){uchar i,j;while(IR_RE==0);delay2400();{delay1000();delay1000();for(i=0;i<4;i++){for(j=0;j<8;j++){while(IR_RE==0); //等待地址码第1位高电平到来delay882(); //延时882us判断此时引脚电平///CY=IR_RE;if(IR_RE==0){date[i]>>=1;date[i]=date[i]|0x00;}else if(IR_RE==1){delay1000();date[i]>>=1;date[i]=date[i]|0x80;}} //1位数据接收完毕} //32位二进制码接收完毕}}//*****************************************************************//********************************************************************/*------------------------外部中断0程序-------------------------*//*------------------主要用于处理红外遥控键值--------------------*/void int0() interrupt 0{uchar i;k=0;EX0=0; //检测到有效信号关中断,防止干扰for(i=0;i<4;i++){delay1000();if(IR_RE==1){k=1;} //刚开场为9ms的引导码. }if(k==0){// EX0=0; //检测到有效信号关中断,防止干扰IR_decode(); //如果接收到的是有效信号,那么调用解码程序P0=date[1];delay2400();delay2400();delay2400();}EX0=1; //开外部中断,允许新的遥控按键}//*********************************************************************//********************************void main(){SP=0x60; //堆栈指针EX0=1; //允许外部中断0,用于检测红外遥控器按键EA=1; //总中断开while(1);}总结:关于本段程序的准确延时在<<C51中准确的延时与计算的实现>>里的评论有很好的诠释.//在STC12C5410上运用红外线解码程序.主要的问题在于延迟上。
51单片机设计的红外线遥控器电路图及工作原理你家里是否有一个电视机遥控器或者空调机遥控器呢?你是否也想让它遥控其他的电器甚至让它遥控您的电脑呢?那好,跟我一起做这个“红外遥控*器”。
该小制作所需要的元件很少:单片机TA89C2051一只,RS232接口电平与TTL电平转换心片MAX232CPE 一只,红外接收管一只,晶振11.0592MHz,电解电容10uF4只,10uF 一只,电阻1K1个,300欧姆左右1个,瓷片电容30P2个。
发光二极管8个。
价钱不足20元。
电路图及原理:主控制单元是单片机AT89C2051,中断口INT0跟红外接受管U1相连,接收红外信号的脉冲,8个发光二极管作为显示*输出(也可以用来扩展接其他控制电路),U3是跟电脑串行口RS232相连时的电平转换心片,9、10脚分别与单片机的1、2脚相连,(1脚为串行接收,2脚为串行发送),MAX232CPE的7、8脚分别接电脑串行口的2(接收)脚、3(发送脚)。
晶振采用11.0592MHz,这样才能使得通讯的波特率达到9600b/s,电脑一般默认值是9600b/s、8位数据位、1位停止位、无校验位。
电路就这么简单了,现在分析具体的编程过程吧。
如图所示,panasonic遥控器的波形是这样的(经过反复测试的结果)。
/sch/rc/0080743.html开始位是以3.6ms低电平然后是3.6ms高电平,然后数据表示形式是0.9ms低电平0.9ms高电平周期为1.8ms表示“0”,0.9ms低电平 2.4ms高电平周期为3.3ms表示“1”,编写程序时,以大于3.4ms小于3.8ms高电平为起始位,以大于2.2ms小于2.7ms高电平表示“1”,大于0.84ms小于1.11ms高电平表示“0”。
因此,我们主要用单片机测量高电平的长短来确定是“1”还是“0”即可。
定时器0的工作方式设置为方式1:mov tmod,#09h,这样设置定时器0即是把GATE置1,16位计数器,最大计数值为2的16次方个机器周期,此方式由外中断INT0控制,即INT0为高时才允许计数器计数。
最简51单片机红外遥控解码程序(转载)2009-09-07 23:03/* 51单片机红外遥控解码程序 *//* 适用uPD6121系列 *//* 周正华 2008.4.11编 *//* /52_diy */#include <reg52.h>#define DIGPORT P2#define WORDPORT P0unsigned char code LED_num[]={0x3f,0x18,0x76,0x7c,0x59,0x6d,0x6f,0x38,0x7f,0x7d};#define Imax 14000 //此处为晶振为11.0592时的取值,#define Imin 8000 //如用其它频率的晶振时,#define Inum 1450 //要改变相应的取值。
unsigned char Im[]={0x00,0x00,0x00,0x00};unsigned long m,Tc;unsigned char i,IrOK;void DelayMy(unsigned int t){while(--t);}void Display_LED(unsigned long num){unsigned int ii;unsigned int jj=0;unsigned long aa,bb;unsigned int xx[8]={0,0,0,0,0,0,0,0};do{bb=num/10;aa=num-bb*10;xx[jj]=aa;num=bb;jj++;}while(num>0);DIGPORT=0x80;for(ii=0;ii<8;ii++){WORDPORT=LED_num[xx[ii]];DelayMy(60);DIGPORT=DIGPORT>>1;};WORDPORT=0;}//外部中断解码程序void intersvr1(void) interrupt 2 using 1{Tc=TH0*256+TL0; //提取中断时间间隔时长TH0=0; TL0=0; //定时中断重新置零if((Tc>Imin)&&(Tc<Imax)) m=0; //找到启始码if(Tc>Inum) Im[m/8]=Im[m/8]>>1|0x80; else Im[m/8]=Im[m/8]>>1; //取码if(m==32) if((Im[2]|0x01)==~Im[3]) IrOK=1; else IrOK=0; //取码完成后判断读码是否正确m++; //准备读下一码}/*演示主程序*/void main(void){m=0;EA=1;IT1=1;EX1=1;TMOD=0x11;TH0=0;TL0=0;TR0=1;ET0=1;for(;;){DelayMy(100);if(IrOK==1) for(i=0;i<400;i++) Display_LED(Im[2]);IrOK=0;}}。
请勿转载!!!
作品功能简介:当学习键按下后,红外接收头便可将接受到的信号存储到单片机中。在接受到通用遥控
器发出的信号后,如果按下发射键,单片机将调出刚刚储存的信息,通过红外发射头发射出和遥控器一
样的信号来达到控制的作用。
#include
#include
#define uchar unsigned char
#define uint unsigned int
sbit studylamp=P2^7;
sbit lamp=P2^6;
sbit studykey=P3^2;
sbit remotein=P1^1;
sbit remoteout=P1^0;
sbit txkey=P2^0;
uint i,j,m=255,n,k,s;
uchar idata remotedata[206];
uint head;
uint remdata;
//一毫秒延时程序
delay1ms(uint t)
{
for(i=0;i
}
//初始化函数
clearmen()
{
studylamp=1;
lamp=1;
remoteout=0;
remotein=1;
for(i=0;i<206;i++)
{
remotedata[i]=0x00;
}
IE=0x00;
IP=0x01;
TMOD=0x22;
PCON=0X00;
TH1=0xf3;
TL1=0xf3;
IT0=1;
EX0=1;
EA=1;
}
//键功能函数
void key_tx()
{
if(txkey==0)
{
delay1ms(1);
if(txkey==0)
{
while(txkey==0);
ET1=1;TR1=1;
for(i=head;i>0;i--);
remoteout=0;ET1=0;TR1=0;
n=0;
while(1)
{
lamp=0;
studylamp=1;
if(remotedata[n]==0x00)
{
delay1ms(10);break;
}
for(i=remotedata[n];i>0;i--)
{
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
}
n++;
ET1=1;TR1=1;
for(i=remotedata[n];i>0;i--);
remoteout=0;ET1=0;TR1=0;n++;
}
}
}
}
//主函数
void main()
{
clearmen(); //初始化
while(1)
{
key_tx(); //按键扫描
}
}
//40KHz发生器
void time_intt1(void) interrupt 3
{
remoteout=~remoteout;
}
//外中断0
void intt0(void) interrupt 0
{
ET1=0;TR1=0;EX0=0;EA=0;
head=0;
while(studykey==0);
studylamp=0;lamp=1;
while(remotein==1);
head=0;
while(remotein==0)
{
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
head++;
}
n=0;remdata=0x0000;
while(1)
{
while(remotein==1)
{
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
remdata++;
}
if(remdata>m) //高电平>5毫秒退出
{remotedata[n]=0x00;EX0=1;EA=1;goto end;}
remotedata[n]=remdata;n++;
remdata=0x0000;
while(remotein==0)
{
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
remdata++;
}
remotedata[n]=remdata;
n++;
remdata=0x00;
}
end: lamp=0;studylamp=0;
}
电路:
实物:
2009-06-25 12:39