c51红外遥控代码
51单片机红外解码资料+源代码
位地 8FH 8EH 8DH 8CH 8BH 8AH 89H 88H 址
源代码如下: #include<reg52.h> #define uchar unsigned char #define uint unsigned int sbit dula=P2^6; sbit wela=P2^7;
uchar irtime; //红外时间 uchar startflag; //启动接收 uchar irdata[33]; uchar bitnum; uchar irreceiveok; //红外接收完毕 uchar ircode[4]; uchar irprosok; uchar disp[8]; uchar code smg_du[]={
发射器发射的的信号为
接收器接收到的信号为
即 9ms 低电平后 4.5ms 高电平作为起始码,之后接受到两次 8 位客户码,一次八位数据码,和一次八位数据反码。
遥控器在按键按下之后周期性的发出同一种 32 位二进制编 码周期约为 108ms,一组码持续时间随本身的“0”“1”个数不同
而不同。大约在 45~63ms 之间,当一个键按下 36ms,振荡器使芯 片激活,将发射一组 108ms 的编码脉冲这 108ms 编码脉冲由一个 起始码(9ms),一个结束码(4.5ms),低八位地址码(9~18ms), 高八位地址码(9~18ms),八位数据码(9~18ms),和这八位数据 码反码(9~18ms),如果按下超过 108ms 仍未松开,接下来发射 的代码(连发代码)将仅有起始码(9ms)和结束码(2.5ms)组 成。
解码的关键是如何识别零和一: “0”和“1”都是以 0.56ms 低电平开始的,不同的是高电平 宽度不同,“0”为 0.56ms“1”为 1.168ms,所以必须根据高电平 宽度来区别“0”和“1”。 如果从 0.56ms 低电平过后,开始延时,0.56ms 后,若读到的 电平为低,说明该位为零,反之则为一,可靠其间,延时必须比 0.56ms'长一些,又不能超过 1.12ms,否则如果该位为零,读到的 已是下一位高电平,因此取(1.12+0.56)/2=0.84ms 最为可靠,一 般取 0.84ms 左右均可。根据码的格式,应该等待 9ms 起始码和 4.5ms 结束码完成后才能读码。 备注:定时器/计数器控制寄存器 TCON 位序 D7 D6 D5 D4 D3 D2 D1 D0 号 位符 TF1 TR1 TF0 IR0 IE1 IT1 IE0 IT0 号
c51、c52单片机红外线遥控接收解码c程序(可直接使用)
/ 亲,此程序以经过测试,可直接使用!!!/#include <reg51.h>#define uchar unsigned char#define uint unsigned intvoid delay(uchar x);sbit IRIN = P3^2;uchar IRCOM[4];void main(){ IE = 0x81;TCON = 0x01;IRIN=1;/* 此处可以根据按键码自由编写程序/以下为3*7遥控按键码//(也可以应用与其他类型遥控,本程序只以3*7遥控为例)/ / 0x45 0x46 0x47 // 0x44 0x40 0x43 // 0x07 0x15 0x09 // 0x16 0x19 0x0d // 0x0c 0x18 0x5e // 0x08 0x1c 0x5a // 0x42 0x52 0x4a /例如:while(1){switch(IRCOM[2]){case 0x45: P2=0x7f; break;case 0x44: P2=0xbf; break;case 0x07: P2=0xdf; break;case 0x16: P2=0xef; break;case 0x0c: P2=0xf7; break;case 0x08: P2=0xfb; break;case 0x42: P2=0xfd; break;case 0x52: P2=0xfe; break;case 0x4a: P2=0xff; break;case 0x5a: P2=0x00; break;}} */while(1);} //end main/**********************************************************/ void IR_IN(void) interrupt 0 //外部中断服务程序{unsigned char j,k,N=0;EX0 = 0;delay(15);if (IRIN==1){ EX0 =1;return;}//确认IR信号出现while (!IRIN) //等IR变为高电平,跳过9ms的前导低电平信号。
红外遥控编码原理及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)
学习型红外线遥控程序——C51
学习型红外线遥控程序——C51学习型红外线遥控程序——C51/*************晶体为11.0592M,波特率9600bps***************学习型红外线遥控程序*******/#include <AT89X51.H>void Ewen(void);void Ewds(void);void Delay(void);void Irda(void);void Study(void);void Output(unsigned int h);void Comput(unsigned char outdata);void Erase(unsigned char Address);unsigned int Read(unsigned char Address);unsigned char Display(unsigned char inAddress);void Write(unsigned char Address,unsigned int InData);unsigned int Both(unsigned char data1,unsigned char data2);unsigned char data e1 _at_ 0x1A; //分别存放红外线译码后的数据unsigned char data w1 _at_ 0x1B;unsigned char data e2 _at_ 0x1C;unsigned char data w2 _at_ 0x1D;sbit IrInput=P3^2; //红外线输入引脚,可自定义sbit Study1=P3^6; //学习按键,可自定义sbit Led2=P2^5; //接收成功、学习成功指示sbit Led1=P2^6; //空闲指示sbit Dout=P2^3; //at93c16--DOsbit Din=P2^2; //at93c16--DIsbit sk=P2^1; //at93c16--SKsbit cs=P2^0; //at93c16--CS/*********************主程序***************************/ void main(void){unsigned int i;SCON = 0x50; //串口方式1,允许接收TMOD = 0x20; //定时器1定时方式2TH1 = 0xFD; //波特率9600TL1 = 0xFD;IT0 = 1; //INT0下降沿有效EX0 = 1; //开INT0中断;TR1 = 1; //启动定时器P2_7=0; //初始化引脚P1=0xff;EA = 1; //允许CPU中断while(1){for (i=0; i<20000; i++){ Led1=1;if(!Study1) Study();}for (i=0; i<20000; i++){ Led1=0;if(!Study1) Study();}}}/***********************串口输出**********************/ void Comput(unsigned char outdata){SBUF = outdata;while(!TI);TI = 0;}/*******************红外线查询子程序*******************/ void Irda(void){#pragma asmMOV R6,#10SB:MOV R4,#19 ;延时880微秒D1:MOV R5,#19DJNZ R5,$DJNZ R4,D1JB P3.2,EXIT ;延时882微秒后判断P3.2脚是为1DJNZ R6, SB ;在8820微秒内如P3.2为1就退出JNB P3.2, $ ;等待高电平避开9毫秒低电平引导脉冲MOV R4,#10 ;延时4740微秒D2: MOV R5,#218DJNZ R5,$DJNZ R4,D2;延时4.74毫秒避开4.5毫秒的结果码MOV R1,#1AH ;设定1AH为起始RAM区MOV R2,#4 ;接收从1AH到1DH,用于存放操作码和操作反码PP:MOV R3,#8 ;每组数据为8位SS:JNB P3.2,$ ;等待地址码第一位的高电平信号MOV R4,#19 ;延时880微秒D5:MOV R5,#19DJNZ R5,$DJNZ R4,D5;高电平开始后882微秒判断信号的高低电平MOV C,P3.2 ;将P3.2引脚此时的电平状态0或1存入C中JNC TT ;如果为0就跳转到TTMOV R4,#2 ;延时1000微秒D6:MOV R5,#248DJNZ R5,$DJNZ R4,D6;检测到高电平1的话延时1毫秒等待脉冲高电平结束TT:MOV A,@R1 ;将R1中地址的给ARRC A ;将C中的值0或1移入A中的最低位MOV @R1,A ;DJNZ R3,SS ;接收满8位换一个内存INC R1 ;对R1中的值加1,换下一个RAMDJNZ R2,PP ;接收完所有数据EXIT:#pragma endasm}。
基于c51的红外解码源代码
#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单片机的红外线遥控接收程序(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单片机红外遥控解码,很详细(汇编语言,C语言等)
//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
STC单片机51简单的红外遥控发射程序C语言
}
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();}//结束位
C51单片机09(红外遥控)
P3.2(INT0)
采用脉宽调制的串行码波形
0.56ms
1.685ms
0.565ms
0.565ms
1.125ms
2.250ms
“0”
“1”
采用脉宽调制的串行码波形
0.5ms 0.5ms 0.56ms 0.5ms 0.5ms 0.5ms 0.5ms
1.685ms
“0”
0.565ms
“1”
0.565ms
采用脉宽调制的串行码波形
0.5ms 0.5ms 0.56ms 0.5ms 0.5ms 0.5ms 0.5ms
1.685ms
“0”
0.565ms
“1”
0.565ms
定时器中断T0发生, 定时器中断 发生,times=2 发生
采用脉宽调制的串行码波形
0.5ms 0.5ms 0.56ms 0.5ms 0.5ms 0.5ms 0.5ms
//LED显示红外解码 显示红外解码
小结
Thank you
D7 EA
D6
D5 ET2
D4 ES
D3 ET1
D2 EX1
D1 ET0
D0 EX0
定时/计数器控制寄存器 定时 计数器控制寄存器TCON 计数器控制寄存器
TF1——定时器T1溢出标志位 ——定时器 溢出标志位 ——定时器 TR1——定时器 启动位(= ,启动) ——定时器 启动位(= ——定时器T1启动位(=1,启动) TF0——定时器 溢出标志位 ——定时器 ——定时器T0溢出标志位 TR0——定时器 启动位(= ,启动) ——定时器 启动位(= ——定时器T0启动位(=1,启动) IE1——外部中断 请求标志位 ——外部中断 ——外部中断1请求标志位 IT1——外部中断 触发方式(= ,边沿触发) ——外部中断 触发方式(= ——外部中断1触发方式(=1,边沿触发) IE0——外部中断 请求标志位 ——外部中断 ——外部中断0请求标志位 IT0——外部中断0触发方式(=0,电平触发) ——外部中断 触发方式(= ,电平触发) ——外部中断 触发方式(= D7 TF1 D6 TR1 D5 TF0 D4 TR0 D3 IE1 D2 IT1 D1 IE0 D0 IT0
keilc51红外遥控解码程序
keilc51红外遥控解码程序keil c51红外遥控解码程序本keil c51程序适用uPC1621/uPC1622及兼容的红外遥控器芯片,占用外部中断0和定时器1,以中断方式解码,节省系统资源,以查询方式检测遥控信号是否有效.解码思路:红外线经一体化接受头解码放到后送到单片机的外部中断0,单片机设置外部中断下降沿触发,T0和T1为16位定时器,T0在系统启动后定时5ms.T1在外部中断0启动后开始定时,初值为0,每次在INT0中断后先读T1计数值,并重设初值为0,而且判断T1的计数值,18.unsigned char IR_repeat=0;19.unsigned char IR_ready=0;20.unsigned char IR_poweron=0;21.//bit ir_done=0;22.// time constants23.unsigned int IRtimer=0; // IR timeout24.25.//cpu初始化26.void cpu_init(void)27.{28.TMOD=0X11; // T0 and T1 十六位定时29.TH0=0xee; //fosc=11.0592M,timer=5ms30.TL0=0x00;31.TR0=1; // run timer 0;32.TF0=0;33.34.ET0=1; // enable tmr 0 overflow interrupt35.IT0=1; // int0 edge sensitive36.EX0=1; // enable "int0"37.EA=1; // global interupt enable38.}39.40.//T0中断41.void tmrint() interrupt 142.{43.TH0=0xee;44.TL0=0x00;45.if (IRtimer) //IR接收超时46.--IRtimer; //47.else48.{49.IRstate=IR_idle;50.// IR_poweron=0;51.}52.}53.54.//Fosc=11.0592MHz55.#define msec_12p5 0x2d0056.#define msec_15 0x360057.#define msec_9 0x206658.//#define msec_9 0x106659.#define msec_2p5 0x90060.#define msec_0p9 0x33d61.#define msec_1p68 0x61062.63.64.//void IRint() interrupt 0(void)65.66.//When the IR receive pin goes low and interrupt is ge nerated67.// IR is collected by starting timer 2 in the first falling edge of the pin68.// then on every other falling edge, the timer value i s saved and the timer restarted .69.// the captured time is then used to get the IR data70.// a "start of data" is 13.5Msec,a "1" is 2.25Msec,a "0" i s 1.12 msec and a "repeat" is 11.25msec.71.// the counter increments at 1.085 Usec72.// I allow a fairly large tolerance to time jitter but there are no false triggers seen.73.74.void IRint() interrupt 075.{76.static unsigned char bits;77.unsigned short time;78.switch(IRstate)79.{80.case IR_idle:81.TL1=0;82.TH1=0;83.TR1=1;84.IRstate=IR_waitstart;85.IRtimer=26;86.break;87.case IR_waitstart: //P2_4=!P2_4;88.TR1=0;89.time=TH1;90.time =(time <<8)+TL1;;91.TL1=0;92.TH1=0;93.TR1=1;94.if ((time > msec_12p5)&&(time < msec_15)) // greate r than 12.5Msec & less than 15 msec = start code95.{96.IRaddr=0;97._IRaddr=0;98.IRdata=0;99._IRdata=0;100.bits=1;101.IRstate=IR_getaddr;102.}103.else if ((time > msec_9)&&(time < msec_12p5))// les s than 12.5Msec and greater than 9 msec =Repeat code 104.{105.IR_repeat=2;106.IRstate=IR_idle;107.}108.else109.{ // to short, bad data just go to idle110.IRstate=IR_idle;111.}112.break;113.case IR_getaddr: // P2_4=!P2_4;114.TR1=0;115.time=TH1;116.time =(time <<8)+TL1;;117.TL1=0;118.TH1=0;119.TR1=1;120.if ((time>msec_2p5)||(time<msec_0p9))// if > 2.5mse c or shorter than .9Msec bad data , go to idle121.{122.IRstate=IR_idle;123.break;124.}125.if (time>msec_1p68)// greater than 1.68Msec is a 1126.{127.IRaddr|= bits;128.}129.bits=bits<<1;130.if (!bits)131.{132.IRstate=IR_getaddrinv;133.bits=1;134.}135.break;136.case IR_getaddrinv: //P2_4=!P2_4;137.TR1=0;138.time=TH1;139.time =(time <<8)+TL1;;140.TL1=0;141.TH1=0;142.TR1=1;143.if ((time>msec_2p5)||(time<msec_0p9))// if > 2.5mse c or shorter than .9Msec bad data , go to idle144.{145.IRstate=IR_idle;146.break;147.}148.if (time>msec_1p68)// greater than 1.68Msec is a 1 149.{150._IRaddr|= bits;151.}152.bits=bits<<1;153.if (!bits)154.{155.IRstate=IR_getdata;;156.bits=1;157.}158.break;159.case IR_getdata:160.TR1=0;161.time=TH1;162.time =(time <<8)+TL1;;163.TL1=0;164.TH1=0;165.TR1=1;166.if ((time>msec_2p5)||(time<msec_0p9))// if > 2.5mse c or shorter than .9Msec bad data , go to idle167.{168.IRstate=IR_idle;169.break;170.}171.if (time>msec_1p68)// greater than 1.68Msec is a 1172.{173.IRdata|= bits;174.}175.bits=bits<<1;176.if (!bits)177.{178.IRstate=IR_getdatainv;179.bits=1;180.}181.break;182.case IR_getdatainv:183.TR1=0;184.time=TH1;185.time =(time <<8)+TL1;;186.TL1=0;187.TH1=0;188.TR1=1;189.if ((time>msec_2p5)||(time<msec_0p9)) // if > 2.5mse c or shorter than .9Msec bad data , go to idle190.{191.IRstate=IR_idle;192.break;193.}194.if (time>msec_1p68)// greater than 1.68Msec is a 1 195.{196._IRdata|= bits;197.}198.bits=bits<<1;199.if (!bits) // we have it all , now we make sure it i s a NEC code from the CHS IR transmitter200.{ // make sure address,~address are correc t , data ,~data are correct and address is 0.201.IR_ready=((IRaddr^_IRaddr)==0xff)&&((IRdata^_IRda ta)==0xff)&&(IRaddr==0);202.if(IR_ready)203.{204.IRstate=IR_idle;205.}206.}207.break;208.default:209.IRstate=IR_idle;210.break;211.}212.}213.214.void main(void) 215.{216.cpu_init();217.while(1)218.{219.if(IR_ready)220.{221.IR_ready=0;222.switch(IRdata) 223.{224.case 0x45: //1 225.//your code226.break;227.case 0x44: //3 228.//your code229.break;230.case 0x43: //4 231.//your code232.break;233.case 0x08: //prev 234.//your code235.break;236.case 0x5a: //next 237.//your code238.break;239.default:240.break;241.&n bsp; } 242.}243.}。
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 次
c51学习型红外遥控器程序
c51学习型红外遥控器程序#include; //装入AT89X51头文件#include;//装入红外解码程序#include;//装入24c02读写程序sbit key=P1^0;//定义按键IOsbit led=P0^0; //定义指示ledsbit rel=P0^1;//定义输出控制脚unsigned char kaver; //定义kaver为输出口状态缓存unsigned char iccdate,irdate; //定义24c02数据和解码数据//延时10ms函数,用于开关消抖等delay10ms(){unsigned char i,j;for(i=20;i>;0;i--)for(j=248;j>;0;j--);}//学习红外解码并写入24c02的函数study(){IR_IN();irdate=IRCOM[3];iccdate=ReadIIC(W_cmd,0x00,R_cmd);if(irdate!=iccdate) //只在解码结果与读取结果不同时写入24C02{if(irdate!=0)//防止没有接收到红外信号,IRCOM[3]置零时,误写入0{WP=0;WriIIC(W_cmd,0x00,irdate);delay10ms();WP=1;led=0;while(key==0);//学习成功等待按键释放,led停止闪动作为指示}}}//进入学习状态时的led闪动函数flash(){unsigned char i;while(key==0){led=~led;for(i=50;i>;0;i--)study();}}//按键模式识别函数keymod(){unsigned char m=0;while(key==0) //如果按键按下,开始对按键时间进行计数{delay10ms();//计数时间延时m++;delay10ms();//计数时间延时if(m>;=90)//如果计数次数大于90次,等于按键按下时间大于约5秒后,进入led闪动学习模式{m=0;flash();}}if(m。
51单片机红外遥控格力空调程序文件
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();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++) 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)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))f=1;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;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(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();}}。
51单片机红外接收解码程序C51
51单片机红外接收解码程序(C51)接收以S52单片机作为接收系统。
以S52的P3.3口作为接收端口,该端口是外部中断1。
这个接受程序是以XC866作为红外发送控制系统,接收程序如下:#include; //头文件#include;#define uchar unsigned char //宏定义#define uint unsigned intsbit HWRx=P3^3; //位声明code uchar Table[]= //共阴数码管 0-9 a-f - 表{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6 f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40};uchar Table_Data[8]={0,0,0,0,0,0,0,0};//用于显示的数组uchar Table_Rx[67];//用于存储判断接收是1或0的参数void Delay();//延时子函数void Display(uchar *lp,uchar lc)//显示{uchar i; //定义变量P2=0; //端口2为输出,关闭P1=P1&0xF8; //将P1口的前3位输出0,对应138译门输入脚,全0为第一位数码管for(i=0;i;0x7f)P2+=0x80;Delay(); //延时P2=0; //清0端口,准备显示下位if(i==7) //检测显示完8位否,完成直接退出,不让P1口再加1,否则进位影响到第四位数据break;P1++; //点亮下一位数码管}}void main() //主函数{EA=1; //首先开启总中断EX1=1; //开启外部中断 1IT1=1; //设置成下降沿触发方式while(1) //一直显示,其它由中断处理{Display(Table_Data,8);}}void Delay() //延时时间大约为31us,晶振12M {uchar i=13;while(i)i--;}void Delay_ms(uint z) //延时时间约为 1ms*X 晶振为12M{uint x=0,y=0;for(x=z;x>;0;x--)for(y=54;y>;0;y--);}void hongwai() interrupt 2 //外部中断 1 ,INT1(P3^3)连接红外线接收IC数据脚{uchar i,j,tmp;EX1=0; //关闭中断j=33; //传送一组数包括引导码1位,4个八位数据,总共33位i=0; //从第一维数组开始Delay_ms(10);if(HWRx){ //然后再检测红线接收脚是有数据招收,有继续,没有则退出EX1=1;return;}while(j--){ //循环接收33位数据,为何我们用到66位数组,我们可以不接收高电平时间常数,只接低电平常数就//可以判断1或0了,在这里我们都接收,还有一点要知道,接收波形是反向,在没有接收时端口为高电平tmp=0;Table_Rx[i]=1; //时间量从1开始while(!HWRx) //检测高低电平的变化,这里检测的是高电平{Table_Rx[i]++; //没变继续加1Delay(); //家一个延时防止,计数值一下子就加满了tmp++; //加1if(tmp==250)break;}i++;tmp=0;Table_Rx[i]=1; //时间量从1开始while(HWRx) //检测高低电平的变化,这里检测的是低电平{Table_Rx[i]++; //没变继续加1Delay(); //同上tmp++; //加1,用于判断是1还是0的,低电平来了if(tmp==250)break;}i++;}P1=0xf8;i=200; //加入循环延时,抗干扰while(i) //在有接收数据的时候显示一个H{tmp=255;while(tmp){tmp--;P2=0x76;}i--;}tmp=0;for(i=3;i;>;=1; //右移一位,接收低位在前if(Table_Rx[i]>;30) //检测低电平时间超过30就确认为1tmp+=0x80;}Table_Data[0]=tmp/16; //分开2位以16进制显示,用显示发送的数据Table_Data[1]=tmp%16;tmp=0;for(i=19;i;>;=1;if(Table_Rx[i]>;30)tmp+=0x80;}Table_Data[2]=tmp/16;Table_Data[3]=tmp%16;tmp=0;for(i=35;i;>;=1;if(Table_Rx[i]>;30)tmp+=0x80;}Table_Data[4]=tmp/16;Table_Data[5]=tmp%16;tmp=0;for(i=51;i;>;=1;if(Table_Rx[i]>;30)tmp+=0x80;}Table_Data[6]=tmp/16;Table_Data[7]=tmp%16;EX1=1; //刚进中断时关闭了分控,现在要打开}。
红外循迹c51程序
#inclu de<re g52.h>#de fineuintunsig ned i nt#defin e uch ar un signe d cha ruin t i,t;lon g cou nter;//编码器脉冲数值u charfinis h=0;//停车标志//--------传感器变量------------s bit r i1=P0^0; //*左边传感器*//sbit ri2=P0^1;sbit ri3=P0^2;sbit mid=P0^3;//*中间传感器*//sbi t le3=P0^4;sbi t le2=P0^5;sbi t le1=P0^6;//*右边传感器*//sb it bz=P2^7;//蔽障管//-------电机舵机控制变量-----------sbit ENA=P1^0; //驱动电机pwm//sb it mo to1=P1^1;//电机控制//s bit m oto2=P1^2;sbit PWM=P1^4; //舵机pwm////---------转角变量---------uint angl e;ui nt ab solut e(int);//--------速度变量----------ui nt pr o; //驱动电机调速uin t car_driv er; //驱动力参数ui nt pu lse_s peed; //电机当前速度uintideal_spee d; //理想状态下的速度i nt sp eed_e rror; //理想速度与当前速度的差值intpre_e rror=0; //PID控制的速度差值intpre_d_erro r=0;//PID控制的速度上一次的差值int pk=0,erro r=0;//速度的PID值int s peedm ax;//----------表格值----------uintcodespeed_tabl e[]={50,40,40};uint code angl e_tab le[]={110,75,110};#defin e kp213#defin e ki7#de finekd 15//-----------函数定义-------void init();v oid d elay(uint);voi d qct yp();void duoj i();voidcarpo sitio n();voidspeed();v oid p id();//=============主函数==========voidmain(){init();while(1){q ctyp();carp ositi on();sp eed();}}//===========子函数============//-----------初始化-----------voi d ini t(){TMO D=0x11;//设定双定时器EA=1;//EX0=1;//开外部中断0// T CON=0x01;TR0=1;T R1=1;TH0=(65536-20000)/256;TL0=(65536-20000)%256;//设定定时初始值,可去下载个定时器计算软件,20m sTH1=(65536-1000)/256;TL1=(65536-1000)%256;E T0=1;ET1=1;ENA=1;pu lse_s peed=0;s peedm ax=0;}//---------延时函数----------v oid d elay(uintn){ucha r a,b,c;for(c=1;c>0;c--)f or(b=n;b>0;b--)f or(a=2;a>0;a--);}//-------光电管全无状态时(脱离轨道),读取前次状态---------voidqctyp(){ri1=P0^0;r i2=P0^1;ri3=P0^2;mid=P0^3;le3=P0^4;l e2=P0^5;le1=P0^6;}//-------循迹函数,读取光电管状态------------vo id ca rposi tion(){if(!le1&&!le2&&!le3&&mid&&!ri3&&!r i2&&!ri1){angle=0;}el se if(le3&&!mid&&!ri3&&!r i2&&!ri1){angle=1;}el se if(le2&&!mid&&!ri3&&!r i2&&!ri1){angle=1;}el se if(le1&&!mid&&!ri3&&!r i2&&!ri1){angle=1;}el se if(ri1&&!mid&&!le3&&!l e2&&!le1){angle=2;}el se if(ri2&&!mid&&!le3&&!l e2&&!le1){angle=2;}el se if(ri3&&!mid&&!le3&&!l e2&&!le1){angle=2;}}//-----------舵机控制-------------void duoj i() //舵机控制{P WM=1;del ay(an gle_t able[angle]); //可改变舵机转向角度PW M=0;}//-----------------计算车的速度-----------------voi d spe ed(){ /*if(speed max<=pulse_spee d) speed max=p ulse_speed;if(sp eedma x>=40) s peedm ax=40;pi d();pro=car_d river;//变量y是改变小车速度这里范围是0--39*/p ro=sp eed_t able[angle];m oto1=1;m oto2=0; }//------------PID控制----------------/*void pid(){signe d int d_e rror, dd_e rror; //e rror=speed_erro rid eal_s peed=speed_tabl e[ang le];erro r=ide al_sp eed-p ulse_speed;d_error=erro r-pre_erro r; //d_er ror 当前速度差与上一次速度差之差dd_er ror=d_erro r-pre_d_er ror;pre_error=erro r; //存储当前偏差pre_d_err or=d_error;pk+=kp*d_err or+ki*erro r+kd*dd_er ror;if(p k<=0)p k=0;else if(p k>=40) pk=40;car_drive r=pk;}//-----------中断---------------voi d ext er0() inte rrupt 0{coun ter++;}*/vo id ti mer0() int errup t 1//产生pwm信号控制舵机,周期20ms{TH0=(65536-20000)/256;//1011 0001 即TH O=(65536-20000)/256TL0=(65536-20000)%256; //1110 0000即TLO=(65536-20000)%256duoji();}void time r1()inter rupt3//产生pwm信号控制驱动电机速度{TH1=(65536-1000)/256;TL1=(65536-1000)%256;i++;i f(i<=pro){ ENA=1;}el se{EN A=0;}i f(i==50){E NA=~E NA;i=0;}/* t++;if(t==1000){t=0;pul se_sp eed=4*coun ter/500; //速度=编码器主动轮周长(M)*脉冲/分辨率coun ter=0;} */}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
EA=1;
EX0=1;
TCON=0x01;
}
void scan()interrupt 0
{
uint i,ti,lo,t=0;
uchar user=0,datai=0;
signal=1;
EX0=0;
for(lo=0;lo<36;lo++)
{
ti=0;
do
{
t=0;
js=1;
while(js)
{
t++;
{
if(key==hwc[i])
key=i;
}
if(t!=0)
signal=1;
EX0=1;
}
本程序只适用于本图所显示的遥控器以及stc12c5a60s2的单片机并且晶振是11.0592M的:
使用方法:
软件上将下列.c和.h加入c51工程,在主程序运行前加入红外初始化ini_hw()函数,然后运行程序的时候,如果signal=1,代表接收到按下的按键,用完后注意清零。读key就是红外按键的值(1,2,3······代表按键依次的按键值),读kr就是按键的键值。
_nop_();
for(i=0;i<80;i++)
_nop_();
if(t==255)
{
if(lo==0)
signal=0;
break;
}
if(!signal)
break;
}
if(t==255)
ti++;
if(ti==3)
break;
}while(t==255||t==0);
if(!signal)
break;
uchar pdata a[I*10],b[40],c[12]={0,128,64,32,16,8,4,2,1,0,0,0};
uchar code hwc[]={104,48,24,122,16,56,90,66,74,82,152,176,224,168,144};
void ini_hw()//中断初始化
if(signal)
{
if(t<=7)
a[lo]=0;
else if(t>7&&t<=20)
a[lo]=1;
else
a[lo
{
lo=0;
user=0;datai=0;
for(i=0;i<36;i++)
{
if(user==0&&datai==8)
{
for(;datai;lo++,datai--,i++)
extern uint signal;//当按键检测到时,signal值是1
extern uchar pdata b[40];
extern void ini_hw();
#endif
下面是.c文件
#include"hwcl.h"//红外处理,用于处理红外键值
uint signal;
uint key=0,kr=0;
{
b[lo]=a[i];
}
signal=0;
}
if(signal)
{
if(a[i]==0)
{
datai=0;
user++;
}
if(a[i]==1)
{
user=0;
datai++;
}
}
}
for(i=1,t=0;i<=8;i++)
{
t=t+c[b[i-1]*i];
}
key=t;
kr=key;
}
for(i=0;i<15;i++)
#ifndef uchar
#define uchar unsigned char
#endif
#ifndef uint
#define uint unsigned int
#endif
extern uint key,kr;//key和kr都是键值,但kr是红外码二进制转换过来的,而key是处理过的键值变成如1,2,3
硬件上,把接收头的put接单片机的外部中断的P3^2上。
下面是.h文件
#ifndef _hwcl_h_//红外处理,用于处理红外键值
#define _hwcl_h_
#include<STC12C5A60S2.H>
#include<intrins.h>
#define I 10
sbit js=P3^2;