基于51单片机红外发射与接收C程序

合集下载

红外遥控和C语言51红外遥控解码程序设计实例

红外遥控和C语言51红外遥控解码程序设计实例

红外遥控和C语言51红外遥控解码程序设计实例红外遥控和C语言51红外遥控解码程序设计实例什么是红外线?人的眼睛能看到的可见光按波长从长到短排列,依次为红、橙、黄、绿、青、蓝、紫。

其中红光的波长范围为0.62~0.76μm;比红光波长还长的光叫红外线。

红外遥控在生产和生活中应用越来越广泛,不同的红外遥控芯片有不同的发码协议,但一般都是由引导码,系统码,键码三部分组成.红外线遥控就是利用波长为0.76~1.5μm之间的近红外线来传送控制信号的。

红外发光二极管一般有黑色、深蓝、透明三种颜色。

红外遥控系统一般分发射和接收两个部分。

发射部分的主要元件为红外发光二极管。

目前大量使用的红外发光二极管发出的红外线波长为940mm左右,外形与普通φ5发光二极管相同。

接收部分的红外接收管是一种光敏二极管。

红外发光二极管一般有圆形和方形两种。

由于红外发光二极管的发射功率一般都较小(100mW左右),所以红外接收二极管接收到的信号比较微弱,因此就要增加高增益放大电路。

最近几年大多都采用成品红外接收头。

成品红外接收头的封装大致有两种:一种采用铁皮屏蔽;一种是塑料封装。

均有三只引脚,即电源正(VDD)、电源负(GND)和数据输出(VO或OUT)。

红外接收头的引脚排列因型号不同而不尽相同,可参考厂家的使用说明。

成品红外接收头的优点是不需要复杂的调试和外壳屏蔽,使用起来如同一只三极管,非常方便。

但在使用时注意成品红外接收头的载波频率。

红外遥控常用的载波频率为38kHz,这是由发射端所使用455kHz晶振来决定的。

在发射端要对晶振进行整数分频,分频系数一般取12,所以455kHz?12?37.9kHz?38kHz。

也有一些遥控系统采用36 kHz、40kHz、56 kHz等,由发射端晶振的振荡频率来决定。

红外遥控的特点是不影响周边环境的、不干扰其他电器设备。

室内近距离(小于10米)遥控中得到了广泛的应用。

红外遥控在生产和生活中应用越来越广泛,不同的红外遥控芯片有不同的发码协议,但一般都是由引导码,系统码,键码三部分组成.引导码是告诉接收机准备接收红外遥控码.系统码是识别码,不同的遥控芯片有不同的误别码,以免搞错.遥控器上不同的按键有不同的键码,系统码和键码都是16位码,8位正码,8位反码.如SC6122的系统码是FF00,FF和00互为反码,键码1为EF10也是互为反码.SC6122的引导码为低电平为9000微秒,高电平为4500微秒.当然高电平不可能精确为9000微秒,在8000微秒到10000微秒都看作是正常范围,低电平在4000-5000之间都看作是正常范围.引导码后的32位编码(16位系统码和16位不管高低电平,载波时间都是560微秒,但低电平持续时间是1125微秒,高键码) 电平持续时间是2250微秒,所以低电平除去载波时间大约是560微秒,高电平除低电平也有一个波动范围,在400-700之间都看作去载波时间大约是1680微秒.是正常的,具体多少可以通过示波器测量出来.高电平也有一个波动范围,在400-2000之间都看作是正常的,具体多少也是根据经验.当然范围越宽,捕捉红外线的范围也越宽,越精确.在捕捉到有高低电平之间,在560-1680之间取一个中间值1120微秒,认为小于1120微秒是低电平,大于1120微秒是高电平.////////////////////////////////////////////////////////红外接收后的数据通过UART发出//晶振:12M//author:cole//date:09.6.6//////////////////////////////////////////////////////#include reg52.h void uart_init(void);#define c(x)(x)sbit Ir_Pin=P3^2;unsigned char Ir_Buf[4];//用于保存解码结果 unsigned int Ir_Get_Low() {TL0=0;TH0=0;TR0=1;while(~Ir_Pin&&(TH0&0x80)==0); TR0=0;return TH0*256+TL0;}//===unsigned int Ir_Get_High(){TL0=0;TH0=0;TR0=1;while(Ir_Pin&&(TH0&0x80)==0); TR0=0;return TH0*256+TL0; }//==main(){unsigned int temp; char i,j;P3=0xff;uart_init();do{restart:while(Ir_Pin);temp=Ir_Get_Low(); if(temp c(8500)||temp c(9500))continue;//引导脉冲低电平9000temp=Ir_Get_High();if(temp c(4000)||temp c(5000))continue;//引导脉冲高电平4500for(i=0;i 4;i++)//4个字节 {for(j=0;j 8;j++)//每个字节8位{temp=Ir_Get_Low();if(temp c(200)||temp c(800))goto restart; temp=Ir_Get_High();if(temp c(200)||temp c(2000))goto restart;Ir_Buf[i]=1;if(temp c(1120))Ir_Buf[i]|=0x80; }}for(i=2;i 4;i++){SBUF=Ir_Buf[i];while(TI==0);TI=0;}}while(1);}///////////////////////////////////////////////////////////UART初始化//波特率:9600/////////////////////////////////////////////////////////void uart_init(void) {unsigned char u;ET1=0;TMOD=0x21;//定时器1工作在方式2(自动重装) SCON=0x50;//10位uart,容许串行接受 TH1=0xFD;TL1=0xFD;u=SBUF;TR1=1;}。

