基于51单片机的NEC红外编码发射C语言程序
红外遥控和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程序(word文档良心出品)
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(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()
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);
while(1)
{
keyscan();
}
}
红外接收程序
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
基于51单片机的NEC红外解码
NEC编码
硬件
红外OUT脚接到了单片机P3^3中断接口
程序流程图
38K载波信号
HS0038
矩形波信号
单片机中断接口
中断计数+1,数据位移,低位 置0
地址储存 所有数据清零
错误,引导标志置0,时间置0, 中断置0
2 时间0 是否为0、1、2
中断计数 /时间清零
错误数据清零
void wrong() {
int_times = 0; tmr_times = 0; head_ok = 0; code_data = 0; lanth = 0; flagf = 0; }
LCD1602显示
void LCD1602_init(void) {
Delay1602(1500); //调用延时函数 LCD1602_Write_com(0x38); //8位数据总线,两行显示模式,5*7点阵显示 Delay1602(500); //调用延时函数 LCD1602_Write_com(0x38); //8位数据总线,两行显示模式,5*7点阵显示 Delay1602(500); //调用延时函数 LCD1602_Write_com(0x38); //8位数据总线,两行显示模式,5*7点阵显示 LCD1602_Write_com_busy(0x38); //8位数据总线,两行显示模式,5*7点阵显示 LCD1602_Write_com_busy(0x08); //显示功能关,无光标 LCD1602_Write_com_busy(0x01); //清屏 LCD1602_Write_com_busy(0x06); //写入新的数据后,光标右移,显示屏不移动 LCD1602_Write_com_busy(0x0C); //显示功能开,无光标 }
红外遥控编码原理及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)
基于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时,忙,等待。
c51单片机红外解码程序-汇编版和c语言版
纯软件解码---汇编版利用程序判电平和时间进行解码,缺点是浪费系统软件资源;优点是对系统硬件要求稍低ORG0000HT0ZDBIT20H.2XHBITP3.3;红外接收头数据接口RSBITP2.3RWBITP2.4EBITP2.5BBBITP3.6ORG0000H;AJMPMAINORG000BH;T0中断入口LJMPT0ZDCXORG0100H;主程序首地址MAIN:LCALLCSHMOVDPTR,#TAB;总查表SETBEA;T0中断设定SETBET0MOVTMOD,#01HDDXH:;信号接收前准备SETBP2.0;关信号指示灯MOVP0,#0FFHCLRTR0;关T0中断CLRT0ZD;接收信号时间判断MOVR5,#4;延时计数MOVTH0,#00HMOVTL0,#00H;================解码主要过程===========关键============================================================ JBXH,$;等待电平变低,解码从这开始CLRP2.0;开信号指示灯,表示正在接收信号MOVP0,#8EHSETBTR0;开T0中断LCALLYS3MSJBXH,DDXH;干扰检测LCALLYS3MSJBXH,DDXH;干扰检测DD1:JBT0ZD,DDXH;是否超出接收允许时间JNBXH,DD1;等待电平变高LCALLYS3MSJNBXH,DDXH;干扰检测DD2:JBT0ZD,DDXH;是否超出接收允许时间JBXH,DD2;等待电平变低JSSJ:;信号确认,开始接收数据MOVR0,#30HZJ:;接收一个字节数据MOVR2,#8WEI:;位数据,分辩0和1JBT0ZD,DDXH;是否超出接收允许时间JNBXH,WEI;等待电平变高LCALLYS845MOVC,XH;取位数据RRCADD3:JBT0ZD,DDXH;是否超出接收允许时间JBXH,DD3;等待电平变低,为1的高电平提供过度DJNZR2,WEI;8位数据是否接收完MOV@R0,AINCR0CJNER0,#34H,ZJ;四字节数据是否接收完MOVA,33HCPLACJNEA,32H,DDXH;键值确认,解码MOVR4,A;==========这里已经取出键值,存在R4中================================================== MOVR7,#100;TSY:MOVR6,#255DJNZR6,$CPLBBDJNZR7,TSYMOVA,#0CDH;键值高位输出LCALLYJP_XZLMOVA,R4MOVB,#10HDIVABMOVCA,@A+DPTR LCALLYJP_XSJMOVA,#0CEH;键值低位输出LCALLYJP_XZLMOVA,BMOVCA,@A+DPTR LCALLYJP_XSJ; LCALLDYBF;调用灯控制子程序LJMPDDXH;返还等待下一次信号YS845:;延时845微秒MOVR7,#255DJNZR7,$MOVR7,#165DJNZR7,$RETYS3MS:;延时3msMOVR7,#8DDD:MOVR6,#255DJNZR6,$DJNZR7,DDDRETT0ZDCX:;T0中断程序MOVTL0,#00HMOVTH0,#00HDJNZR5,T0FHSETBT0ZDT0FH:RETI;===============以下是多余部分=========================================================================== DYBF:MOVA,#0C0H;用号码前高位输出LCALLYJP_XZLMOVA,30HMOVB,#10HDIVABMOVCA,@A+DPTRLCALLYJP_XSJMOVA,#0C1H;用户码前低位输出LCALLYJP_XZLMOVA,BMOVCA,@A+DPTRLCALLYJP_XSJMOVA,#0C4H;用户码后高位输出LCALLYJP_XZLMOVA,31HMOVB,#10HDIVABMOVCA,@A+DPTRLCALLYJP_XSJMOVA,#0C5H;用户码后低位输出LCALLYJP_XZLMOVA,BMOVCA,@A+DPTRLCALLYJP_XSJ;============此处专门针对我的开发板和遥控,不是解码的关键,只是一种应用举例MOVA,R4CJNEA,#0CH,BA1;是否1号键按下CPLP1.0;点亮1号灯BA1:CJNEA,#18H,BA2;是否2号键按下CPLP1.1;点亮1号灯BA2:CJNEA,#5EH,BA3;是否3号键按下CPLP1.2;点亮1号灯BA3:CJNEA,#08H,BA4;是否4号键按下CPLP1.3;点亮1号灯BA4:CJNEA,#1CH,BA5;是否5号键按下CPLP1.4;点亮1号灯BA5:CJNEA,#5AH,BA6;是否6号键按下CPLP1.5;点亮1号灯BA6:CJNEA,#42H,BA7;是否7号键按下CPLP1.6;点亮1号灯BA7:CJNEA,#52H,BAB;是否8号键按下CPLP1.7;点亮1号灯BAB:RETCSH:;=============液晶初始化===============MOVA,#00111000B;8位数据,双行显示,5-7字型LCALLYJP_XZL;调用写液晶指令MOVA,#00001100B;显示屏开启,光标出现在地址计数器位置,光标不闪烁LCALLYJP_XZL;调用写液晶指令MOVA,#00000110B;光标右移一格,AC值加一,字符全部不动LCALLYJP_XZL;调用写液晶指令MOVA,#81H;LCALLYJP_XZLMOVA,#4CH;L的ASCII码LCALLYJP_XSJMOVA,#83H;LCALLYJP_XZLMOVA,#47H;G的ASCII码LCALLYJP_XSJMOVA,#85H;LCALLYJP_XZLMOVA,#58H;X的ASCII码LCALLYJP_XSJMOVA,#88H;LCALLYJP_XZLMOVA,#5AH;Z的ASCII码LCALLYJP_XSJMOVA,#89H;LCALLYJP_XZLLCALLYJP_XSJMOVA,#8AH; LCALLYJP_XZLMOVA,#69H;i的ASCII码LCALLYJP_XSJMOVA,#8CH; LCALLYJP_XZLMOVA,#5AH;Z的ASCII码LCALLYJP_XSJMOVA,#8DH; LCALLYJP_XZLMOVA,#61H;a的ASCII码LCALLYJP_XSJMOVA,#8EH; LCALLYJP_XZLMOVA,#6FH;o的ASCII码LCALLYJP_XSJMOVA,#0C2H; LCALLYJP_XZLMOVA,#48H;H的ASCII码LCALLYJP_XSJMOVA,#0C6H; LCALLYJP_XZLMOVA,#48H;H的ASCII码LCALLYJP_XSJMOVA,#0CAH; LCALLYJP_XZLLCALLYJP_XSJMOVA,#0CBH;LCALLYJP_XZLMOVA,#5AH;Z的ASCII码LCALLYJP_XSJMOVA,#0CCH;LCALLYJP_XZLMOVA,#3AH;:的ASCII码LCALLYJP_XSJMOVA,#0CFH;LCALLYJP_XZLMOVA,#48H;H的ASCII码LCALLYJP_XSJRET;=========写指令到液晶============= YJP_XZL:LCALLCHECK_BUSY;查询忙碌状态CLRECLRRSCLRRWSETBEMOVP0,A;写指令CLRERET;==========写数据到液晶============== YJP_XSJ:LCALLCHECK_BUSY;查询忙碌状态CLRESETBRSCLRRWSETBEMOVP0,A;写数据CLRERET;=========查询忙碌标志============CHECK_BUSY:PUSHACCBUSY_LOOP:CLRESETBRWCLRRSSETBEMOVA,P0;读取状态JBp0.7,BUSY_LOOPPOPACCLCALLDELRETDEL:MOVR6,#5L1:MOVR7,#248DJNZR7,$DJNZR6,L1RETTAB:DB30H,31H,32H,33H,34H,35H,36H,37H,38H,39H DB41H,42H,43H,44H,45H,46HEND中断加定时器---C语言版优点:完全是状态解码,极少的占用系统软件资源(CPU),随时都可以解码,而不管系统此时运行到何处。
自己写的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有没有下降沿。
NEC协议的红外遥控程序(任意IO口)
/**************************************************************************** NEC_INF_S.h用于NEC协议的遥控器与51单片机结合的驱动程序,可用任意IO口,不占用中断资源。
用户码8位,分布于2-17个脉冲;按键码8位,分布于18-33个脉冲。
皆为前8原码,后8反码,并且接收数据时低位在前,高位在后。
主控器为51单片机,晶振频率为11.0592MHz。
注意:由于未用中断,所以信号的接收是靠查询方式的,可能会漏掉若干次红外信号。
*****************************************************************************/ #include<reg52.h>#define uchar unsigned char#define uint unsigned int#define N 5000//用于在while()中循环时超时跳出的数的上限,可小刀sbit nec_dat=P3^3;//任意IO口,用到哪个自己改哪个uchar nec_id[2]={0};//遥控器的编码号,第一个为原码,第二个为反码uchar nec_data[2]={0};//遥控器的命令号,第一个为原码,第二个为反码uchar nec_status=0;//遥控器的按键状态信息。
0:无按键;1:一次按键;2:连续按键uchar nec_actflag=0;//用于带到主函数里的按键响应标志。
0:不动作;1:动作#ifndef NEC_INF_S_h#define NEC_INF_S_hvoid nec_init();//初始化函数,注意一定要拉高,拉低就错误了void nec_delay();//延时0.8ms左右,要求要非常精确,这是正确读数的关键void nec_pulsedat();//读第2到第32个脉冲,第一个脉冲已判定void nec_getdat();//扫描式读遥控器的数据,可能有时会扫描不到#endifvoid nec_init()//初始化函数,注意一定要拉高,拉低就错误了{nec_dat=1;}void nec_delay()//延时0.8ms左右,要求要非常精确,这是正确读数的关键{uchar i;for(i=0;i<245;i++);}/*void nec_act()//按键响应程序,根据自己需要写{nec_getdat();//先扫描一遍红外信号if(nec_actflag==1)//如果是正确的红外信号才处理,否则跳过{if(nec_data[0]==~nec_data[1])//验证所接收数据是否正确{switch(nec_data[0])//自己写所需要的程序段{case 69:/*点亮二极管,让蜂鸣器发声,什么都行,写在这里*/ break;case 70: /*以下都一样,对应的遥控器按键见图1-1*/ break;case 71: break;case 68:break;case 64:break;case 67:break;case 7:break;case 21:break;case 9:break;case 22:break;case 25:break;case 13:break;case 12:break;case 24:break;case 94:break;case 8:break;case 28:break;case 90:break;case 66:break;case 82:break;case 74:break;}}nec_actflag=0;}}*/void nec_pulsedat()//读第2到第32个脉冲,第一个脉冲已判定{uchar i=0;uint num=0;for(i=1;i<32;i++){num=0;while((nec_dat==0)&&(num<N))num++;nec_delay();{if((i>=1)&&(i<=7))nec_id[0]=nec_id[0]|(0x01<<i);if((i>=8)&&(i<=15))nec_id[1]=nec_id[1]|(0x01<<(i-8));if((i>=16)&&(i<=23))nec_data[0]=nec_data[0]|(0x01<<(i-16));if((i>=24)&&(i<=31))nec_data[1]=nec_data[1]|(0x01<<(i-24));num=0;while((nec_dat==1)&&(num<N))num++;}else{if((i>=1)&&(i<=7))nec_id[0]=nec_id[0]&(~(0x01<<i));if((i>=8)&&(i<=15))nec_id[1]=nec_id[1]&(~(0x01<<i-8));if((i>=16)&&(i<=23))nec_data[0]=nec_data[0]&(~(0x01<<i-16));if((i>=24)&&(i<=31))nec_data[1]=nec_data[1]&(~(0x01<<i-24));}}}void nec_getdat()//扫描式读遥控器的数据,可能有时会扫描不到{uint num=0;if(nec_dat==1){num=0;while((nec_dat==1)&&(num<N))num++;}nec_delay();if(nec_dat==0){nec_delay();if(nec_dat==0){nec_delay();if(nec_dat==0){nec_delay();if(nec_dat==0){nec_status=1;num=0;while((nec_dat==0)&&(num<N))num++;num=0;while((nec_dat==1)&&(num<N))num++;}}}}if(nec_status==1){num=0;while((nec_dat==0)&&(num<N))num++;if(nec_dat==1){nec_delay();nec_delay();nec_delay();if(nec_dat==1)nec_status=2;else{nec_id[0]=0x01;nec_pulsedat();}}else{nec_id[0]=0x00;nec_pulsedat();}nec_actflag=1;//一次按键的响应程序}if(nec_status==2){//持续按键的响应程序}nec_status=0;//必须归零,非常重要}图1-1 红外遥控器按键对应的接收码图1-2 本程序使用的遥控器注意:本程序适用于NEC协议的红外遥控器,但是每一款遥控器的按键码可能不同,需要自己找到自己手头上遥控器的按键码资料来对程序进行改动。
NEC格式红外发射C程序 C51
NEC格式红外发射C程序 C51nec格式红外发射c程序c51//**********************************************////**********nec格式红外遥控发射程序*************////*******************idwrok*******************////************* **20210315_zxq*******************////****20s-m-1s-40eb728d-3s-idwr(40ee6699)******////**********************************************//#inclu de#defineuintunsignedint#defineucharunsignedcharstaticbitopt;sbitir=p3^4;//sbi tkey=p1^7;staticuintcount;staticuintendcount;staticucharflag;staticucharsyscod e_h;staticucharsyscode_l;ucharir_bufdata[4];voidinit(void);voidsend_ir(ucharcustomcode);//voiddelay_ms(uintms);voiddelay_s(uchars);voidmain(void){init();delay_s(20);syscode_l=0xee;send_ir(0x01);delay_s(1);sysc ode_l=0xeb;send_ir(0x72);delay_s(3);syscode_l=0xee;send_ir(0x66);delay_s(17);w hile(1){delay_s(1);syscode_l=0xee;send_ir(0x67);}}//红外发射管的状态十一位0,1//红外升空端口//延时计数器//中止延时计数//红外传送标志//系统码点低8十一位//系统码点高8十一位//遥控代码放置缓冲区//升空数据码//ms延后子程序//s延后子程序//起始//等候开机//系统码设置//传送遥控代码m//系统码设置//传送遥控代码//系统码设置//传送遥控代码idwr//系统码设置//传送遥控代码led提示信息voidtimeint(void)interrupt1{th0=0xff;tl0=0xe6;count++;if(flag==1){opt=~opt;}else{opt=0;}ir=opt;}voidinit(void){count=0;flag=0;opt=0;ir=0;syscode_h=0x40;syscode_l=0xbf;ea=1;tm od=0x01;et0=1;th0=0xff;tl0=0xe6;tr0=1;}voidsend_ir(ucharcustomcode){uinti,j;ir_bufdata[0]=syscode_h;ir_bufdata[1]=sys code_l;ir_bufdata[2]=customcode;ir_bufdata[3]=~customcode;endcount=223;flag=1;count=0;//定时器0中断处理//26us中断一次,频率为38khz//cpu开总中断//设立定时器0为16十一位模式1//定时器0中断容许//26us中断一次频率为38khz//开始计数//syscode数据迁移至ir_bufdata[]内//发送9ms的起始码while(countendcount=117;//传送4.5ms的结果码flag=0;count=0;while(count>1;}}endcount=10;//每个代码传送完后的延时flag=1;count=0;while(countvoiddelay_ms(uintms)//ms延后子程序{for(;ms>0;ms--){flag=0;count=0;while(count<24);}}*/voiddelay_s(uchars){for(;s>0;s--){flag=0;count=0;while(count<27772);}}//1ms//s延后子程序//1s。
基于51单片机红外发射程序
基于51单片机红外发射程序#include "reg52.h"sbit ir=P2^0;//红外发射管控制脚,使用24M晶振sbit led = P2^1;sbit ka=P1^0;sbit kb=P1^1;sbit kc=P1^2;sbit kd=P1^3;unsigned int count, set_count; //中断计数,设定中断次数bit irflag,keyflag; //红外发送标志位,按键标志位unsigned char irsys[]={0x00,0xff};//16位用户码unsigned char irdata,ircode; //发送的红外数据//---------------------------------------------------------------------------void delay(unsigned int a)//延时约1ms,晶振24M ,此处延时不需很精确{unsigned char i;while(--a!=0)for(i=300;i>0;i--); //若是12M晶振i=125}//---------------------------------------------------------------------------void keyscan() // 按键扫描{if(ka==0){ delay(5);while(!ka);keyflag=1;irdata=0x0a;} //a键按下,则发射数据0x0aif(kb==0){ delay(5);while(!kb);keyflag=1;irdata=0x0b;} //a键按下,则发射数据0x0aif(kc==0){ delay(5);while(!kc);keyflag=1;irdata=0x0c;} //a键按下,则发射数据0x0aif(kd==0){ delay(5);while(!kd);keyflag=1;irdata=0x0d;} //a键按下,则发射数据0x0a}//---------------------------------------------------------------------------void ir_sendbyte() //红外发送一个字节数据{unsigned char i;for(i=0;i<8;i++) //发送8位数据{set_count=43;//35; //发送编码中的0.56ms高电平(//后为12M 晶振下的数值)irflag=1; //启动红外发射二极管发射count=0; //中断计数先清0TR0=1; //开启定时器0while(count<="">TR0=0; //关闭定时器0if(ircode&0x01) set_count=130;//130; //判断红外编码最低位,若为1则1.69ms的低电平(//后为12M晶振下的数值)else set_count=43;//35; //为0则0.565ms的低电平(//后为12M 晶振下的数值) irflag=0; //低电平则不发射count=0; //中断计数清0TR0=1; //开启定时器0while(count<="">TR0=0; //关闭定时器0ircode=ircode>>1; //将数据右移,即从低位到高位发送}}//---------------------------------------------------------------------------void ir_send() //发送红外数据{set_count=692;//672; //发送编码中的引导码(9ms高电平+4.5ms低电平) (//后为12M晶振下的数值) tc9012irflag=1; //启动红外发射二极管发射count=0; //中断计数清0TR0=1;while(count<set_count);< p="">TR0=0;set_count=346;//336; //发送编码中的4.5ms低电平(//后为12M晶振下的数值)irflag=0; //低电平则不发射count=0;TR0=1;while(count<="">TR0=0;ircode=irsys[0]; //发送16位用户码的前1-8位ir_sendbyte();ircode=irsys[1]; //发送16位用户码的前9-16位ir_sendbyte();ircode=irdata; //发送8位数据码ir_sendbyte();ircode=~irdata; //发送8位数据反码ir_sendbyte();set_count=43;//35; //发送编码中的0.56ms高电平(//后为12M 晶振下的数值)irflag=1;count=0;TR0=1;while(count<set_count);< p="">TR0=0;ir=1;delay(23); //延时23ms(编码中的23ms低电平)set_count=692;//670; //发送编码中的引导码(9ms高电平+4.5ms低电平) (//后为12M晶振下的数值)irflag=1;count=0;TR0=1;while(count<set_count);< p="">TR0=0;set_count=346;//336; //发送编码中的4.5ms低电平(//后为12M晶振下的数值)irflag=0;count=0;TR0=1;while(count<set_count);< p="">TR0=0;set_count=43;//35; //发送编码中的0.56ms高电平(//后为12M 晶振下的数值) irflag=1;count=0;TR0=1;while(count<set_count);< p="">TR0=0;ir=1; //发射完了关闭红外发射二极管}//---------------------------------------------------------------------------void timer0_init() //定时器初始化{EA=1;TMOD=0x02; //定时0 8位自动重装模式ET0=1;TH0=0xe6;//0xf3; //定时13us,38K红外矩形波,晶振24M (//后为12M晶振下的数值) TL0=0xe6;}//---------------------------------------------------------------------------void main(){timer0_init(); //定时0初始化count=0; //中断计数先清0irflag=0; //红外发射标志先置0while(1){keyscan(); //键值扫描if(keyflag) //若有按键按下{led = 0;delay(10);ir_send(); //发送红外编码delay(500);keyflag=0; //按键标志清零delay(100);}else{led = 1;}}}//---------------------------------------------------------------------------void timer0() interrupt 1 //定时器0中断{count++;if(irflag==1) ir=~ir; //有发射标志,则发射38khz的矩形波else ir=1; //否则不发射,即相当于发射编码中的低电平}</set_count);<></set_count);<></set_count);<></set_count);<></set_count);<>。
51单片机的红外收发C程序
{
while(--tt);
}
void main(void)
{
signalBit=0;
P2_2= 0;
设定定时器 TMOD=0x12;// 1 和 0 工作方式为 1 和 2
EX1=1;
定时器 中断允许 IT1=1;
ET0 =1; //
0
ET1 =1;
1
}
}
a[i]=temp; //将解码出的字节值储存在 a[i]
temp=0;
}
解码正确,返回 if(a[2]==~a[3])
return 1; //
1
else return 0;
}
/************************************************************
case 0x7d: SendIRdata(irData); break;
case 0xeb: SendIRdata(irData); break;
case 0xdb: SendIRdata(irData); break;
case 0xbb: SendIRdata(mazhi); break;
case 0x7b: SendIRdata(mazhi); break;
保存高电平宽度 HighTime=TH0*256+TL0; //
if((LowTime<300)||(LowTime>620))
if((HigrheTtuirmne0>;3/0/如0)果&&低(H电ig平hT长im度e<不6在20合)) /理/如范果围高,电则平认时为间出在错5,60停微止秒解左码右, 即计数 / = 560 1.085 516 次
51单片机红外发射程序
51单片机红外发射程序一定要用灌电流驱动,拉电流驱动最远遥控距离2米,改用灌电流之后,可以遥控6米,PK遥控板,通过中间串联一个3v电池之后,遥控距离达30米以上(亲测)。
#include ;#define uchar unsigned char#define uint unsigned intsbit IR_OUT=P1^0 ;void delay_ms(uint ms){uint i,j;for(i=0;i<120;i++){for(j=0;j<ms;j++);}}//T1 13us产生一次中断用于产生38K载波//T0 方式1 16位用于定时void Init_Timer(void){TMOD=0x21; //T0 mode 1T1 mode 2TH1=256-(1000*11.0592/38.0/12)/2+0.5;//特殊TL1=TH1;ET1=1;EA=1;}//发送引导码发送方:4.5ms高电平 4.5ms低电平void Send_Start_Bit(void)//TR1的值=发送的电平{//4.5ms 1TH0=(65536-8295)/256;TL0=(65536-8295)%256;TR0=1;TR1=1;while(!TF0);TR1=0;TF0=0;TR0=0;IR_OUT=1;//4.5ms 0TH0=(65536-4146)/256; TL0=(65536-4146)%256; TR0=1;TR1=0;while(!TF0);TR1=0;TF0=0;TR0=0;IR_OUT=1;}//发送0void Send_Bit_0(void) {//0.565ms 1TH0=(65536-521)/256; TL0=(65536-521)%256; TR0=1;TR1=1;while(!TF0);TR1=0;TF0=0;IR_OUT=1;//0.565ms 0TH0=(65536-521)/256; TL0=(65536-521)%256; TR0=1;TR1=0;while(!TF0);TR1=0;TF0=0;TR0=0;IR_OUT=1;}//发送1void Send_Bit_1(void) {//0.565ms 1TH0=(65536-521)/256; TL0=(65536-521)%256; TR0=1;TR1=1;while(!TF0);TF0=0;TR0=0;IR_OUT=1;//1.685ms 0TH0=(65536-1563)/256;TL0=(65536-1563)%256;TR0=1;TR1=0;while(!TF0);TR1=0;TF0=0;TR0=0;IR_OUT=1;}void Send_over(void)//发送一个结束码,因为最后一个位只有遇到下降沿才能读取(发射端的上升沿){//0.500ms 1//小于0.5ms 接收端很难识别到TH0=(65536-500)/256; TL0=(65536-500)%256; TR0=1;TR1=1;while(!TF0);TR1=0;TF0=0;TR0=0;IR_OUT=1;//0.500ms 0TH0=(65536-500)/256; TL0=(65536-500)%256; TR0=1;TR1=0;while(!TF0);TR1=0;TF0=0;TR0=0;IR_OUT=1;}//发送一字节 8位void Send_Char(){unsigned char i,j1,j2,j3,j4; j1=0xBE;j2=0x41;j3=0xDE;j4=0x20;Send_Start_Bit();Send_Bit_0();//发射引导吗for(i=0;i<8;i++){if(j1&0x80)Send_Bit_0();elseSend_Bit_1();j1=j1<<1;//先发射低位}for(i=0;i<8;i++){if(j2&0x80)Send_Bit_0();elseSend_Bit_1(); j2=j2<<1;//先发射低位}for(i=0;i<8;i++) {if(j3&0x80)Send_Bit_0(); elseSend_Bit_1(); j3=j3<<1;//先发射低位}for(i=0;i<8;i++) {if(j4&0x80)Send_Bit_0(); elseSend_Bit_1(); j4=j4<<1;//先发射低位}Send_over();//结束符}void T1_ISR(void) interrupt 3 {IR_OUT=!IR_OUT;}void main(void){Init_Timer();while(1){Send_Char();delay_ms(1000);}}。
51单片机的红外收发C程序_带仿真图
发射部分#include <reg52.h>sbit P2_2=P2^2;sbit signalBit=P2^1; //发送信号标志位sbit LED=P3^7; //使能信号位,将E位定义为P2.2引脚unsigned char irData[]={0x14,0xeb,0xf0,0x0f}; //存放所有的控制码unsigned char mazhi[]={0x33,0x22,0xeb,0x14};unsigned char key,send_flag=0;void SendIRdata(unsigned char irdata[4]); //红外发射函数void anjian_send(unsigned char flag);void delay(unsigned int tt) //延时函数{while(--tt);}void main(void){signalBit=0;P2_2= 0;TMOD=0x12;//设定定时器1和0工作方式为1和2EX1=1;IT1=1;ET0 =1; //定时器0中断允许ET1 =1;TH0= 0xf4;TL0= 0xf4; //设定时值0为38K 也就是每隔13us中断一次周期为26us TR0= 0;//先关闭定时器0TR1= 0;IP=0X01;EA=1; //允许CPU中断LED=0;while(1){P1=0XF0;if(send_flag==1){anjian_send(key);send_flag=0;}}}void anjian_send(unsigned char flag){unsigned char zhi=flag;switch(zhi){case 0xee: SendIRdata(irData); break;case 0xbe: SendIRdata(irData); break;case 0xde: SendIRdata(irData); break;case 0x7e: SendIRdata(irData); break;case 0xed: SendIRdata(irData); break;case 0xdd: SendIRdata(irData); break;case 0xbd: SendIRdata(irData); break;case 0x7d: SendIRdata(irData); break;case 0xeb: SendIRdata(irData); break;case 0xdb: SendIRdata(irData); break;case 0xbb: SendIRdata(mazhi); break;case 0x7b: SendIRdata(mazhi); break;case 0xe7: SendIRdata(mazhi); break;case 0xd7: SendIRdata(mazhi); break;case 0xb7: SendIRdata(mazhi); break;case 0x77: SendIRdata(mazhi); break;}}/******* 定时器1中断处理***********/void isr_T1(void) interrupt 3{}/******* 定时器0中断处理38K载波发生器***********/ void timeint(void) interrupt 1{P2_2=~P2_2; //产生38k的载波信号}/**************** 中断1 键盘的扫描********************/ void Int1(void) interrupt 2{unsigned char l,h;P1=0XF0;l=P1;l=l&0xf0;if(l!=0xf0){delay(10);if(l!=0xf0){l=P1&0xf0;l=l|0x0f;P1=l;h=P1;h=h&0x0f;l=l&0xf0;key=h+l;send_flag=1;LED=~LED;}}}/********* 红外发射函数************/void SendIRdata(unsigned char *mData){unsigned char i,j;unsigned char test[4];for(i=0;i<4;i++)test[i]=mData[i];TR0=1; //开定时器T0 输出38K载波/********* 发送9ms的高电平************/TH1=0XDF; //装入初值设置波延时为9msTL1=0XE3;TR1=1; //启动T1工作定时所需时间signalBit=1; //发送信号while(!TF1);TF1=0;/********* 发送4.5ms的低电平*************/TH1=0xef;TL1=0xf0;signalBit=0;while(!TF1);TF1=0;/********* 发送用户码控制码控制反码***********/for(j=0;j<4;j++)//发送十六位地址的前八位{for(i=0;i<8;i++){//先发送0.565ms的38KHZ红外波(即编码中0.565ms的高电平)TH1=0XFE;TL1=0X70;signalBit=1;while(!TF1);TF1=0;//停止发送红外信号(即编码中的高电平)if(test[j]&0x01) //判断二进制数个位为1还是0{TH1=0XFA; // //1为宽的低电平,持续时间1.685msTL1=0X30;}else{TH1=0XFE; //0为窄的低电平,持续时间0.56msTL1=0x50;}signalBit=0;while(!TF1);TF1=0;test[j]=test[j]>>1;}}TR1=0; //发送停止位关闭定时器T0signalBit=1;delay(100);signalBit=0;TR0=0; //关闭定时器T1}检测部分#include<reg52.h> //包含单片机寄存器的头文件#define uchar unsigned char#define uint unsigned intsbit IR=P3^2; //将IR位定义为P3.2引脚sbit rs=P2^4; //寄存器选择位,将RS位定义为P2.0引脚sbit rw=P2^5; //读写选择位,将RW位定义为P2.1引脚sbit e=P2^6; //使能信号位,将E位定义为P2.2引脚sbit LED=P2^0; //使能信号位,将E位定义为P2.2引脚unsigned char code string[ ]= "1602IR-CODE TEST";unsigned char code smg[]="code:";unsigned char code MA[]="0123456789ABCDEF";unsigned char a[4]; //储存用户码、用户反码与键数据码、键数据反码unsigned int LowTime,HighTime; //储存高、低电平的宽度0-65535void delay(unsigned int tt){while(--tt);}void w_cmd(unsigned char dd){rs=0;rw=0;e=0;P0=dd;delay(50);e=1;delay(50);e=0;}void w_dat(unsigned char dd){rs=1;rw=0;e=0;P0=dd;delay(50);e=1;delay(50);e=0;}void disp_ma(uchar *p,uchar hang,uchar wei){if(hang==1)w_cmd(0x80+wei);if(hang==2)w_cmd(0xc0+wei);while(*p!='\0'){w_dat(*p);p++;}}void init_LCD(void){w_cmd(0x38);delay(1000);w_cmd(0x38);delay(300);w_cmd(0x38);//注意顺序,设置工作方式,显示模式设置delay(300);w_cmd(0x08);//注意顺序,关闭显示w_cmd(0x01);//清屏w_cmd(0x06);//光标·画面滚动模式设置w_cmd(0x0c);//显示及光标模式设}/************************************************************函数功能:对4个字节的用户码和键数据码进行解码说明:解码正确,返回1,否则返回0出口参数:dat*************************************************************/bit DeCode(void){unsigned char i,j;unsigned char temp=0; //储存解码出的数据for(i=0;i<4;i++) //连续读取4个用户码和键数据码{for(j=0;j<8;j++) //每个码有8位数字{temp=temp>>1; //temp中的各数据位右移一位,因为先读出的是低位数据TH0=0; //定时器清0TL0=0; //定时器清0TR0=1; //开启定时器T0while(IR==0) ;//如果是低电平就等待低电平计时TR0=0; //关闭定时器T0LowTime=TH0*256+TL0; //保存低电平宽度TH0=0; //定时器清0TL0=0; //定时器清0TR0=1; //开启定时器T0while(IR==1); //如果是高电平就等待TR0=0; //关闭定时器T0HighTime=TH0*256+TL0; //保存高电平宽度if((LowTime<300)||(LowTime>620))return 0; //如果低电平长度不在合理范围,则认为出错,停止解码if((HighTime>300)&&(HighTime<620)) //如果高电平时间在560微秒左右,即计数560/1.085=516次{temp=temp&0x7f; //(520-100=420, 520+100=620),则该位是0}if((HighTime>1300)&&(HighTime<1850)) //如果高电平时间在1680微秒左右,即计数1680/1.085=1548次{temp=temp|0x80; //(1550-250=1300,1550+250=1800),则该位是1}}a[i]=temp; //将解码出的字节值储存在a[i]temp=0;}if(a[2]==~a[3])return 1; //解码正确,返回1else return 0;}/************************************************************函数功能:1602LCD显示*************************************************************/void Disp(void){w_cmd(0xc5); // 设置显示位置为第二行的第6个字w_dat(MA[(a[0]>>4)]);w_dat(MA[(a[0]&0x0f)]);w_dat(0x20);w_dat(MA[(a[1]>>4)]);w_dat(MA[(a[1]&0x0f)]);w_dat(0x20);w_dat(MA[(a[2]>>4)]);w_dat(MA[(a[2]&0x0f)]);w_dat(0x20);w_dat(MA[(a[3]>>4)]);w_dat(MA[(a[3]&0x0f)]);}/************************************************************函数功能:主函数*************************************************************/void main(){init_LCD(); //调用LCD初始化函数disp_ma(string,1,0);disp_ma(smg,2,0);EX0=1; //开外中断0ET0=1; //定时器T0中断允许IT0=1; //外中断的下降沿触发TMOD=0x01; //使用定时器T0的模式1TR0=0; //定时器T0关闭EA=1; //开启总中断while(1); //等待红外信号产生的中断}/************************************************************函数功能:红外线触发的外中断处理函数*************************************************************/void Int0(void) interrupt 0{EX0=0; //关闭外中断0,不再接收二次红外信号的中断,只解码当前红外信号TH0=0; //定时器T0的高8位清0TL0=0; //定时器T0的低8位清0TR0=1; //开启定时器T0while(IR==0); //如果是低电平就等待,给引导码低电平计时TR0=0; //关闭定时器T0LowTime=TH0*256+TL0; //保存低电平时间TH0=0; //定时器T0的高8位清0TL0=0; //定时器T0的低8位清0TR0=1; //开启定时器T0while(IR==1); //如果是高电平就等待,给引导码高电平计时TR0=0; //关闭定时器T0HighTime=TH0*256+TL0; //保存引导码的高电平长度if((LowTime>7500&&LowTime<10000)&&(HighTime>3500&&HighTime<5000)){//次数=9000us/1.085=8294, 判断区间:8300-500=7800,8300+500=8800.if(DeCode()==1) // 执行遥控解码功能Disp();//调用1602LCD显示函数}EX0=1; //开启外中断EX0}。
红外NEC编码发射程序_C语言
unsigned int temp; //temp扫描中介变量,用于keyscan()
/*---------------------------------------------
yindao()产生引导码:9ms载波+4.5ms无载波,载波占空比:1/3
c为a的反码,d为b的反码,发射顺序为:acbd,先发8位中的高位(这与解码对应)
---------------------------------------------*/
void NEC_emit(unsigned char a,unsigned char b)
{
void emit1();
{
unsigned char a;
for(a=0;a<=20;a++)
{
zaibo=0;
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
panduan01=a&0x08;
if(panduan01)emit1();
else emit0();
panduan01=a&0x10;
if(panduan01)emit1();
else emit0();
panduan01=a&0x20;
if(panduan01)emit1();
{
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
基于51单片机的红外遥控编码解码的C语言程序和电路
请勿转载!!!作品功能简介:当学习键按下后,红外接收头便可将接受到的信号存储到单片机中。
在接受到通用遥控器发出的信号后,如果按下发射键,单片机将调出刚刚储存的信息,通过红外发射头发射出和遥控器一样的信号来达到控制的作用。
#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit 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<t;i++)for(i=0;j<120;j++);}//初始化函数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;}//外中断0void 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。
NEC码红外遥控完整编码
红外遥控编码程序如下:NEC .SECTION 'DATA'a_REM_CODE DB ? ;KEY DATA CODEa_CUSTOMER_1 DB ? ;遥控器头码(客户码)低八位a_CUSTOMER_2 DB ? ;遥控器头码(客户码)高八位#define CUS_6221_1 00110100b ;1234H#define CUS_6221_2 00010010b;@------------------------------------------------NEC_CODE .SECTION 'CODE';@************* SUBROUTINE[xx]: Send Remote Code ************;;遥控码发送:SEND_REMOTE_CODE:clr WDT ;清除进位标志,检测遥控发送的有效的按键SZ fg_SendActive ;SZ表示以0结尾的字符串JMP READY_SEND ;跳转到READY_SEND模块retREADY_SEND:NEC_CODE:mov A,a_KEY_NUM ;将数值发送到寄存器A中,直接寻址mov M_TBLP,ATABRDL a_REM_CODE ;查表专用指令MOV A,CUS_6221_1 ;读取遥控头码(客户码)低八位数值MOV a_CUSTOMER_1,AMOV A,CUS_6221_2MOV a_CUSTOMER_2,A以上为READY_SEND运行模块,同时是为后面NEC码发送的准备;首先将一个按键的数值已以直接寻址方式发送到寄存器A中,将寄存器A的是发送到M_TBLP中,然后查表a_REM_CODE,将CUS_6221_1的值发送到寄存器中,在赋值给遥控器头码(客户码)低八位a_CUSTOMER_1,同理,将CUS_6221_2赋值给遥控器头码(客户码)低八位a_CUSTOMER_2,随后即开始发送NEC遥控码。
红外遥控编码原理及C程序,51单片机红外遥控
红外遥控解解码程序#include <reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intsbit lcden=P1^0;sbit rs=P1^2;sbit ir=P3^2;sbit led=P1^3;sbit led2=P3^7;unsigned int LowTime,HighTime,x;unsigned char a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;unsigned char flag;//中断进入标志位uchar z[4];uchar code table[]={"husidonghahahah"};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){//写液晶命令函数rs=0;lcden=0;P2=com;delay(3);lcden=1;delay(3);lcden=0;}void write_date(uchar date){//写液晶数据函数rs=1;lcden=0;P2=date;delay(3);lcden=1;delay(3);lcden=0;}void init_anjian() //初始化按键{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液晶初始化write_com(0x0c);write_com(0x06);write_com(0x01);write_com(0x80);for(num=0;num<14;num++)//写入液晶固定部分显示{write_date(table[num]);delay(3);}write_com(0x80+0x40);for(num=0;num<9;num++){write_date(table1[num]);delay(3);}}void write_dianya(uchar add,char date){//1602液晶刷新时分秒函数4为时,7为分,10为秒char shi,ge;shi=date%100/10;ge=date%10;write_com(0x80+0x40+add);write_date(0x30+shi);write_date(0x30+ge);}void dingshiqi() //定时器记高低电平时间{TH0=0; //定时器高八位置0TL0=0; //定时器低八位置0TR0=1; //开启定时器0while(ir==0); //如果是低电平就等待,给低电平计时TR0=0; //关闭定时器T0LowTime=TH0*256+TL0; //保存低电平时间TH0=0; //定时器高八位置0TL0=0; //定时器低八位置0TR0=1; //开启定时器0while(ir==1); //如果是高电平就等待,给引导码高电平计时TR0=0; //关闭定时器T0HighTime=TH0*256+TL0; //保存高电平长度}void main(){char i=0;TMOD=0x01; //定时器T0作为定时模式ET0=1; //开T0中断IT0=0; //外部中断,下降沿触发EX0=1; //开外部中断EA=1; //开总中断init_1602();while(1){}}void inter0() interrupt 0 //开始解码{EX0=0; //关闭外部中断0,不再接受红外信号,只解码当前的红外信号。
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。