SAA3010紅外遙控接收的C程序源代碼
// 用單片機進行紅外遙控接收已經(jīng)是很平常的應用了,基本上稍懂單片機就可以自己編//
// 但往往很多人編的程序要么繁瑣,要么占用大量存儲器、CPU資源, //
// 而且用于現(xiàn)場時還可能因為受到干擾而不能正常工作 //
// 真正試過的都會發(fā)現(xiàn),要想編個真正好用的接收程序不是那么簡單的 //
// 其實,所有遙控芯片的編碼都是比較簡單的(有限的狀態(tài)),只要仔細分析它的編碼//
// 我們完全可以用狀態(tài)機的方式來處理各種可能的情況,甚至從被干擾的雜亂波形中找出正確的編碼//
// 下面是基于狀態(tài)機的SAA3010紅外遙控接收程序示例: //
//--------------------------------------------------------------------------//
// //
// (c) Copyright 2001-2003 xuwenjun //
// All Rights Reserved //
// V1.00 //
//--------------------------------------------------------------------------//
//標 題: SAA3010遙控芯片接收程序 //
//文件名: ir_3010.c //
//版 本: V1.00 //
//修改人: xuwenjun E-mail:xuwenjun@21cn.com //
//日 期: 03-06-14 //
//描 述: SAA3010遙控芯片接收程序 //
//--------------------------------------------------------------------------//
//老版本: 無 老版本文件名: //
//創(chuàng)建人: xuwenjun E-mail:xuwenjun@21cn.com //
//日 期: 03-06-14 //
//描 述: SAA3010遙控芯片接收程序 //
// 當ykok=1時,ykcode中的數(shù)據(jù)就是接收到的遙控碼(14位的最后8位) //
//--------------------------------------------------------------------------//
//占用以下資源: //
// 1. 遙控使用外部中斷0,接P3.2口 //
// 2. 遙控使用定時計數(shù)器1 //
// 3. 5.1字節(jié)data RAM //
// 4. 293字節(jié) code ROM //
//--------------------------------------------------------------------------//
//聲 明: //
// 以下代碼僅免費提供給學習用途,但引用或修改后必須在文件中聲明出處. //
// 如用于商業(yè)用途請與作者聯(lián)系. E-mail:xuwenjun@21cn.com //
// 有問題請mailto xuwenjun@21cn.com 歡迎與我交流! //
//--------------------------------------------------------------------------//
#i nclude <reg52.h>
#define uchar unsigned char
// SAA3010存儲定義
uchar ykcode; //遙控碼(14位的最后8位)
bit ykok; //遙控數(shù)據(jù)有效標志
uchar ykbnum; //遙控已接收位數(shù)
uchar ykbtc; //遙控中斷時 ykbtc=TH1
uchar ykdelay; //遙控延時接收
bdata uchar ykcodetemp; //遙控臨時碼
sbit ykcodetemp0=ykcodetemp^0;
// SAA3010端口定義
//sbit YKIO=P3^3; //遙控使用外部中斷0,接P3.2口
// SAA3010函數(shù)原型: 公用函數(shù)
void YkInit(void); //遙控接收初始化
unsigned char YkGetcode(void); //返回遙控碼
bit YkTest(void); //檢查有無遙控信號
/*
// SAA3010函數(shù)原型: 公用函數(shù)
extern void YkInit(void); //遙控接收初始化
extern unsigned char YkGetcode(void); //返回遙控碼
extern bit YkTest(void); //檢查有無遙控信號
*/
/*
// 外部引用四位LED顯示模塊 //
extern unsigned char code tab_duam[]; //位映射
extern void led_send(unsigned char d); //發(fā)送子程序
extern void led_cls(void); //清除顯示
extern void led_show(unsigned int n); //顯示數(shù)字子程序
extern void led_showhh(unsigned int n); //16進制顯示數(shù)字子程序
extern void led_test(void); //4LED測試函數(shù)
extern void led_delay(unsigned char ms); //延遲函數(shù)
*/
// SAA3010函數(shù)內容
void YkInit(void) //遙控接收初始化
{
TMOD=0x11; //TMOD T0,T1均選用方式1(16位定時)
SCON=0x00;
TH1=0;
TL1=0;
IE|=0x89; //SETB EX0 0x1 外部中斷 0 允許
//SETB ET0 0x8 定時器 1 中斷允許
//SETB EA 0x80 開中斷
IP|=0x01; //SETB INT0 中斷優(yōu)先
TCON |= 0x41; //TCON EX0下降沿觸發(fā),啟動T1 //
ykbnum=0;
ykcodetemp=0;
ykdelay=0;
}
unsigned char YkGetcode(void) //返回遙控碼
{
return(ykcode);
}
bit YkTest(void) //檢查有無遙控信號
{
return(ykok);
}
void intx0() interrupt 0 using 2 //遙控使用外部中斷0,接P3.2口
{
ykbtc=TH1;TH1=0;TL1=0;TR1=1;ET1=1;
switch(ykbnum)
{
case(0):
ykbnum=1;
break;
case(1):
if(ykbtc==6)ykbnum=2;
else ykbnum=0;
break;
case(2):
if(ykbtc==6||ykbtc==9)ykbnum=3;
else ykbnum=0;
break;
case(3):
if(ykbtc==9||ykbtc==6){ykbnum=4;}
else ykbnum=0;
break;
default:
if(ykbnum<7)if(ykbtc==6)ykbnum++;
else ykbnum=0;
else
{
if(ykbtc==6){if(ykcodetemp0)ykcodetemp=ykcodetemp*2+1;
else ykcodetemp=ykcodetemp*2;
ykbnum++;
}
else if(ykbtc==9){ if(ykcodetemp0){ykbnum++;ykcodetemp=ykcodetemp*2;}
else {ykbnum+=2;ykcodetemp=ykcodetemp*2;ykcodetemp=ykcodetemp*2+1;}
}
else if(ykbtc>11&&ykbtc<15)
{ykbnum+=2;ykcodetemp=ykcodetemp*2;ykcodetemp=ykcodetemp*2+1;}
else if(ykbtc>30){EX0=1;}
else ykbnum=0;
}
}
}
void intt1() interrupt 3 using 3 //遙控使用定時計數(shù)器1
{
if(ykdelay){ykdelay--;EX0=0;} //ykdelay不為0暫停接收
else
{
if(ykbnum==13) //遙控碼最后一位為0,補0
{
ykcode=ykcodetemp*=2;
ykdelay=3;
EX0=0; //暫停接收
ykok=1; //遙控數(shù)據(jù)有效
}
else if(ykbnum==14) //遙控碼最后一位為1,不用補
{
ykcode=ykcodetemp;
ykdelay=3;
EX0=0; //暫停接收
ykok=1; //遙控數(shù)據(jù)有效
}
else EX0=1; //ykbnum不為13,14接收無效,繼續(xù)接收
ykbnum=0;
ykcodetemp=0;
}
}
/*
// SAA3010測試主函數(shù)內容
main()
{
YkInit();
led_test(); //4LED測試函數(shù)
for(;1;) //主程序
{
if (YkTest())
led_showhh(YkGetcode());
led_delay(10);
}
}