一個(gè)紅外遙控接收頭解碼的列子 試驗(yàn)成功,51單片機(jī)+1602液晶顯示,完整的源碼下載地址是:http://www.torrancerestoration.com/bbs/dpj-19538-1.html 下面給出主要程序的預(yù)覽:
/**************************************************
*程序名稱: HS0038B紅外遙控鍵值顯示
*晶 振: 11.0592MHZ
*作 者: Kevin.Xie
*時(shí) 間: 2009\4\04
*地 址: 51hei
***************************************************/
/* HS0038B 知識點(diǎn)補(bǔ)充:
out腳在沒有接收到紅外時(shí)輸出高電平,接收到則輸出低電平。
紅外發(fā)射的編碼中,數(shù)據(jù)“0”和“1”是這樣定義的:
高電平0.565ms,低電平0.56ms,周期1.125ms,表數(shù)據(jù)“0”;
高電平0.565ms,低電平1.685ms,周期2.25ms,表數(shù)據(jù)“1”;
***************************************************/
#include <reg52.h>
#include <intrins.h>
#include "lcd1602.h"
sbit IR_GET = P3^2; //紅外接收頭數(shù)據(jù)輸入端
uchar hdata=0x10,ldata=0x10; //分別存放顯示的紅外編碼的高四位和低四位。
uchar RXDDATA[]={0x00,0x00,0x00,0x00};//存放接收到的四組紅外編碼
/************************************************************
約0.1ms延時(shí)函數(shù)
*************************************************************/
void delay(uchar x)
{
unsigned char i;
while(x--)
{
for (i = 0; i<10; i++);
}
}
/************************************************************
主函數(shù)
*************************************************************/
void main(void)
{
EA= 1; //允許總中斷中斷,
EX0= 1; //使能 INT0 外部中斷
IT0 =1; //外中斷0下降沿觸發(fā)
IR_GET=1; //I/O口初始化
display_1602();
while(1)
{
hangwei(1,7);
if(ldata<0x09)
wdat_1602(ldata+0x30);
else
wdat_1602(ldata+0x40);
if(hdata<0x09)
wdat_1602(hdata+0x30);
else
wdat_1602(hdata+0x40);
wdat_1602('H'); //H
}
}
/************************************************************
外部中斷0服務(wù)函數(shù)
*************************************************************/
void intt_0() interrupt 0 //下降沿觸發(fā):接收不到紅外時(shí)OUT高電平,接收到紅外時(shí)OUT低電平。
{
uchar four,one,num=0;
EX0 = 0; //關(guān)中斷0使能,防止處理過程中再接收紅外信號
delayms(2); //稍延時(shí)2ms,防干擾
if (IR_GET) //再檢測紅外接收腳(9ms的前導(dǎo)低電平),為高電平說明是干擾
{
EX0 =1; //使能中斷0
return; //退出中斷程序
}
while(!IR_GET); //等IR變?yōu)楦唠娖,跳過9ms的前導(dǎo)低電平信號。
while (IR_GET); //等 IR 變?yōu)榈碗娖,跳過4.5ms的前導(dǎo)高電平信號。
for (four=0;four<4;four++) //四組數(shù)據(jù)
{
for (one=0;one<8;one++) //每組數(shù)據(jù)8位
{
while (!IR_GET); //等 IR 變?yōu)楦唠娖?br />
while (IR_GET) //計(jì)算IR高電平時(shí)長(低電平時(shí)長是一樣的,不用計(jì))
{
delay(1); //計(jì)時(shí)
num++; //計(jì)時(shí)N次
if (num>=20) //20*0.1ms=2ms
{ //數(shù)據(jù)“1”的時(shí)長最長也就1.685ms,計(jì)數(shù)超過則數(shù)據(jù)錯(cuò)誤,退出中斷
EX0=1; //使能中斷0
return; //退出中斷
}
} //高電平計(jì)數(shù)完畢
RXDDATA[four]>>=1; //從低位讀出,隨著one的循環(huán)8次剛好讀出一字節(jié)
if(num>6&&num<20) // 20*0.1ms=2ms>1.685ms
RXDDATA[four]|=0x80; //數(shù)據(jù)“1”
num=0; //計(jì)時(shí)值清0,為下一位數(shù)據(jù)的計(jì)時(shí)做準(zhǔn)備
}//一組數(shù)據(jù)接收結(jié)束
}//全部四組數(shù)據(jù)接收結(jié)束
if (RXDDATA[2]!=~RXDDATA[3]) //檢測接收到的數(shù)據(jù)是否正確
{ //不正確則
EX0=1; //使能中斷0
return; //退出中斷
}
ldata=RXDDATA[2]&0x0F; //取鍵碼的低四位
hdata=RXDDATA[2]>>4; //取鍵碼的高四位
EX0 = 1; //處理完紅外接收,使能中斷0,退出中斷0
}