基于51单片机的红外遥控智能小车源程序(C语言)

基于51单片机的红外遥控智能小车源程序(C语言)

/*预处理命令*/#include<reg52.h> //包含单片机寄存器的头文件#include<intrins.h> //包含_nop_()函数定义的头文件#define uchar unsigned char#define uint unsigned int#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};sbit IRIN=P3^2; //红外接收器数据线sbit LCD_RS = P0^7;sbit LCD_RW = P0^6;sbit LCD_EN = P0^5;uchar begin[]={"My car!"};uchar cdis1[]={"jiansu!"};uchar cdis2[]={"qianjin!"};uchar cdis3[]={"jiasu!"};uchar cdis4[]={"zuozhuang!"};uchar cdis5[]={"STOP!"};uchar cdis6[]={"youzhuan!"};uchar cdis8[]={"daoche!"};sbit M1 = P1^0;sbit M2 = P1^1;sbit M3 = P1^2;sbit M4 = P1^3;sbit EN12 = P1^4;sbit EN34 = P1^5;uchar IRCOM[7];uchar m,n;uchar t=2;uchar g;uchar code digit[]={"0123456789"};uint v;uchar count;bit flag;void delayxms(uchar t);void delay(unsigned char x) ;void delay1(int ms);void motor();void lcd_display();/*检查LCD忙状态lcd_busy为1时,忙,等待。

自己写的51单片机的红外线遥控接收程序(C语言)

自己写的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有没有下降沿。

红外收发模块51单片机程序部分

红外收发模块51单片机程序部分

深圳市技新电子科技有限公司www.jixin.pro红外收发模块51单片机程序部分V1.0.0.0红外收发模块51单片机程序部分1、红外收发原理介绍1.1红外接收头决定了通信的频率是38KHZ红外通信模块发射红外光的频率是38KHZ,这个频率是由红外接收探头决定的,市场上还有其他频率的产品这里不讨论。

技小新的红外收发模块上面用的接收头就是这种38KHZ 的,型号是IRM-3638T。

红外发射的探头没有这个频率限制,所以可以用单片机自由控制。

1.2红外通信的流程单片机A控制红外发光管,发射38KHZ频率的光,同时遵守一定的通信规则,比如电影里常见的“摩斯密码”。

