51单片机红外接收解码程序(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的前导低电平信号。
51单片机红外遥控程序
unsigned long m,Tc;
unsigned char IrOK;
void delay(uchar i)
{
uchar j,k;
for(j=i;j>0;j--)
for(k=125;k>0;k--);
}
void display()
{
dula=0;
P0=table[show[0]];
MOV R7,#202
DELAY882_A
NOP
NOP
DJNZ R7,DELAY882_A
RET
;=============================1000
DELAY1000 ;1.085x ((229x4)+5)=999.285
MOV R7,#229
DELAY1000_A
NOP
NOP
DJNZ R7,DELAY1000_A
Qq:735491739
红外遥控发射芯片采用PPM编码方式,当发射器按键按下后,将发射一组108ms的编码脉冲。遥控编码脉冲由前导码、8位用户码、8位用户码的反码、8位操作码以及8位操作码的反码组成。通过对用户码的检验,每个遥控器只能控制一个设备动作,这样可以有效地防止多个设备之间的干扰。编码后面还要有编码的反码,用来检验编码接收的正确性,防止误操作,增强系统的可靠性。前导码是一个遥控码的起始部分,由一个9ms的低电平(起始码)和一个4. 5ms的高电平(结果码)组成,作为接受数据的准备脉冲。以脉宽为0. 56ms、周期为1. 12ms的组合表示二进制的“0”;以脉宽为1. 68ms、周期为2. 24ms的组合表示二进制的“1”。如果按键按下超过108ms仍未松开,接下来发射的代码(连发代码)将仅由起始码(9ms)和结束码(2. 5ms)组成。
51单片机红外遥控解码程序
51单片机红外遥控解码程序类别:单片机/DSP 阅读:2975编者按:以下是网友编写的遥控解码程序!一种用延时等待的解码方法,比较容易理解,但缺点是占用CPU运行时间,第二种方法用定时器和外中断的解码方法,初学不易理解,但优点也很明显,第二种方法如果能解决连发解码就比较完美,更完善的红外遥控解码程序,请参考本站TOPA V-2008,TOP51-2005所配程序。
解码方法一;//单片机接收红外解读程序\\;硬件结构:8951,P0口数码管段码,P2.0-P2.3为位,P1为8个LED;P3.2为红外接收头,P2.7蜂鸣器,晶振12M;适用UPD6121 6122芯片接收;---------------------------------------------------------ORG 0000HAJMP MAIN ;转入主程序ORG 0003H ;外部中断P3.2脚INT0入口地址AJMP INT ;转入外部中断服务子程序(解码程序);以下为主程序进行CPU中断方式设置MAIN: SETB EA ;打开CPU总中断请求SETB IT0 ;设定INT0的触发方式为脉冲下降沿触发SETB EX0 ;打开INT0中断请求AJMP $;以下为进入P3.2脚外部中断子程序,也就是解码程序INT: CLR EA ;暂时关闭CPU的所有中断请求MOV R6,#10SB: ACALL YS1 ;调用882微秒延时子程序JB P3.2,EXIT ;延时882微秒后判断P3.2脚是否出现高; 电平如果有就退出解码程序DJNZ R6, SB ;重复10次,目的是检测在8820微秒内;如果出现高电平就退出解码程序;以上完成对遥控信号的9000微秒的初始低电平信号的识别。
JNB P3.2, $ ;等待高电平避开9毫秒低电平引导脉冲ACALL YS2 ;延时4.74毫秒避开4.5毫秒的结果码MOV R1,#1AH ;设定1AH为起始RAM区MOV R2,#4;PP: MOV R3,#8JJJJ: JNB P3.2,$ ;等待地址码第一位的高电平信号LCALL YS1 ;高电平开始后用882微秒的时间尺去判断信;号此时的高低电平状态MOV C,P3.2 ;将P3.2引脚此时的电平状态0或1存入C中JNC UUU ;如果为0就跳转到UUULCALL YS3;UUU: MOV A,@R1 ;将R1中地址的给ARRC A ;将C中的值0或1移入A中的最低位MOV @R1,A ;将A中的数暂时存放在R1中DJNZ R3,JJJJ ;接收地址码的高8位INC R1 ;对R1中的值加1,换下一个RAMDJNZ R2,PP ;接收完16位地址码和8位数据码和8位数据反; 码,存放在1AH/1BH/1CH/1DH的RAM中MOV A,1CH ;比较数据码和数据反码是否正确?CPL AXRL A,1DH ;将1CH的值取反后和1DH比较不同则无效丢弃,核对数据是否准确JNZ EXITMOV DPTR,#TAB ;表头地址送指针MOV A,1DHANL A,#0FH ;相与,得到低四位码MOVC A,@A+DPTRMOV 1EH,A ;查表得表码存入1EHMOV A,1DHSWAP AANL A,#0FHMOVC A,@A+DPTRMOV 1FH,A ;查表得高四位码存入1FMOV R7,#20HDISP:MOV P0,1FH ;送数码管显示CLR P2.1ACALL YS2SETB P2.1MOV P0,1EHCLR P2.2ACALL YS2SETB P2.2MOV P1,1DH ;将按键的键值通过P1口的8个LED显示出来!CLR P2.7 ;蜂鸣器鸣响-嘀嘀嘀-的声音,表示解码成功LCALL YS2SETB P2.7 ;蜂鸣器停止DJNZ R7,DISPEXIT: SETB EA ;允许中断RETI ;退出解码子程序YS1: MOV R4,#20 ;延时子程序1,精确延时882微秒D1: MOV R5,#20DJNZ R5,$DJNZ R4,D1RETYS2: MOV R4,#10 ;延时子程序2,精确延时4740微秒D2: MOV R5,#235DJNZ R5,$DJNZ R4,D2RETYS3: MOV R4,#2 ;延时程序3,精确延时1000微秒D3:MOV R5,#248DJNZ R5,$DJNZ R4,D3RETTAB: DB 0C0H,0DEH,0A2H,8AH,9CH,89H,81H,0DAH,80H,88H,90H,85H,0E1H,86H,0A1H,0B1H;数据表,0-9-A-FEND解码方法二你的解码程序和我现在用的解码程序大体是一样的,我自己实际做了一下,发现按下遥控器,接收到红外信号后,数码管闪的厉害。
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
红外解码 程序 c51
#include<reg52.h>unsigned char finish;//解码标志位unsigned char address1,address2,data1,data2;//地址位,反地址位,数据位,反数据位unsigned char tt[32];//32位码unsigned char d[9];//数据缓冲sbit P32=P3^2;/**********************Modbus通讯**************************/unsigned char code auchCRCHi[] = {0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40} ;/* CRC低位字节值表*/unsigned char code auchCRCLo[] = {0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,0x43, 0x83, 0x41, 0x81, 0x80, 0x40} ;unsigned char code Re_code[10]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39}; #define Time_L 0x00 // 定时器初始值11.0592M 定时10ms 初始值#define Time_H 0xDCsbit DE = P3^4; //?sbit DEF = P3^5;//?unsigned char Address;unsigned char Buf[20]; // 接收缓存区unsigned char xdata Sbuf[20]; // 发送缓存区unsigned short receive_count = 0; // 接收计数union Check //定义地址共用体把CRC校验码高位和低位分开{ // CRC.Chdata[0]为低位CRC.Chdata[1]为高位unsigned int CRCdata;unsigned char Chdata[2]; // [0] 为高位[1] 为低位} CRC;unsigned short CRC16(unsigned char *puchMsg,unsigned short usDataLen){//unsigned char *puchMsg ; /* 要进行CRC校验的消息*///unsigned short usDataLen ; /* 消息中字节数*/unsigned char uchCRCHi = 0xFF ; /* 高CRC字节初始化*/unsigned char uchCRCLo = 0xFF ; /* 低CRC 字节初始化*/unsigned uIndex ; /* CRC循环中的索引*/while (usDataLen--) /* 传输消息缓冲区*/{uIndex = uchCRCHi ^ *puchMsg++ ; /* 计算CRC */uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex];uchCRCLo = auchCRCLo[uIndex] ;}return (uchCRCHi << 8 | uchCRCLo) ;}void System_Init(){TMOD=0x20; // 串口初始化9600 None 8 1(11.0592MHZ)SCON = 0x50;ES=1;TH1=0xFD;TL1=0xFD;TR1=1;TMOD=0x21;TH0=0;TL0=0;EX0=1; //开外部中断0//ET0=1;IT0=1;//下降沿产生中断// EA=1;TR0=0;//定时器0关闭// TMOD=TMOD&0xf0; //定时器初始化// TMOD=TMOD|0x01;// TH0=Time_H;// TL0=Time_L;// ET0=1; //允许定时器中断DE = 0;Address = 0xFF; // Set AdrressEA=1; // allowed interrupt}void Send_Data(unsigned char dat){ES = 0;SBUF = dat;while(!TI);TI = 0;ES = 1;}void Key_delay(unsigned int z)//延时函数{unsigned int x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void add(void) //转换成10进制数子函数{unsigned char i;address1=0;address2=0;data1=0;data2=0;for(i=0;i<8;i++) //位{address1=(tt[i]<<7)|(address1>>1);address2=(tt[8+i]<<7)|(address2>>1);data1=(tt[16+i]<<7)|(data1>>1);data2=(tt[24+i]<<7)|(data2>>1);}}void main(){unsigned char i;System_Init();while(1){if(finish==1){finish = 0;add();Sbuf[0] = 0x45;Sbuf[1] = address1;Sbuf[2] = address2;Sbuf[3] = data1;Sbuf[4] = data2;CRC.CRCdata = CRC16(Sbuf,5);Sbuf[5] = CRC.Chdata[0];Sbuf[6] = CRC.Chdata[1];DE = 0; // 485 发送允许DEF= ~DE;Key_delay(1);for(i=0;i<7;i++){Send_Data(Sbuf[i]);}Key_delay(10);DE = 1; // 485 接收允许DEF= ~DE;}}}void rese() interrupt 4{if(RI){RI = 0;TR0 = 1;Buf[receive_count++] = SBUF;if(receive_count>=20)receive_count = 0;TH0 = Time_H;TL0 = Time_L;}if(TI)TI = 0;}void int0(void) interrupt 0 //外部中断0{unsigned char i,t;EX0=0;//关外部中断0TR0=1;//定时器0开始记数while(P32==0);TR0=0;//定时器0关t=(TH0*256+TL0)/921;//低电平9 MSTH0=0;TL0=0;if(t>=8){TR0=1;while(P32==1);TR0=0;t=(TH0*256+TL0)/921;//高电平3 MSTH0=0;TL0=0;if(t>=3){for(i=0;i<32;i++){TR0=1;while(P32==0);//等待TR0=0;t=(TH0*256+TL0)/921;TH0=0;TL0=0;if(t==0) //0跟1的低电平的时间相同{TR0=1;//定时器0开while(P32==1);TR0=0;//定时器0关//while(P32==1);//{if(TH0>10) break;}//如果高电平的时间大于2.5ms,跳出while 循环//TR0=0;//定时器0关t=(TH0*256+TL0)/921;TH0=0;TL0=0;//循环一次重新付初值tt[i]=t;}}finish=1;}}EX0=1;//外部中断开}。
c51单片机红外解码程序-汇总版和c语言版
精心整理纯软件解码---汇编版利用程序判电平和时间进行解码,缺点是浪费系统软件资源;优点是对系统硬件要求稍低ORG0000HT0ZDBIT20H.2XHBITP3.3;红外接收头数据接口RSBITP2.3RWBITP2.4============================================================JBXH,$;等待电平变低,解码从这开始CLRP2.0;开信号指示灯,表示正在接收信号MOVP0,#8EHSETBTR0;开T0中断LCALLYS3MSJBXH,DDXH;干扰检测LCALLYS3MSJBXH,DDXH;干扰检测DD1:JBT0ZD,DDXH;是否超出接收允许时间JNBXH,DD1;等待电平变高LCALLYS3MSJNBXH,DDXH;干扰检测DD2:JBT0ZD,DDXH;是否超出接收允许时间JBXH,DD2;等待电平变低JSSJ:;信号确认,开始接收数据ZJ:;MOVR7,#100;TSY:MOVR6,#255DJNZR6,$CPLBBDJNZR7,TSYMOVA,#0CDH;键值高位输出LCALLYJP_XZLMOVA,R4MOVB,#10HDIVABMOVCA,@A+DPTRLCALLYJP_XSJMOVA,#0CEH;键值低位输出LCALLYJP_XZLMOVA,BMOVCA,@A+DPTR LCALLYJP_XSJ; LCALLDYBF;调用灯控制子程序LJMPDDXH;返还等待下一次信号YS845:;延时845微秒MOVR7,#255RETRETDIVABMOVCA,@A+DPTR LCALLYJP_XSJMOVA,#0C1H;用户码前低位输出LCALLYJP_XZLMOVA,BMOVCA,@A+DPTR LCALLYJP_XSJMOVA,#0C4H;用户码后高位输出LCALLYJP_XZLMOVA,31HMOVB,#10HDIVABMOVCA,@A+DPTRLCALLYJP_XSJMOVA,#0C5H;用户码后低位输出LCALLYJP_XZLMOVA,BMOVCA,@A+DPTRLCALLYJP_XSJ;============此处专门针对我的开发板和遥控,不是解码的关键,只是一种应用举例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_XZLLCALLYJP_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_XZLMOVA,#4AH;J的ASCII码LCALLYJP_XSJMOVA,#0CBH;LCALLYJP_XZLMOVA,#5AH;Z的ASCII码RETRETCLRESETBRSCLRRWSETBEMOVP0,A;写数据CLRERET;=========查询忙碌标志============ CHECK_BUSY:PUSHACCBUSY_LOOP:CLRESETBRWCLRRSSETBEMOVA,P0;读取状态JBp0.7,BUSY_LOOPPOPACCLCALLDELRETDEL:MOVR6,#5RET/////////#definezd_cffsIT0///中断触发方式设置#definezd_dkEX0///中断打开设置////#definestc_dsqszAUXR&=0x7F;//定时器时钟12T模式,不需要可在AUXR....前加// ///**************************************************/****************************************************************** *****本程序使用外部中断加定时器来实现红外解码,占用系统软件资******** *****源极少,硬件方面占用了一个外部中断,定时器中断还可以进行******** *****一些简单的运用,软件部分可以做很多的动作,就看你发挥了!**************************************************************************/ #defineshi_jian定时器设置,请勿更改unsignedcharhwyhmh,hwyhml,hwjz,hwsj,hwjmws;///全局变量bithwjmok,yxjm;///全局变量,红外解码OK,允许解码voidmain(void){EA=1;//总中断打开zd_cffs=1;//外部中断_边沿触发方式zd_dk=1;//外部中断_打开ET0=1;//while(1)}}}定时器0{hwjz=0;TR0=0;//}voidZDhwjsCX(void)zd_rkdzusing3{unsignedinta=TH0*256+TL0;TL0=0;TH0=0;TR0=1;///开启T0if(a>shi_jian_*13000&&a<shi_jian_*14000)///if1分支2.判引导码13-14ms {hwsj=0;hwjmws=32;yxjm=1;}elseif(yxjm)///if1分支1.已收到引导码,允许解码{if(a>shi_jian_*11000&&a<shi_jian_*12000&&hwjmws==0)///if2分支1。
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.}。
c51解密红外 + c语言红外解码xy
首先说一下想写这个帖子看到论坛上有关于遥控器方面的帖子但是都没有很详细的介绍而且是已经有完整的波形仅仅介绍了解码部分而没有分析波形数据方面的介绍,因此有了写一篇完整的关于遥控器方面的文章的冲动此贴对新手可能有点困难不过不要紧我会以最通俗的方式来解释如果有不明白的建议去看看书,自己努力没有不可能的事别人能做到你也一定行,关于红外遥控的基础理论,大家可以到这个贴去看下/mcu/184.html,里面有详细的介绍。
在这里我仅把一些关键的带出来关于硬件电路那么抛开那么多文字介绍最后意思就是说你家里的遥控板也就是发射部分是把所有的封装好了的比如键盘矩阵、编码调制、LED红外发送器等等那么接受部分SM00383个脚一个脚地一个脚电源一个脚信号脚接到单片机随便个P口上(此处是P3。
6)OK 硬件部分就搞定了当然还有数码管显示,这些肯定不用说你都能搞定吧,我这刚好有一块51hei单片机学习板是在的论坛买的,这些东东都有,所以就不用自己去搭电路那么麻烦了),那么我们想我们按一下遥控板大家看到有个灯闪了一下然后OVER 那么我们现在要做的就是在灯闪了那一下之后让单片机来读它的键码然后不同的键码来干不同的事,本文是向大家解释一种方法当然如果你知道遥控器的编码那么我想写解码程序应该是很简单的事而我的意思是说我们现在从0开始拿到任何一种遥控板那怕不知道它的型号但是大家想即使它什么型号都没写但是按一下不同的键它的发射的脉冲肯定不一样无非就是引导码然后地址码键码验证码因为不同的遥控板它所定义的规则不一样(这里说一点题外话其实在读出波型后大家就可以看出这个遥控板最开始设计时的人的意思或者说考虑它的这个设计方式是否是最好的是否稳定是否具有通用性或者说日本的和中国的设计师在设计时他们所考虑的名牌和杂牌的他们在设计时所考虑的等等这些其实也是件很有意思的事就像偷窥到一个人的内心世界一样扯远了。
--)下面我们来说说本问利用51单片机软件解密的方法首先大家看了我刚才贴出来的连接应该知道了编码无非就是低电平高电平。
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单片机实现红外遥控。
关键字:单片机,红外遥控,解码1.引言遥控器相信大家不会陌生,日常生活中会使用到各种各样的遥控器,比如电视机、DVD 机、空调、机顶盒甚至音响、热水器等都用到遥控器,其实红外技术已经走进与人们的生活并且与人们的生活息息相关了。
红外遥控器作为设备的输入控制具有操作简便、价格便宜等诸多好处。
您可以根据您公司产品需要和遥控器提供商协商定制遥控器,包括遥控器键盘布局、每个按键的键码等。
遥控器键盘上每个按键的键码是一个小于256的一个数值,按键后通过遥控器红外管产生脉冲发送出去,红外接收器接收到脉冲后,对脉冲流进行分析,提取键码值,并按照键码值实现其遥控目的。
2.红外接收原理红外遥控信号接收:红外接收电路可以使用集成接收器,接收器包括红外接收管及信号处理IC,接收器对外只有三个引脚,一个接电源的Vcc脚、一个接地的GND脚、一个脉冲信号输出脚,当然脉冲信号输出脚直接接单片机的某个可以使用的IO脚就可以了。
3.脉冲波形分析:每次按键,红外接收器这边会收到一串脉冲宽度不等的脉冲波形流,其脉冲流由35个脉冲波形构成:前导码:第1个脉冲波形用户码1:第2到第9个脉冲波形用户码2:第10到第17个脉冲波形键码:第18到第25个脉冲波形键码反码:第26到第33个脉冲波形连续按键脉冲:第34和第35个脉冲为结束脉冲(也即连续按键脉冲),在每次按键结束后会有两个结束脉冲,如果一直按键不放的话,会一直发送连续按键脉冲,并可以认为在收到10个连续按键脉冲后是下一个按键。
注意:不同的遥控器产生的用户码值可能不一样,笔者碰到两种不同的用户码:0x00,0xFF及0x04,0x7F。
脉冲流中有四种不同的脉冲波形宽度:其中前导码脉宽为:40(4ms) < 脉冲宽度< 50(5ms)连续按键脉宽为: 21(2.1ms) < 脉冲宽度 < 25(2.5ms)bit "0" 脉宽为: 3(0.3ms) < 脉冲宽度 < 7(0.7ms)bit "1" 脉宽为: 14(1.4ms) < 脉冲宽度 < 19(1.9ms)在收到一串脉冲流后,就要对其进行分析,先要检测第一个脉冲波形是不是前导码,如果不是,则继续检测前导码,如果是则检测如下32个脉冲波形:用户码1为1字节,由8个脉冲波形组成(其中一个脉冲波形表示字节中1 bit );用户码2为1字节; 键值为1字节;键值反码为1字节,键值反码为键值取反值。
51单片机红外解码程序
51单片机红外解码程序1、红外遥控系统通用红外遥控系统由发射和接收两大部分组成,应用编/解码专用集成电路芯片来进行控制操作,如图1所示。
发射部分包括键盘矩阵、编码调制、LED红外发送器;接收部分包括光、电转换放大器、解调、解码电路。
下面,我们将使用下面两种设备:另外,使用51单片机进行解码。
2、原理图从原理图看出,IR的data脚与51的PD2(P3.2)相连。
2、红外发射原理要对红外遥控器所发的信号进行解码,必须先理解这些信号。
a) 波形首先来看看,当我们按下遥控器时,红外发射器是发送了一个什么样的信号波形,如下图:由上图所示,当一个键按下超过22ms,振荡器使芯片激活,将发射一组108ms的编码脉冲(由位置1所示)。
如果键按下超过108ms仍未松开,接下来发射的代码(连发代码由位置3所示)将仅由起始码(9ms)和结束码(4.5ms)组成。
下面把位置1的波形放大:由位置1的波形得知,这108ms发射代码由一个起始码(9ms),一个结果码(4.5ms),低8位地址码(用户编码)(9ms~18ms),高8位地址码(用户编码)(9ms~18ms),8位数据码(键值数据码)(9ms~18ms)和这8位数据的反码(键值数据码反码)(9ms~18ms)组成。
b) 编码格式遥控器发射的信号由一串0和1的二进制代码组成.不同的芯片对0和1的编码有所不同。
通常有曼彻斯特编码和脉冲宽度编码。
XS-091遥控板的0和1采用PWM方法编码,即脉冲宽度调制。
下图为一个发射波形对应的编码方法:放大0和1的波形如下图:这种编码具有以下特征:以脉宽为0.565ms、间隔0.56ms、周期为1.125ms 的组合表示二进制的“0”;以脉宽为0.565ms、间隔1.685ms、周期为2.25ms 的组合表示二进制的“1”。
3、红外接收原理a) 波形红外接收头将38K载波信号过虑,接收到的波形刚好与发射波形相反:放大,位定义0和位定义1波形如下:4、解码原理及算法注:代码宽度算法:16位地址码的最短宽度:1.12×16=18ms 16位地址码的最长宽度:2.24ms×16=36ms可以得知8位数据代码及其8位反代码的宽度和不变:(1.12ms+2.24ms)×8=27ms所有32位代码的宽度为(18ms+27ms)~(36ms+27ms)对于红外线遥控对于很多电子爱好者来讲,都感觉到非常神奇,看不到,摸不着,但能实现无线遥控,其实控制的关键就是我们要用单片机芯片来识别红外线遥控器发出红外光信号,即我们通常所说的解码。
基于C51的红外线解码
课题:红外解码课程设计前言传统的遥控器大多数采用了无线电遥控技术,但是随着科技的进步,红外线遥控技术的成熟,红外也成为了一种被广泛应用的通信和遥控手段。
继彩电、录像机之后,在录音机、音响设备、空调机以及玩具等其它小型电器装置上也纷纷采用红外线遥控。
工业设备中,在高压、辐射、有毒气体、粉尘等环境下,采用红外线遥控不仅完全可靠而且能有效地隔离电气干扰。
所以采用单片机进行遥控系统的应用设计,遥控装置将同时具有编程灵活、控制范围广、体积小、功耗低、功能强、成本低、可靠性高等特点,因此采用单片机的红外遥控技术具有广阔的发展前景。
本设计主要研究并设计一个基于单片机的红外接收系统,并实现对电视遥控器的解码及编码值显示。
控制系统主要是由51系列单片机、电源电路、红外遥控器发射、红外接收电路、数码管显示电路等部分组成,红外接收头接收到的编码信息通过单片机处理,单片机根据不同的遥控器按键信息进行处理并在数码管上相应的显示相应的按键值编码信息以加深对红外编码的理解。
第1章红外解码系统分析第1节设计要求整个控制系统的设计要求:被控设备的控制实时反应,从接收信号到信号处理及对设备控制反映时间应小于1s;整个系统的抗干扰能力强,防止误操作;整个系统的安装、操作简单,维护方便;成本低。
红外载波、编码电路设计要求:单片机定时器精确产生38KHz红外载波;根据控制系统要求能对红外控制指令信号精确编码并迅速发送。
红外解码电路设计要求:精确接收红外信号,并对所接收信号进行解码、放大、整形、解调等处理,最后输出信号;对非红外光及边缘红外光抗干扰能力强。
设备扩展模块设计要求:直流控制交流;抗干扰能力强;反应迅速不产生误动作;能承受大电流冲击。
第2节总体设计方案2.1 方案论证(一)单片机控制器模块方案一:采用目前比较通用的51系列单片机。
此单片机的运算能力强,软件编程灵活,自由度大,市场上比较多见价格便宜且技术比较成熟容易实现。
方案二:采用16 位单片机SPCE061A 作为控制核心。
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; //刚进中断时关闭了分控,现在要打开}。
51单片机红外解码、超声波测距程序(详细解释程序)
// c51红外解码、超声波测距程序#include <reg52.h>#define uchar unsigned char#define uint unsigned int#define count 4uchar data IRcode[4]; //定义一个4字节的数组用来存储代码uchar table[4];uchar enled[4]={0x1f,0x2f,0x4f,0x8f};uchar CodeTemp,temp,tt; //编码字节缓存变量uchari,j,k,temp,timeH,timeL,succeed_flag,flag,h,h1,h2,a,key,key1,key2; //延时用的循环变量uint distance,distance1,time; //距离,timesbit IRsignal=P3^2; //HS0038接收头OUT端直接连P3.2(INT0)sbit come=P3^3;sbit d=P1^1;//发送码sbit BZ=P1^0;sbit s=P3^7;//38ksbit ss=P3^6;//38kuchar m;// 开关控制//sbit n=P2;//电机反转code unsigned charseg7code[10]={0xa0,0xbb,0x62,0x2a,0x39,0x2c,0x24,0xba,0x20,0x28}; //显示段码/**************************** 定时器0中断************************/void timer0() interrupt 1{TH0=(65536-count)/256;TL0=(65536-count)%256;s=~s;//产生38K信号ss=~ss;//tt++;//发送超声波个数}/**************************** 延时0.9ms子程序************************/void Delay0_9ms(void){uchar j,k;for(j=18;j>0;j--)for(k=20;k>0;k--);}/***************************延时1ms子程序**********************/void Delay1ms(void){uchar i,j;for(i=2;i>0;i--)for(j=230;j>0;j--);}/***************************延时4.5ms子程序**********************/ void Delay4_5ms(void){uchar i,j;for(i=10;i>0;i--)for(j=225;j>0;j--);}/**************************** 解码延时子程序************************/ void Delay(void){uchar i,j,k;for(i=100;i>0;i--)for(j=100;j>0;j--)for(k=3;k>0;k--);}/**************************** 显示延时子程序************************/ void ledDelay(unsigned int tc) //延时程序{unsigned int i,j;for(i=0;i<10;i++)for(j=0;j<tc;j++);}/************************************************ ****************///定时器1中断,用做超声波测距无回波void timer1() interrupt 3{TR1=0;ET1=0;EX1=0;TH1=0;TL1=0;}/***********************显示程序*********************/ void Led(int date) //显示函数{ int i;table[0]=date/1000;table[1]=date/100%10;table[2]=date/10%10;table[3]=date%10;date=0;for(i=0;i<120;i++){P2=enled[i%4]&m;//P2口高四位控制数码管,低位陪分控制继电器P0=seg7code[table[i%4]]; //取出千位数,查表,输出。
红外线发射与接收C51用C语言解决方案
//红外线延时函数,延时 0.56 毫秒
//红外线延时函数,延时 0.5 毫秒
delay_ms(9); rfot=1; delay_ms(4); delay_50(); } void a_key() { uint i; bit_boot(); for(i=0;i<8;i++) { rfot=0; delay_56(); rfot=1; delay_56(); } for(i=0;i<8;i++) { rfot=0; delay_56(); rfot=1; delay_112(); } rfot=0; delay_56(); rfot=1; delay_56(); rfot=0; delay_56(); rfot=1; delay_56(); rfot=0; delay_56(); rfot=1; delay_56(); rfot=0; delay_56(); rfot=1; delay_56(); rfot=0; delay_56(); rfot=1; delay_112(); rfot=0; //A 键编码
现在大家已经知道了每个键的编码,在写程序之前,先要说一下有关红外线发射的知识,我 想大家对这些知识应该是很了解的了,在这里补充说一下是为了在下一步写程序是大家能明白我 的思路是对还是错? 再不考虑发射芯片的型号,就用大家常用的编码方式: 首先先来说说引导区,如下图:
图 二 每个按键在被按下之后首先会有像上图所的信号发出,称为引导区,实际生活中,用遥控器 发出的信号与上面的信号是相反的,经过红外线接收头解码以后就和上图一样了,值得大家注意 的是发射模块的芯片不同,引导区的时间和数据都有所不同,但解决的方法都是一样的。 在写程序是就按照上面的图来写: P1^6=0; Delay(); //延时 9mS P1^6=1; Delay(); //延时 4.5mS
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
{
P2=Table[lp[i]]; //查表法得到要显示数字的数码段
ifபைடு நூலகம்lp[i]>0x7f)
P2+=0x80;
Delay(); //延时
P2=0; //清0端口,准备显示下位
if(i==7) //检测显示完8位否,完成直接退出,不让P1口再加1,
否则进位影响到第四位数据
break;
P1++; //点亮下一位数码管
}
while(j--)
{ //循环接收33位数据,为何我们用到66位数组,我们可以不接收高电平
时间常数,只接低电平常数就
//可以判断1或0了,在这里我们都接收,还有一点要知道,
tmp>>=1;
if(Table_Rx[i]>30)
tmp+=0x80;
}
Table_Data[2]=tmp/16;
Table_Data[3]=tmp%16;
tmp=0;
接收以S52单片机作为接收系统。以S52的P3.3口作为接收端口,该端口是外部中断1。
这个接受程序是以XC866作为红外发送控制系统,接收程序如下:
#include<reg52.h> //头文件
#include<intrins.h>
#define uchar unsigned char //宏定义
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)//显示
i++;
tmp=0;
Table_Rx[i]=1; //时间量从1开始
while(HWRx) //检测高低电平的变化,这里检测的是低电平
{
Table_Rx[i]++; //没变继续加1
#define uint unsigned int
sbit HWRx=P3^3; //位声明
code uchar Table[]= //共阴数码管 0-9 a-f - 表
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
}
i++;
}
P1=0xf8;
i=200; //加入循环延时,抗干扰
while(i) //在有接收数据的时候显示一个H
{
tmp=255;
for(i=35;i<51;i++,i++)
{
tmp>>=1;
if(Table_Rx[i]>30)
tmp+=0x80;
}
Table_Data[4]=tmp/16;
接收波形是反向,在没有接收时端口为高电平
tmp=0;
Table_Rx[i]=1; //时间量从1开始
while(!HWRx) //检测高低电平的变化,这里检测的是高电平
{
Table_Rx[i]++; //没变继续加1
void hongwai() interrupt 2 //外部中断 1 ,INT1(P3^3)连接红外线接收IC数据脚
{
uchar i,j,tmp;
EX1=0; //关闭中断
j=33; //传送一组数包括引导码1位,4个八位数据,总共33位
Table_Data[5]=tmp%16;
tmp=0;
for(i=51;i<67;i++,i++)
{
tmp>>=1;
if(Table_Rx[i]>30)
tmp+=0x80;
while(tmp)
{
tmp--;
P2=0x76;
}
i--;
}
tmp=0;
for(i=3;i<19;i++,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--);
}
{
Display(Table_Data,8);
}
}
void Delay() //延时时间大约为31us,晶振12M
{
uchar i=13;
while(i)
Delay(); //家一个延时防止,计数值一下子就加满了
tmp++; //加1
if(tmp==250)
break;
}
}
Table_Data[6]=tmp/16;
Table_Data[7]=tmp%16;
EX1=1; //刚进中断时关闭了分控,现在要打开
}
i=0; //从第一维数组开始
Delay_ms(10);
if(HWRx)
{ //然后再检测红线接收脚是有数据招收,有继续,没有则退出
EX1=1;
return;
{
uchar i; //定义变量
P2=0; //端口2为输出,关闭
P1=P1&0xF8; //将P1口的前3位输出0,对应138译门输入脚,
全0为第一位数码管
Delay(); //同上
tmp++; //加1,用于判断是1还是0的,低电平来了
if(tmp==250)
break;
{
tmp>>=1; //右移一位,接收低位在前
if(Table_Rx[i]>30) //检测低电平时间超过30就确认为1
tmp+=0x80;
}
}
}
void main() //主函数
{
EA=1; //首先开启总中断
EX1=1; //开启外部中断 1
IT1=1; //设置成下降沿触发方式
while(1) //一直显示,其它由中断处理
Table_Data[0]=tmp/16; //分开2位以16进制显示,用显示发送的数据
Table_Data[1]=tmp%16;
tmp=0;
for(i=19;i<35;i++,i++) //同上
{