# include <reg52.h>
# include "LCD1602.h"
sbit red_jie= P3^2; // 紅外接收引腳,外部中斷 0 引腳
bit irpro_ok,irok;
unsigned char IRcord[4]; // 四個字節
unsigned char irdata[33]; // 32位 和 引導碼
unsigned char irtime;//紅外用全局變量
void TIM0init(void); // 定時器 0 初始化
void EX0init(void); // 外部中斷 0 初始化
void Ir_work(void); //紅外鍵值散轉程序
void Ircordpro(void);//紅外碼值處理函數
int main(void)
{
EX0init(); //初始化外部中斷
TIM0init();//初始化定時器
chushihua();
clear();
while(1)
{
if(irok)
{
Ircordpro();
irok=1;
}
if(irpro_ok)
{
Ir_work();
}
}
return 0;
}
void TIM0init(void)//定時器0初始化
{
TMOD=0x02;//定時器0工作方式2: 八位自動重裝模式 2^8=256-1 溢出后進入中斷
TH0=0x00; //重載值 255*irtime:兩個下降沿的時間
TL0=0x00; //初始化值
ET0=1; //開中斷
TR0=1; // 定時器 0的開關
}
void tim0_isr (void) interrupt 1 //using 1
{
irtime++; //用于計數2個下降沿之間的時間
}
void EX0_ISR (void) interrupt 0 //外部中斷0服務函數
{
static unsigned char i; //接收紅外信號處理
static bit startflag; //是否開始處理標志位
if(startflag)
{ // 范圍 越大,兼容性越好,但 誤差會增大
if(irtime<63&&irtime>=33)//引導碼 TC9012的頭碼時間:9ms+4.5ms (255us)*irtime:兩個下降沿的時間
i=0;
irdata[i]=irtime;//存儲每個電平的持續時間,用于以后判斷是0還是1
irtime=0;
i++;
if(i==33)
{
irok=1; // 數據發送結束,33個位 全部收集
i=0;
}
}
else // 程序運行 第一次先運行這里
{
irtime=0;
startflag=1;
}
}
void EX0init(void)
{
IT0 = 1; //指定外部中斷0下降沿觸發,INT0 (P3.2)
EX0 = 1; //使能外部中斷
EA = 1; //開總中斷
}
void Ir_work(void)//紅外鍵值散轉程序
{
switch(IRcord[2])//判斷第三個數碼值
{
case 0x0c:char_data(1,2,'1');break;//1 顯示相應的按鍵值
case 0x18:char_data(1,2,'2');break;//2
case 0x5e:char_data(1,2,'3');break;//3
case 0x08:char_data(1,2,'4');break;//4
case 0x1c:char_data(1,2,'5');break;//5
case 0x5a:char_data(1,2,'6');break;//6
case 0x42:char_data(1,2,'7');break;//7
case 0x52:char_data(1,2,'8');break;//8
case 0x4a:char_data(1,2,'9');break;//9
default:break;
}
irpro_ok=0;//處理完成標志
}
void Ircordpro(void)//紅外碼值處理函數
{
unsigned char i, j, k;
unsigned char cord,value;
k=1;
for(i=0;i<4;i++) //處理4個字節
{
for(j=1;j<=8;j++) //處理1個字節8位
{
cord=irdata[k]; // 255us * 7 =1.785ms 選取 1.125 和 2.25 的中間值
if(cord>7)//大于某值為1,這個和晶振有絕對關系,這里使用12M計算,此值可以有一定誤差
value|=0x80;
if(j<8)
{
value>>=1;
}
k++;
}
IRcord[i]=value;
value=0;
}
irpro_ok=1;//處理完畢標志位置1
}
|