红外接收头连接着单片机B,红外接收头收到红外光后会输出一连串的高低电平到单片机B,单片机B根据“摩斯密码”的规则解码。

这样就完成了一次红外通信。

1.3红外载波调制的约定我们使用的通信方式叫做载波调制。

(1)由于发射频率是38KHZ,很容易得出发射一个信号的周期是26.3uS.(2)对于发射端:“载波发射”一个周期是,发光8.77uS+不发光17.53uS。

“载波不发射”一个周期是,26.3uS不发光。

(3)对于接收端:如果收到了一个“载波发射”信号,输出低电平26.3uS。

如果收到了一个“载波不发射”信号(其实就是没有收到信号),输出高电平26.3uS。

真正使用时候要发送一连串的“载波发射”和“载波不发射”,这样接收端输出的是连续的脉冲。

(注意,仅仅一个“载波发射”并不能让接收端正确输出。

)1.4NEC_upd6121红外通信协议。

这是很多遥控器厂商都在使用的协议。

它的协议约定如下:(1)引导码:342个连续“载波发射”+171个“载波不发射”。

接收端的反应是9mS的低电平+4.5mS的高电平。

(2)数据“0”表示为:21个连续“载波发射”+21个连续“载波不发射”。

接收端的反应是:0.56mS的低电平+0.56mS的高电平。

(3)数据“1”表示为:21个连续“载波发射”+64个连续“载波不发射”。

基于51单片机控制红外通信

基于51单片机控制红外通信

精心整理红外通信原理红外遥控有发送和接收两个组成部分。

发送端采用单片机将待发送的二进制信号编码调制为一系列的脉冲串信号,通过红外发射管发射红外信号。

红外接收完成对红外信号的接收、放大、检波、整形,并解调出遥控编码脉冲。

为了减少干扰,采用的是价格便宜性能可靠的一体化红外接收头(HS0038,它接收红外信号频率为38kHz,(2)PPM编码这种遥控编码具有以下特征:遥控编码脉冲由前导码、16位地址码(8位地址码、8位地址码的反码)和16位操作码(8位操作码、8位操作码的反码)组成。

前导码:是一个遥控码的起始部分,由一个9ms的高电平(起始码)和一个4.5ms的低电平(结果码)组成,作为接受数据的准备脉冲。

16位地址码:能区别不同的红外遥控设备,防止不同机种遥控码互相干扰。

16位操作码:用来执行不同的操作。

采用脉宽调制的串行码,以脉宽为0.56ms、间隔0.56ms、周期为1.12ms的组合表示二进制的“0”;以脉宽为1.68ms、间隔0.56ms、周期为2.24ms的组合表示二进制的“1”。

???{???}?}}一串完整的编码如下图所示前导码地址码地址反码操作码操作反码2.红外接收部分:红外接收完成对红外信号的接收、放大、检波、整形,并解调出遥控编码脉冲。

为形得到HS0038#defineuintunsignedintucharram[4]={0,0,0,0};//存放接受到的4个数据地址码16位+按键码8位+按键码取反的8位voiddelaytime(uinttime)//延迟90uS{uchara,b;for(a=time;a>0;a--){for(b=40;b>0;b--);}}voidrem()interrupt0//中断函数{ucharramc=0;//定义接收了4个字节的变量ucharcount=0;//定义现在接收第几位变量{电平return;//}32位中//第一位数据的0.56MS开始脉冲for(ramc=0;ramc<4;ramc++)//循环4次接收4个字节{for(count=0;count<8;count++)//循环8次接收8位(一个字节){while(prem!=1);//开始判断现在接收到的数据是0或者1,首先在这行本句话时,//保已经进入数据的0.56MS低电平阶段//等待本次接受数据的高电平的到来。

51单片机基于红外线的发射与接收控制机顶盒和电视机一体化遥控方案

51单片机基于红外线的发射与接收控制机顶盒和电视机一体化遥控方案

