利用定时器的红外解码程序

TR0=0;
Time=TH0;
Time=(Time<<8)|TL0;
if(Time>4000)
{
TH0=0;
TL0=0;
for(Count=0;Count<4;Count++)
{
for(NumCount=0;NumCount<8;NumCount++)
{
while(!DQ);//过度码,低电平0.56ms
printf("%u\n",HWData);
}
主函数
#include "hongwai.h"
UINT8 code table1[]={
0x00,0x80,0x40,0x20,0xa0,0x60,0x10,
0x90,0x50,0x30,0xb0,0x70,0x08,0x88,
0x48,0x28,0xa8,0x68,0x18,0x98,0x58
TR0=1;
while(DQ);//表示数据1时,高电平1.68ms,表示数据0时,高电平0.56ms
TR0=0;
Time=TH0;
Time=(Time<<8)|TL0;
TAB[Count]<<=1;
if(Time>850&&Time<1680)
{
TAB[Count]|=0x01;
}
if(Time>1680)
{
UINT8 Count,NumCount,TAB[4]={0};
UINT16 Time;
TR0=1;
while(!DQ);//引导码,低电平9ms
TR0=0;
Time=TH0;
Time=(Time<<8)|TL0;
if(Time>8000)
{
TH0=0;
TL0=0;
TR0=1;
while(DQ);//引导码,高电平4.5ms
#endif
sbit DQ=P3^2;
void HWInit(void);
void HWReceive(void);
#endif
程序
/********************************************************************************/
/*-----------------------------此源码写于2011-7-9-------------------------------*/
else if(HWData==table1[2])P1=~P1;
HWData=HWoppoData;
}
}
return 0;
}
/*void delay_1ms(UINT8 z)
{
UINT8 x,y;
for(x=z;x>0;x--)
for(y=550;y>0;y--);
} */
/*------------------------------红外解码-------------------------------*/
/********************************************************************************/
/*------------------------------xiaoshuai制作-------------------------------*/
/********************************************************************************/
/*函数名:HWInit
/*功能:红外解码初始化(初始化串口,初始化定时器,初始化外部中断)
/*参数:无
/*返回值:无
/******************************************************************/
void HWInit(void)
{
TMOD=0x21;
};
//void delay_1ms(UINT8 z);
extern UINT16 HWAddress;
extern UINT8 HWData,HWoppoData;
int main(void)
{
HWInit();
while(1)
{
if(HWData==(~HWoppoData))
{
if(HWData==table1[1])P1=0xfe;
头文件/********************************************************************************/
/*-----------------------------此源码写于2011-7-9-------------------------------*/
/*函数名:HWReceive
/*功能:红外接收解码函数(接收红外发射的四个字节的码,2个字节的地址码,一个字节的键码和一个字节键反码)
/*参数:无
/*返回值:无
/******************************************************************/
void HWReceive(void)
#include"hongwai.h"
#include<intrins.h>
#include<stdio.h>
UINT16 HWAddress;
UINT8 HWData,HWoppoData;
/******************************************************************/
{
return;
}
TH0=0;
TL0=0;
}
}
HWAddress=TAB[1];
HWAddress=(HWAddress<<8)|TAB[0];
HWData=TAB[2];
HWoppoData=TAB[3];
}
}
TH0=0;
TL0=0;
}
/******************************************************************/
TH0=0;
TL0=0;
EA=1;
EX0=1;
IT0=1;
SCON=0X50; //选择串行工作方式1
TH1=0xfd; //波特率设为9600
TR1=1;
TI=1;
}
/*********************************************************0入口
/*参数:无
/*返回值:无
/******************************************************************/
void Ex_int(void) interrupt 0
{
_nop_();
HWReceive();
#ifndef __HONGWAI_H__
#define __HONGWAI_H__
#include<stc12c5a60s2.h>
#ifndef UINT8
typedef unsigned char UINT8;
typedef unsigned int UINT16;
typedef unsigned long UINT32;
合集下载

(完整word版)红外编码解码程序(word文档良心出品)

(完整word版)红外编码解码程序(word文档良心出品)

红外编码解码程序,我写的是:发送模块通过按键,发送出相应键值的编码,接收模块接收到信号后解码该键值,并点亮相应的状态灯(新手,高手勿喷)//************************* 单片机红外发射******************************* #include<reg52.h> sbit ir=P 1人3;sbit k1= P2A5;sbit k2=P2M;sbit k3=P2A3;sbit k4=P2A2;sbit k5=Pil;unsigned int count, set_count; bit irflag,keyflag; unsigned char irsys[]={0x00,0xff}; unsigned char irdata,ircode;void delay(unsigned int a){unsigned char i;while(--a!=0) for(i=300;i>0;i--);}void keyscan(){/*if(k1==0){delay(10);if(k1==0){keyflag=1;while(!k1);irdata=0x01;}*/ if(k2==0) {delay(10); if(k2==0) {keyflag=1;while(!k2); irdata=0x02;}{delay(10); if(k3==0) {keyflag=1;while(!k3); irdata=0x03;} if(k4==0){delay(10); if(k4==0) {keyflag=1;while(!k4); irdata=0x04;} if(k5==0){delay(10); if(k5==0) {keyflag=1;while(!k5); irdata=0x05;void ir_sendbyte() // 红外发送一个字节数据{ unsigned char i; for(i=0;i<8;i++) //发送8 位数据{set_count=43; //发送编码中的0.56ms 高电平irflag=1;count=0;TR0=1; while(count<set_count);TR0=0;if(ircode&0x01) set_count=130; // 判断红外编码最低位,若为 1 则 1.69ms 的低电平else set_count=43; // 为0 则0.565ms 的低电平irflag=0;count=0;TR0=1; while(count<set_count);TR0=0; ircode=ircode>>1;}}void ir_send(){set_count=346; //发送编码中的引导码(4.5ms高电平+4.5ms低电平)irflag=1;count=0;TR0=1;while(count<set_count);set_cou nt=346; //发送编码中的 4.5ms低电平irflag=0;count=0;TR0=1;while(count<set_count);TR0=0; ircode=irsys[0];ir_sendbyte();ircode=irsys[1];ir_sendbyte();ircode=irdata; //发送8 位数据码ir_sendbyte();ircode=~irdata; // 发送8 位数据反码ir_sendbyte();set_count=43; //发送编码中的0.56ms高电平irflag=1;count=0;TR0=1;while(count<set_count);TR0=0;irflag=0;/*delay(23); //延时23ms (编码中的23ms低电平)set_count=346; //发送编码中的引导码(4.5ms高电平+4.5ms低电平) irflag=1;count=0;TR0=1; while(count<set_count);TR0=0; set_count=346; irflag=0;count=0;TR0=1;while(count<set_count);TR0=0;*/ set_count=43;irflag=1;count=0;TR0=1;while(count<set_count);TR0=0;irflag=0;delay(23);}void timer0_init(){EA=1;TMOD=0x02;//定时0 8 位自动重装模式ET0=1;TH0=0xe6; //定时13us,38K 红外矩形波,晶振24M TL0=0xe6; }void main(){timer0_init();count=0;ir=0;irflag=0;while(1){keyscan(); if(keyflag) {delay(10); ir_send(); delay(500); keyflag=0;delay(100);}}}void timer0() interrupt 1 {count++;if(irflag==1)ir=~ir; // 有发射标志,则发射38khz 的矩形波elseir=0;红外接收**************************** //*************************#include<reg52.h>#define uchar unsigned char #define uint unsigned intsbit led仁P2A1;sbit led2=卩2人2;sbit led3=卩2人3;uchar irtime;uchar startflag;uchar irdata[33];uchar bitnum;uchar irreceok;uchar ircode[4]; uchar irprosok;void display();void timer0init(){TMOD=0x02;TH0=0x00;TL0=0x00;ET0=1;EA=1;TR0=1;void int0init(){IT0=1;EX0=1; EA=1;}}void irpros(){uchar k,i,j;uchar value;k=1;for(j=0;j<4;j++){for(i=0;i<8;i++){ value=value>>1; if(irdata[k]>6){value=value | 0x80;}k++;if(k>33)k=1;}ircode[j]=value;}irprosok=1;}void main(){ timer0init(); int0init(); while(1) { if(irreceok) { irpros(); irreceok=0;} display();}void display()switch(ircode[2]){case 0x05:led1=1; led2=1; led3=1; break;case 0x02:led1=0;led2=1; led3=1; break;case 0x03:led2=0; led1=1; led3=1; break;case 0x04:led3=0;led1=1;led2=1; break;//case 0x01: 备用}void timer0 () interrupt 1 { irtime++;}void int0 () interrupt 0 {if(startflag){if(irtime>32) // 检测引导码{bitnum=0;}irdata[bitnum]=irtime;irtime=0;bitnum++;if(bitnum==33){bitnum=0;irreceok=1;startflag=0;}else{startflag=1; irtime=0;}}。

红外解码程序

红外解码程序

注:主函数由读者自己编写,本程序只用于解码,最终得出的按键码存于变量Key_Temp中。

本人习惯写某个器件的程序的时候,习惯创建.c和.h文件,因为这样方便移植,在新建的程序中只需添加.C文件和include .h文件就行了,很方便。

本人用芯片是15W4K32S4。

自己用这块芯片做有开发板,平时写程序都用它。

也可用一般的51单片机,但要注意定时器的时间和外部中断的端口头文件(.h文件)#ifndef __IR_H__#define __IR_H__sfr INT_CLKO = 0x8f;sbit IR = P3^6; //外部中断2的端口在P3.6口extern Byte Long_Press;extern Byte Key_Temp;void Init_IR();#endif以下是(.C文件)#include <15W4K32S4.h> //也可以用reg52.h ,一般的编译器没有<15W4K32S4.h>这个头文件,因为这是我个人添加进编译器里面的#include "IR.h"/******************************************************************* 时间计算:时间由定时器计的定时值来决定,本程序设定工作频率是24MHz,但定时器是12T模式。

故一个定时脉冲时间为0.5us。

实际定时所得时间应为((TH0<<8)|TL0)*0.5 ,单位us。

本程序由:河池学院-物电学院-XXX编写,*******************************************************************/bit IR_Error = 0; //超时错误标志,解码过程中,每个高电平或低电平的时间都不会//超时,也就是定时器不会被记满,如若定时器记满,向CPU申请了中断,那便可认//为是解码失败也就无需再等待高电平结束或低电平结束Byte Long_Press; // 长按计数,若用到长按功能Byte Key_Temp;Word IR_table[4];void Init_IR() //初始化函数,初始化定时器和外部中断{INT_CLKO |= 0x10; //使能外部中断2(不固定,用哪个外部中断都行:下降沿触发)AUXR &= 0x7F; //定时器时钟12T模式,此句可以不写,//因为单片机的定时器上电默认是12T,写是为了方便日后了解TMOD = 0x01; //设置定时器0为不可重装模式,从零开始定时TR0 = 0; //定时器不定时,也可不写,上电默认不启动ET0 = 1; //允许定时器中断,解码超时时进入定时器中断,以方便结束解码EA = 1; //打开总中断}void IR_Rec() interrupt 10{Byte IR_cnt;Byte IR_cnt1;Word L_Time; //定义低电平时间Word H_Time; //定义高电平时间INT_CLKO &= 0xEF; //关闭外部中断2TH0 = 0; //清零定时器的值TL0 = 0;TR0 = 1; //开始定时while(!IR&&!IR_Error); //等待低电平结束if(IR_Error)//若计时超过正常红外时间{IR_Error = 0;TR0 = 0; //关闭定时器TH0 = 0;TL0 = 0;INT_CLKO |= 0x10; //使能外部中断2return; //返回:即结束整个中断服务,退出当前中断服务}TR0 = 0; //关闭定时器L_Time = (TH0<<8)|TL0; //获取定时器的值L_Time = L_Time*0.5; //计算出时间TH0 = 0;TL0 = 0;TR0 = 1;while(IR&&!IR_Error); //等待高电平结束if(IR_Error)//若计时超过正常红外时间{IR_Error = 0;TR0 = 0; //关闭定时器TH0 = 0;TL0 = 0;INT_CLKO |= 0x10; //使能外部中断2return;}TR0 = 0;H_Time = (TH0<<8)|TL0;H_Time = H_Time*0.5;if((L_Time>8000)&&(L_Time<10000)&&(H_Time>4000)&&(H_Time<5000))//判断是否为起始码{//若为起始码,则进行解码//一共接收到四个字节,第一个字节为用户码,第二个字节为用户码反码//第三个字节为按键码,第四个字节为按键码的反码//红外遥控是先发低电平,所以接收时候数据是右移,左移或右移,都是自动补零,//故只用判断高电平Long_Press = 0;//长按计数清零for(IR_cnt=0;IR_cnt<4;IR_cnt++){for(IR_cnt1=0;IR_cnt1<8;IR_cnt1++){Key_Temp >>= 1; //先右移一位TH0 = 0;TL0 = 0;TR0 = 1; //启动定时器while(!IR&&!IR_Error); //等待低电平结束if(IR_Error)//若计时超过正常红外时间{IR_Error = 0;TR0 = 0; //关闭定时器TH0 = 0;TL0 = 0;INT_CLKO |= 0x10; //使能外部中断2return;}TR0 = 0; //关闭定时器L_Time = (TH0<<8)|TL0; //获取低电平时间L_Time = L_Time*0.5; //计算时间(us)TH0 = 0; //定时器清零TL0 = 0;TR0 = 1; //启动定时器while(IR&&!IR_Error); //等待高电平结束if(IR_Error)//若计时超过正常红外时间{IR_Error = 0;TR0 = 0; //关闭定时器TH0 = 0;TL0 = 0;INT_CLKO |= 0x10; //使能外部中断2return;}TR0 = 0;H_Time = (TH0<<8)|TL0;H_Time = H_Time*0.5;if((L_Time<220)||(L_Time>700)) //若低电平时间异常{INT_CLKO |= 0x10; //使能外部中断2return; //停止解码}if((H_Time>1400)&&(H_Time<1800)) //若高电平时间在“1”的范围{Key_Temp |= 0x80;}else if((H_Time<200)&&(H_Time>2000)) //若高电平时间异常{INT_CLKO |= 0x10; //使能外部中断2return; //停止解码}}IR_table[IR_cnt] = Key_Temp;}if(((IR_table[0]+IR_table[1])==0xFF)&&((IR_table[2]+IR_table[3])==0xFF))//验证接收到的数据是否正确,原码加反码等于全1,也就是FF{Key_Temp = IR_table[2]; //将存储的按键值赋给Key_Temp,}else Key_Temp = 0; //若验证的数据有误,则赋0}elseif((L_Time>8000)&&(L_Time<10000)&&(H_Time>1950)&&(H_Time<2350)) //长按{Long_Press++; //长按计数}INT_CLKO |= 0x10; //处理完毕,打开外部中断}void Time0() interrupt 1{IR_Error = 1;}。

STC89C58RD+22.1184MHz晶振+外中断0+红外遥控解码+定时器0+定时器1+定时器2+串口+看门狗

STC89C58RD+22.1184MHz晶振+外中断0+红外遥控解码+定时器0+定时器1+定时器2+串口+看门狗

STC89C58RD+22.1184MHz晶振+外中断0+红外遥控解码+定时器0+定时器1+定时器2+串口+看门狗本程序通过外中断0与定时器0实现红外遥控解码,并通115200波特率的串口将红外遥控的地址码和数据码发送到PC机上的串口助手,同时使用定时器1进行喂狗,防止程序出现异常。

本程序适用于STC系列的单片,ATMEL的单片机基本通用,就是在设置看门狗和定时器2时需要参考ATMEL单片机的手册才行。

//以下程序适用于STC89C58RD+ ,使用22.1184MHz晶振,用1838来对红外遥控器解码,1838的1脚接外中断0脚,即单片机P3.2脚//红外遥控器发出的红外信号经过1838处理后输出的是9.5ms低电平(也可能是4.5ms低电平)加4.5ms高电平的前导码,后面8位的地址码,8位的地址反码(也可能是地址码),8位的数据码,8位的数据反码,总共32位码//其中0码由O.56ms低电平和0.56ms高电平组合而成.脉冲宽度为1.12ms;1码由0.56ms低电平和1.69ms高电平组合而成,脉冲宽度为2.25ms//特别说明:当使用定时器1作为波特率发生器,而定时器2作为16位自动装载的定时器时,定时器2无法正常工作,必须是定时器2作为波特率发生器,定时器1作为定时器用#include<reg52.h>#include<stdio.h>//#include<string.h>unsigned char count;unsigned int Address_Part,Data_Part;unsigned char date;bit Rev_flag;bit Over_flag;sfr WDT_CONTR=0xe1;//STC的看门狗寄存器的地址,ATMEL的芯片看门狗地址不一样sfr T2MOD=0xc9;//定时器2的模式选择寄存器地址//unsigned int time_data[35];//unsigned char time_count;#define WDT_Time 22unsigned char Count_Num=0;void delay(unsigned int z)//延时函数,在22.1184M晶振下没有调试过,只是大概的使用,大概是1个毫秒{unsigned int x,y;for(x=z;x>0;x--)for(y=200;y>0;y--);}void init_config()//初始化函数{// PCON |=0x80;//SMOD=1,定时器1要产生115200波特率必须置位,定时器2则不需要REN=1;//启动串行接收数据SM0=0;SM1=1;//SM0,SM1设置串行口为工作方式1,10位异步收发器-->1位起始位,8位数据,1位停止位TI=1;//要使用printf()函数,就需要置位,后期不能置0T2MOD=0x00;//选择定时器2为向上定时计数器T2CON=0x34;//选择定时器2为16位自动重新装载模式下的波特率发生器,启动定时器2RCAP2H=0xff;//65536-(fosc/(32*baud));//22.1184MHz产生115200波特率,算法和用定时器1做波特率发生器的算法不一样RCAP2L=0xfa;//TMOD=0x11;//设置定时器0为工作方式1,定时器1为方式1TH1=(65536-65000)/256;//定时器初值,大概是35ms进一次定时器中断TL1=(65536-65000)%256;//TR1=1;//启动T1定时器TH0=0x00;TL0=0x00;//设置定时器0初值IT0=1;//设置外中断0为下降沿触发ET0=1;//开定时器0允许中断ET1=1;//开定时器1允许中断EX0=1;//开外中断0//TR0=1;ES=1;//开串口中断EA=1;//开总中断Rev_flag=0;Over_flag=0;printf("Initialization is OK!\n\r");WDT_CONTR=0x35;//看门狗启动,计数清零,晶振为22.1184MHz,64分频,溢出时间为1S}void main()init_config();while(1){// WDT_CONTR=0x35;//看门狗启动,计数清零,64分频,溢出时间为1Sif(Over_flag){Over_flag=0;printf("Address_Part:%x,Data_Part:%x\n\r",Address_Part,Data_Part);}if(Rev_flag)//判断串口接受到数据,只是把从串口调试助手发过来的数据发回去,测试收发用而已{ES=0;Rev_flag=0;SBUF=date;//发送数据while(!TI);//发送数据完毕才跳出死循环ES=1;// TI=0;}/* if(Count_Num>WDT_Time)//0.8秒左右喂狗{Count_Num=0;//WDT_CONTR=0x35;//看门狗启动,计数清零,64分频,溢出时间为1Sprintf("T1!\n\r");}*//* if(time_count==40)//把收到的时间th值传给串口打印出来{time_count=0;printf("time:\n\r");for(;time_count<35;time_count++){printf("%d \n\r",time_data[time_count]);}memset(time_data,0,sizeof(time_data));EX0=1;//开外中断0}*/}}void exter() interrupt 0{unsigned int th;unsigned char tl;bit ds;TR0=0;//关定时器0th=TH0;//提取出高8位tl=TL0;//提取出低8位th<<=8;//左移8位th=th|tl;//算出定时器总共的计数值TH0=0x00;//初始值TL0=0x00;/* time_data[time_count]=th;//这段代码的作用是在不知道th的数值是多少为前导码,为0,为1时,把收到的时间th给提取出来,方便传给串口打印出来,要使用这一功能要把下面判断前导码那些代码给屏蔽,并且开启主函数里面的那段代码time_count++;if(time_count==35){time_count=40;EX0=0;}TR0=1;*//*这段判断前导码和0、1的值是12M晶振下的if(th>950&&th<1225)ds=0;//判断0和1else if(th>2050&&th<2345)ds=1;else if(th>13325&&th<13600)//判断前导码*///这段判断前导码和0、1的值是22.1184M晶振下的if(th>1900&&th<2260)ds=0;//判断0和1else if(th>4000&&th<4300)ds=1;else if(th>24900&&th<25350)//判断前导码{Address_Part=0;Data_Part=0;count=0;Over_flag=0;TR0=1;return;}else{TR0=1;return;}//去除干扰,当接收的是准备进前导码时的下降沿和截止码时,该语句起作用,没有该语句,则只能接收一次count++;if(count<16){Address_Part=Address_Part|ds;Address_Part=Address_Part<<1;TR0=1;}else if(count==16){Address_Part=Address_Part|ds;TR0=1;}else if(count<32){Data_Part=Data_Part|ds;Data_Part=Data_Part<<1;TR0=1;}else if(count==32){Data_Part=Data_Part|ds;Over_flag=1;}//接收完32位,后面应该有连续码,但不需要,所以不作处理}void time0() interrupt 1//要是没有该函数,可能会因为溢出而导致解码不正确{TR0=0;}void ser() interrupt 4{if(RI)//一定要加该判断句,不然串口调试助手那里会一直收到数据{RI=0;date=SBUF;//提取数据Rev_flag=1;}}void timer1() interrupt 3{TH1=(65536-65000)/256;//定时器初值;TL1=(65536-65000)%256;//Count_Num++;// printf("T2!\n\r");if(Count_Num>WDT_Time)//0.8秒左右喂狗{Count_Num=0;WDT_CONTR=0x35;//看门狗启动,计数清零,64分频,溢出时间为1S}}。

51单片机红外遥控解码,很详细(汇编语言,C语言等)

51单片机红外遥控解码,很详细(汇编语言,C语言等)
//k[i]=TH0;
//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

单片机的红外线解码程序

单片机的红外线解码程序
{
switch(inf_shuju)
{
case inf_code_0: inf_array[1]=30;
break;
case inf_code_1: inf_array[1]=1;
break;
case inf_code_2: infe inf_code_3: inf_array[1]=3;
TR1 = 1; //定时器1开始计数,由于晶振是24M
inf_shunxu++;
}
//#############################################################################
//函数名称:void inf_gongcuowu()
//功能:红外线错误子程序
break;
case inf_code_12: inf_array[1]=12;
break;
case inf_code_13: inf_array[1]=13;
break;
case inf_code_14: inf_array[1]=14;
break;
case inf_code_15: inf_array[1]=15;
//入口参数:无
//出口参数:无
//#############################################################################
void inf_gongcuowu(void)
{
inf_mode_cuowu = 1; //红外线接收出现错误
void T_1(void) interrupt 3 //参与红外线接收
{
TR1 = 0;

红外遥控器解码程序

红外遥控器解码程序

//===================================================================== //// 红外遥控器解码程序演示//// 本程序主要将现在比较常用TX1300遥控器进行解码,将解码后的数据通过P2端////口的数码管显示出来,为了更好的看到运行过程,特加了三个指示灯用来指示当////前运行状态.P10主要用来闪亮,表示程序正在运行,P11则用来表示接收到数据, ////P12表示触发内部的定时器操作.P13的闪亮表示正确接收完一个数据. //// 程序运行效果: 打开本机电源开关,可以看到P10不停的闪动,按下遥控器的数////字键,数码管则显示相应的数字键(1-9).可以看到P11,P12在显示后呈亮状态.则////可以接收下一个数据,在上面过程中可以看到P13闪亮了一下.表明上次正确接收////到数据. ////---------------------------------------------------------------------//// 开发日期: 2009/01/30 研发单位:上海腾芯实业有限公司//#include <reg52.h> //包含51单片机相关的头文件#define uint unsigned int //重定义无符号整数类型#define uchar unsigned char //重定义无符号字符类型uchar code LedShowData[]={0x03,0x9F,0x25,0x0D,0x99, //定义数码管显示数据0x49,0x41,0x1F,0x01,0x19};//0,1,2,3,4,5,6,7,8,9uchar code RecvData[]={0x07,0x0A,0x1B,0x1F,0x0C,0x0D,0x0E,0x00,0x0F,0x19};uchar IRCOM[7];static unsigned int LedFlash; //定义闪动频率计数变量unsigned char RunFlag=0; //定义运行标志位bit EnableLight=0; //定义指示灯使能位/***********完成基本数据变量定义**************/sbit S1State=P1^0; //定义S1状态标志位sbit S2State=P1^1; //定义S2状态标志位sbit B1State=P1^2; //定义B1状态标志位sbit IRState=P1^3; //定义IR状态标志位sbit RunStopState=P1^4; //定义运行停止标志位sbit FontIRState=P1^5; //定义FontIR状态标志位sbit LeftIRState=P1^6; //定义LeftIR状态标志位sbit RightIRState=P1^7; //定义RightIRState状态标志位/*************完成状态指示灯定义*************/sbit S1=P3^2; //定义S1按键端口sbit S2=P3^4; //定义S2按键端口/*************完成按键端口的定义*************/sbit LeftLed=P2^0; //定义前方左侧指示灯端口sbit RightLed=P0^7; //定义前方右侧指示灯端口/*************完成前方指示灯端口定义*********/sbit LeftIR=P3^5; //定义前方左侧红外探头sbit RightIR=P3^6; //定义前主右侧红外探头sbit FontIR=P3^7; //定义正前方红外探头/*************完成红外探头端口定义***********/sbit M1A=P0^0; //定义电机1正向端口sbit M1B=P0^1; //定义电机1反向端口sbit M2A=P0^2; //定义电机2正向端口sbit M2B=P0^3; //定义电机2反向端口/*************完成电机端口定义***************/sbit B1=P0^4; //定义话筒传感器端口sbit RL1=P0^5; //定义光敏电阻端口sbit SB1=P0^6; //定义蜂鸣端口/*********完成话筒,光敏电阻,蜂鸣器.端口定义**/sbit IRIN=P3^3; //定义红外接收端口/*********完成红外接收端口的定义*************/#define ShowPort P2 //定义数码管显示端口extern void ControlCar(uchar CarType); //声明小车控制子程序void delayms(unsigned char x) //0.14mS延时程序{unsigned char i; //定义临时变量while(x--) //延时时间循环{for (i = 0; i<13; i++) {} //14mS延时}}void Delay() //定义延时子程序{ uint DelayTime=30000; //定义延时时间变量while(DelayTime--); //开始进行延时循环return; //子程序返回}void IR_IN() interrupt 2 using 0 //定义INT2外部中断函数{unsigned char j,k,N=0; //定义临时接收变量EX1 = 0; //关闭外部中断,防止再有信号到达delayms(15); //延时时间,进行红外消抖if (IRIN==1) //判断红外信号是否消失{EX1 =1; //外部中断开return; //返回}while (!IRIN) //等IR变为高电平,跳过9ms 的前导低电平信号。

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.}。

红外遥控器解码程序

红外线遥控器在家用电器和工业控制系统中已得到广泛应用,了解他们的工作原理和性能、进一步自制红外遥控系统,也并非难事。

1.红外线的特点人的眼睛能看到的可见光,若按波长排列,依次(从长到短)为红、橙、黄、绿、青、蓝、紫,如图1所示。

由图可见,红光的波长范围为0.62μm~0.76μm,比红光波长还长的光叫红外线。

红外线遥控器就是利用波长0.76μm~1.5μm之间的近红外线来传送控制信号的。

红外线的特点是不干扰其他电器设备工作,也不会影响周边环境。

电路调试简单,若对发射信号进行编码,可实现多路红外遥控功能。

2.红外线发射和接收人们见到的红外遥控系统分为发射和接收两部分。

发射部分的发射元件为红外发光二极管,它发出的是红外线而不是可见光,如图2所示。

常用的红外发光二极管发出的红外线波长为940nm左右,外形与普通φ5mm发光二极管相同,只是颜色不同。

一般有透明、黑色和深蓝色等三种。

判断红外发光二极管的好坏与判断普通二极管一样的方法。

单只红外发光二极管的发射功率约100mW。

红外发光二极管的发光效率需用专用仪器测定,而业余条件下,只能凭经验用拉距法进行粗略判定。

接收电路的红外接收管是一种光敏二极管,使用时要给红外接收二极管加反向偏压,它才能正常工作而获得高的灵敏度。

红外接收二极管一般有圆形和方形两种。

由于红外发光二极管的发射功率较小,红外接收二极管收到的信号较弱,所以接收端就要增加高增益放大电路。

然而现在不论是业余制作或正式的产品,大都采用成品的一体化接收头,如图3所示。

红外线一体化接收头是集红外接收、放大、滤波和比较器输出等的模块,性能稳定、可靠。

所以,有了一体化接收头,人们不再制作接收放大电路,这样红外接收电路不仅简单而且可靠性大大提高。

图3是常用两种红外接收头的外形,均有三只引脚,即电源正VDD、电源负(GND)和数据输出(Out)。

接收头的引脚排列因型号不同而不尽相同,图3列出了因接收头的外形不同而引脚的区别。

红外遥控解码

红外遥控解码作者:佚名来源:不详录入:Admin更新时间:2008-7-26 19:43:29点击数:3【字体:】编者按:以下是网友编写的遥控解码程序!一种用延时等待的解码方法,比较容易理解,但缺点是占用CPU运行时间,第二种方法用定时器和外中断的解码方法,初学不易理解,但优点也很明显,第二种方法如果能解决连发解码就比较完美,更完善的红外遥控解码程序,请参考本站TOPAV-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 ;相与,得到低四位码MOV C A,@A+DPTRMOV 1EH,A ;查表得表码存入1EHMOV A,1DHSWAP AANL A,#0FHMOV C 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-F END你的解码程序和我现在用的解码程序大体是一样的,我自己实际做了一下,发现按下遥控器,接收到红外信号后,数码管闪的厉害。

MSP430G2553定时器捕获之红外遥控器编码破解

MSP430G2553应用之红外遥控器按键编码的破解(ls_core)之前笔者利用51单片机、FPGA 和S3C2440对红外遥控器的编码破解过。

由于最近手里使用的单片机为MSP430G2553,同时也为了扩展LaunchPad 开发板按键所需,笔者还是将之前弄使用过的红外遥控器拿了起来。

使用遥控器作为开发板的按键使有个好处就是,占用一个IO 口即可扩展出很多按键。

但是,这样做的不足就是,占用了一个定时器和相应中断的资源。

所以,建议大家应该依据具体的项目工程而确定具体的解决方案。

好了进入正题。

一 红外时序在这里笔者探讨的问题是破解红外遥控器的编码,而不是对其编码。

所以,我们直接谈谈红外接收头1838T 接收到红外遥控器发送出的按键编码时序。

笔者在普源(RIGOL)示波器上观察到的时序波形如图1红外遥控器按键编码时序所示:图1 红外遥控器按键编码时序面对这样一列串行的序列,笔者将其测量、记录、整理并为其制作了一张时序图以便讲解,绘制的时序图如下图2 红外编码时序图 所示:ls _c o r e Q Q 1021480125 837278968图2 红外编码时序图接下来,让我们一起详细地探讨一下这一列时序波形。

首先当我们手中的遥控器的按键被按下时,其红外发射头会发射出红外线(该红外线载有数据信息,即对应的按键编码),然后红外接收头1838T 会接收该红外线对其解码还原载波信息。

所还原的信息即为按键编码的串行时序信息,如上图2所示。

那笔者所讲的破解编码是指的什么呢?很显然,笔者所讲的破解就是要把图2所示的串行数据转化成方便微机或者是人记忆识别的并行数据。

好,接着让我们一起分析一下这个时序。

⑴ 空闲状态:当红外接收头1838T 没有数据时(无按键按下,或是数据转化完成),红外接收头的输出引脚会一直保持高电平,即上图2所指的空闲状态。

⑵ 引导码:当红外接收头1838T 接收到了数据,其输出引脚首先会由空闲的高电平状态跳转为低电平状态,该低电平状态会保持9ms ,那么着9ms 的高电平状态即称之为引导码。

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