/****************************************************************************** ******************************************************************************* 51单片机基于红外线的发射与接收控制机顶盒和电视机一体化遥控方案实验平台:51单片机开发板实验目的:通过机顶盒遥控器控制与单片机连接的继电器控制机顶盒的电源切断同时单片机的红外发射管控制电视机关闭。

实验连线:红外线一体接收管IR接P3^2;继电器0,1,2分别接P2^7;P2^6,P2^5,采用低电平触发,红外发射管P1^5;实验要点:注意接收管采用的是NEC协议,而发射使用的是TP9012的协议,且载波不同。

NEC协议的载波占空比为1/2,TP9012的协议载波占空比为1/3,可使用逻辑分析仪对载波进行调节。

******************************************************************************* ******************************************************************************/ #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义#define uchar unsigned char#define uint unsigned intsbit IR=P3^2; //红外接口标志bit jdq;sbit jdq0=P2^7;sbit jdq1=P2^6;sbit jdq2=P2^5;sbit out=P1^5;//红外线发射端口/*------------------------------------------------全局变量声明------------------------------------------------*/unsigned char irtime;//红外用全局变量bit irpro_ok,irok;unsigned char IRcord[4];unsigned char irdata[33];//************************************************//// 红外线发射程序部分////************************************************///*------------------------------------------------延时函数1ms------------------------------------------------*/void delay(uint xms){uint i,j;for(i=xms;i>0;i--) //i=xms即延时约xms毫秒for(j=120;j>0;j--);}void delay9us(void) //误差0us{unsigned char a;for(a=1;a>0;a--);}void delay560us(void) //560us延迟函数{unsigned char a,b,c;for(c=1;c>0;c--)for(b=2;b>0;b--)for(a=130;a>0;a--);}void delay4500us(void) //4.5ms延迟函数{unsigned char a,b,c;for(c=3;c>0;c--)for(b=136;b>0;b--)for(a=4;a>0;a--);}void khz_2(uint num) //38KHZ脉冲占空比1:3{for(;num>0;num--){out=1;delay9us();out=0;delay9us();}}void send0_a(void) //发送0{khz_2(21) ;out=1;delay560us();}void send1_a(void) //发送1{khz_2(21) ;out=1;delay560us();delay560us();delay560us();}void leadcode_a(void) //发送引导码{khz_2(150) ;out=1;delay4500us();}void overcode(void){out=0;delay(46);leadcode_a();khz_2(12) ;out=1;delay560us();delay560us();delay560us();khz_2(12) ;out=0;}const uchar TabHL1[4]={0x70,0x70,0x30,0xcf};//电视机客户码+用户码+用户反码void Send8Bit(uchar d) //发送一字节数据{if(d&0x80){ send1_a();}else{ send0_a();}if(d&0x40){ send1_a();}else{ send0_a();}if(d&0x20){ send1_a();}else{ send0_a();}if(d&0x10){ send1_a();}else{ send0_a();}if(d&0x08){ send1_a();}else{ send0_a();}if(d&0x04){ send1_a();}else{ send0_a();}if(d&0x02){ send1_a();}else{ send0_a();}if(d&0x01){ send1_a();}else{ send0_a();}}void usercode() //发送用户码{Send8Bit(TabHL1[0]);Send8Bit(TabHL1[1]);}void fashe(){leadcode_a();usercode();Send8Bit(TabHL1[2]);Send8Bit(TabHL1[3]);khz_2(12) ;out=0;}//************************************************// // 红外线接收程序部分////************************************************///*------------------------------------------------函数声明------------------------------------------------*/void Ir_work(void);void Ircordpro(void);/*------------------------------------------------定时器0中断处理------------------------------------------------*/void tim0_isr (void) interrupt 1 using 1{irtime++; //用于计数2个下降沿之间的时间}/*------------------------------------------------外部中断0中断处理------------------------------------------------*/void EX0_ISR (void) interrupt 0 //外部中断0服务函数{static unsigned char i; //接收红外信号处理static bit startflag; //是否开始处理标志位if(startflag){if(irtime<63&&irtime>=33)//引导码TC9012的头码,9ms+4.5ms 63 33i=0;irdata[i]=irtime;//存储每个电平的持续时间,用于以后判断是0还是1irtime=0;i++;if(i==33){irok=1;i=0;}}else{irtime=0;startflag=1;}}/*------------------------------------------------定时器0初始化------------------------------------------------*/void TIM0init(void)//定时器0初始化{TMOD=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值TH0=0x00; //重载值TL0=0x00; //初始化值ET0=1; //开中断TR0=1;}/*------------------------------------------------外部中断0初始化------------------------------------------------*/void EX0init(void){IT0 = 1; //指定外部中断0下降沿触发,INT0 (P3.2)EX0 = 1; //使能外部中断EA = 1; //开总中断}/*------------------------------------------------键值处理------------------------------------------------*/void Ir_work(void)//红外键值散转程序{switch(IRcord[2])//判断第三个数码值{case0x45:jdq=~jdq;if(jdq){delay(100);jdq0=0;jdq1=0;jdq2=0;fashe();delay(100);}break;//1 显示相应的按键值default:break;}irpro_ok=0;//处理完成标志}/*------------------------------------------------红外码值处理------------------------------------------------*/void Ircordpro(void)//红外码值处理函数{unsigned char i, j, k;unsigned char cord,value;k=1;for(i=0;i<4;i++) //处理4个字节{for(j=1;j<=8;j++) //处理1个字节8位{cord=irdata[k];if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差value|=0x80;if(j<8){value>>=1;}k++;}IRcord[i]=value;value=0;}irpro_ok=1;//处理完毕标志位置1}/*------------------------------------------------主函数------------------------------------------------*/void main(void){EX0init(); //初始化外部中断TIM0init();//初始化定时器jdq=0;while(1)//主循环{//if(work==1)//{delay(5);if(work==1){if(!jdq){jdq0=1;jdq1=1;jdq2=1;}if(irok) //如果接收好了进行红外处理{Ircordpro();irok=0;}if(irpro_ok) //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等{Ir_work();}}}// else//{// jdq0=1;// jdq1=1;// jdq2=1;// ET0=0;// PCON=0x02;//}//}}。

STC单片机51简单的红外遥控发射程序C语言

STC单片机51简单的红外遥控发射程序C语言
for (j=0;j<43;j++) {s1=1;s1=1;Delay13us();} //高电平0.565ms无载波
}
void H(){ //红外1; 以低电平0.565ms,高电平1685表示1
uchar j;
for (j=0;j<43;j++) {s1=~s1;Delay13us();} //低电平0.565ms载波,模拟38KHZ
{
uint j;
while(1){
Delay3000ms();
//以下开始发送
for (j=0;j<692;j++) {s1=~s1;Delay13us();}//载波发送9ms的起始码
for (j=0;j<346;j++) {s1=1;Delay13us();} //无载波发送4.5ms的结果码
for (j=0;j<173;j++) {s1=1;Delay13us();} //2.25ms
for (j=0;j<44;j++) {s1=~s1;Delay13us();}//结束位
for (j=0;j<7400;j++) {s1=1;Delay13us();} //在延时96.2ms到108ms,在发送连发码
for (j=0;j<692;j++) {s1=~s1;Delay13us();}//载波发送9ms的起始码
for (j=0;j<173;j++) {s1=1;Delay13us();} //2.25ms
for (j=0;j<44;j++) {s1=~s1;Delay13us();}//结束位

51单片机红外数据收发程序(NEC标准)

51单片机红外数据收发程序(NEC标准)

发射部分程序:/********************************************************* FUNCTION: 红外数据发送 * DESCRIPTION: * HARDWAER: * PROGRAMMER: XXC * DATE: 2010-9-6 * COPYRIGHT: no * **********************************************************/;---------------------------------------------------------- ;存储空间定义DSEG AT 30HSend BIT P2.0LedSend BIT P2.1;---------------------------------------------------------- ;主程序CSEG AT 0000HORG 0000HAJMP L_MainORG 0030HL_Main: MOV SP,#60HMOV DPTR,#T_SendBufferMOV R1,#08H ;发送1字节数据(先低位后高位)MOV R2,#00H;发送4字节L_Loop1:CLR LedSend ;开LED指示NOPNOPSETB SendLCALL F_Delay4500us ;引导码LCALL F_Delay4500usCLR SendLCALL F_Delay4500usL_Loop2:MOV A,R2MOVC A,@A+DPTRL_Loop3:SETB SendLCALL F_Delay560us ;560usCLR SendRRC AJC L_Next1LCALL F_Delay560usLJMP L_Next2L_Next1:LCALL F_Delay1680usL_Next2:DJNZ R1,L_Loop3INC R2CJNE R2,#04H,L_Loop2SETB Send ;560us高电平结束LCALL F_Delay560usCLR SendSETB LedSend ;关LED指示LJMP $/*INT_Int0:PUSH ACCPUSH PSWCPL LED1POP PSWPOP ACCRETI*/;---------------------------------------------------------- ;延时约4500usF_Delay4500us:MOV R7,#20L_Delay4500:MOV R6,#225DJNZ R6,$DJNZ R7,L_Delay4500RET;---------------------------------------------------------- ;延时约560usF_Delay560us:MOV R7,#2L_Delay560:MOV R6,#140DJNZ R6,$DJNZ R7,L_Delay560RET;---------------------------------------------------------- ;延时约1680usF_Delay1680us:LCALL F_Delay560usLCALL F_Delay560usLCALL F_Delay560usRET;---------------------------------------------------------- ;延时约1sF_Delay1s:MOV R7,#5L_Delay1s1:MOV R6,#200L_Delay1s2:MOV R5,#250DJNZ R5,$DJNZ R6,L_Delay1s2DJNZ R7,L_Delay1s1RET;-----------------------------------------------;红外发送区数据T_SendBuffer:DB 0FH,0F0H ;用户码及反码DB 56H,0A9H ;操作码及反码END ;结束接收部分程序:/********************************************************* FUNCTION: 红外数据接收程序 * DESCRIPTION: * HARDWAER: * PROGRAMMER: XXC * DATE: 2010-9-7 *COPYRIGHT: no * **********************************************************/;---------------------------------------------------------- ;存储空间定义DSEG AT 30HF_Re BIT P3.2LED1 BIT P2.6R_Receive: DS 4 ;红外数据接收空间;---------------------------------------------------------- ;主程序CSEG AT 0000HORG 0000HAJMP L_MainORG 0003H ;INT0入口LJMP INT_Int0ORG 0030HL_Main: MOV SP,#60HSETB EASETB EX0SETB IE0 ;下降沿触发MOV DPTR,#T_CodeL_LoopMain:;------------------------MOV R1,#R_Receive+2MOV A,@R1ANL A,#0FH ;屏蔽高4位MOVC A,@A+DPTRMOV P1,A;------------------------;CPL P2.5;LCALL F_Delay300msLJMP L_LoopMain;---------------------------------------------------------- ;外部中断0;Function: NEC红外解码.黑色遥控器用户码FFH,00H;P3.2接外部中断INT_Int0:PUSH ACCPUSH PSWMOV R0,#R_ReceiveMOV R3,#08HMOV R4,#04HLCALL F_Delay8000usJB F_Re,L_ExitINT0 ;非引导码退出JNB F_Re,$LCALL F_Delay2500usJNB F_Re,L_ExitINT0 ;遇简码退出JB F_Re,$CLR LED1 ;open LED1L_NextBit:JNB F_Re,$LCALL F_Delay840usJB F_Re,L_Next1MOV C,F_ReLJMP L_Next2L_Next1:MOV C,F_ReLCALL F_Delay1100usL_Next2:RRC A ;先收低位DJNZ R3,L_NextBitMOV @R0,AINC R0MOV R3,#08HDJNZ R4,L_NextBitL_ExitINT0:SETB LED1 ;close LED1POP PSWPOP ACCRETI;---------------------------------------------------------- ;延时约8000usF_Delay8000us:MOV R7,#20L_Delay8000:MOV R6,#200DJNZ R6,$DJNZ R7,L_Delay8000RET;---------------------------------------------------------- ;延时约840us。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

基于51单片机红外发射与接收程序实验证明,效果非常好。

红外发射程序
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char #define uint unsigned int
sbit key1=P3^3;
sbit key2=P3^4;
sbit key3=P3^5;
sbit LED=P1^0; //发射指示灯sbit out=P3^7;
uchar i,a,num1;
void init()//初始化作用
{
key1=1;
key2=1;
key3=1;
}
void delay(uchar aa)
{
uchar bb,cc;
for(bb=aa;bb>0;bb--)
for(cc=200;cc>0;cc--);
}
void delayms(uchar aa)//延时程序
{
for(a=aa;a>0;a--)
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
}
void khz(uchar aa)//是发射38KHZ的程序
{
for(a=aa;a>0;a--) //这个for语句可以得到准确的26.3波特率{
out=0;
i=7; //低了17us
while(i>0)i--; // 38kHZ
out=1;
//高了9us 17+9=26us 比26.3快一点点}
}
//khz(116);//3.028ms 精确的时间
//khz(64);//2.006ms
//khz(40); //1.052ms
//delayms(125);//2.012ms 这里是一些时间的介绍
//delayms(65);//1.054ms
//delayms(93);//1.5ms
void fashu(uchar num)
{
khz(116);//发射3ms 38khz
delayms(125);
for(num1=8;num1>0;num1--) //原来用的是a 后来出错,肯定在这里!{
khz(40);
if(num&0x01)
delayms(93);//delay 1.5ms
else
delayms(65);//delay 1ms
num=num>>1;
}
khz(20);
}
void tishi()
{
LED=0;
delay(50);
LED=1;
delay(50);
LED=0;
delay(50);
LED=1;
}
void keyscan()//按键扫描
{
if(key1==0)
{
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
if(key1==0)
{
while(!key1);
fashu(0xf3);
tishi();
}
}
if(key2==0)
{
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
if(key2==0)
{
while(!key2);
fashu(0x3f);
tishi();
}
}
if(key3==0)
{
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
if(key3==0)
{
while(!key3);
fashu(0xf5);
tishi();
}
}
}
void main()
{
init();
while(1)
{
keyscan();
}
}
红外接收程序
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit led1=P1^0;
sbit led2=P1^1;
sbit led3=P1^2;
sbit in=P3^2;
uchar i,a,num;
bit fleg;
void init()
{
fleg=1;
in=1;
EA=1;
EX0=1;
IT0=1;
}
void delayms(uchar aa)
{
for(i=aa;i>0;i--)
{
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
}
}
void main()
{
init();
//delayms(45);//0.642ms
//delayms(35);//0.502ms
//delayms(115);//1.623ms
//delayms(72);//1.02ms
//delayms(84);//1.188ms
//delayms(31);//0.446ms
while(1);
}
void sieasdf() interrupt 0
{
EX0=0;
for(a=5;a>0;a--)
{
delayms(35);//延时0.5ms 判断5次5*0.5=2.5ms
if(in)fleg=0;
}
if(fleg)
{
delayms(72);//延时1ms 判断是不是高电平了
if(in)
{
delayms(115);//延时让它超过2ms; 2.5+1+1.623=5.123ms 开始读数据
delayms(118);//若偏移一位,可以去掉。

for(a=8;a>0;a--)
{
while(!in);
delayms(86);//延时1.188ms 判断IO高低,从而得0或1
num=num>>1;
if(in)
{
num=num|0x80;
delayms(31);//延时0.6ms 因为上面延时1.2ms+0.6 刚好跳过1.5ms }
}
P2=num;
}
}
fleg=1;
EX0=1;
}。

相关文档
最新文档