|
這是為什么啊?????以下是紅外解碼程序:
//lcd1602顯示鍵值
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
//定義數(shù)組
uchar HL_Time[33]={0};//存儲高低電平的時間
uchar BYTE[4]={0};//存放碼(用戶碼,用戶反碼,數(shù)據(jù)碼,數(shù)據(jù)反碼)
uchar table[16]={"IR_CODE:0x "};//lcd2602初始化顯示的
//標志位
bit decode_ok = 0;//解碼標志位。decode_ok=1解碼成功,decode-ok=0解碼失敗
bit trans_ok = 0;//時間轉換標志位。trans_ok=1轉換成功,trans_ok =0轉換失敗
bit head_ok = 0;//引導碼接受標志位,head_ok=1引導碼接受成功,head_ok=0 引導碼接受失敗
bit head_start= 0; //引導碼開始接收標志位
//定義變量
uchar Timer0_Count=0; //時間計數(shù)器,Timer0_Count每加1,時間經(jīng)過250us
uchar Init0_Count=0;//外部中斷0計數(shù)器,Init0_Count每加1,就經(jīng)歷了一次下降沿
//位定義led接口
sbit lcd_E=P2^7;
sbit lcd_RS=P2^6;
sbit lcd_RW=P2^5;
void delayms(uint z)
{
uint x,y;
for(x=1;x<z;x++)
for(y=1;y<110;y++);
}
void write_commend(uchar commend)
{
lcd_RS=0;
lcd_RW=0;
P0=commend;
delayms(2);
lcd_E=1;
delayms(5);
lcd_E=0;
delayms(2);
}
void write_data(uchar date)
{
lcd_RS=1;
lcd_RW=0;
P0=date;
delayms(2);
lcd_E=1;
delayms(5);
lcd_E=0;
delayms(2);
}
//1602顯示字符串函數(shù)(y=1時顯示在第一行,y=2顯示在第二行。x表示從第x個開始顯示)
void write_str(uint y,uint x,uchar * str)
{
uint i;
if(y==1)
{
write_commend(0x80+x-1);
for(i=0;i<16;i++)
write_data(*(str+i));
}
else
{
write_commend(0x80+0x40+x-1);
for(i=0;i<16;i++)
write_data(*(str+i));
}
}
//輸入字符函數(shù)(y=1時顯示在第一行,y=2顯示在第二行。x表示從第x個開始顯示)
void write_char(uint y,uint x,uchar value)
{
if(y==1)
{
write_commend(0x80+x-1);
write_data(value);
}
else
{
write_commend(0x80+0x40+x);
write_data(value);
}
}
//lcd顯示16進制數(shù)函數(shù)
void write_16(uint x,uint y,uchar dat)
{
uchar j;
j=dat>>4; //把要顯示內(nèi)容的高4位移到低4位上
if(j<10) //0-F在ASCII碼中并不連續(xù),所以要分開處理
{
j+='0'; //0-9的數(shù)據(jù)以0為基點進行偏移即可
}
else
{
j=j-10+'A'; //A-F的數(shù)據(jù)以A為基點進行偏移即可
}
write_char(x,y,j); //在第x行的第y列顯示高4位的十六進制數(shù)字
j=dat&0x0F; //把要顯示內(nèi)容的高4位屏蔽掉,保留低4位
if(j<10) //0-F在ASCII碼中并不連續(xù),所以要分開處理
{
j+='0'; //0-9的數(shù)據(jù)以0為基點進行偏移即可
}
else
{
j=j-10+'A'; //A-F的數(shù)據(jù)以A為基點進行偏移即可
}
write_char(x,y+1,j); //在第x行的第y+1列顯示低4位的十六進制數(shù)字
}
void init_lcd()
{
lcd_E=0;
write_commend(0x38);
write_commend(0x0e);
write_commend(0x06);
write_commend(0x01);
write_commend(0x80);
write_str(1,1,&table);
}
//初始化外部中斷0
void Init_EX0()
{
IT0 = 1;//外部中斷0下降沿觸發(fā)方式
EX0 = 1;//開外部中斷0
EA = 1;//開總中斷
}
//初始化定時器0
void Init_T0()
{
TMOD=0X01;//設置定時器0位工作方式1
TH0=(65535-250*(11059200/12000000))/256; //設定計數(shù)初值,計數(shù)250us
TL0=(65535-250*(11059200/12000000))%256; //設定計數(shù)初值,計數(shù)250us
ET0=1; //允許定時器0中斷
TR0=1;//開定時器0
}
//將HL_Time[]數(shù)組中的時間轉化為邏輯1或邏輯0;
void Transform_Time()
{
uint i,j;
uint num=1;//等于1是為了拋棄HL_Time[0]這個元素,因為這個元素存放的是引導碼的時間
uchar IR_CODE=0; //存儲接收到的碼
for(j=0;j++;j<4) //兩個for循環(huán),循環(huán)一次接收好一字節(jié)的數(shù)據(jù),循環(huán)4次,接收一字節(jié)時循環(huán)8次
{
for(i=0;i<8;i++)
{
if(HL_Time[num]>7) //接收1
IR_CODE |= 0X80;
else //接收0
IR_CODE = IR_CODE;
IR_CODE >>= 1;
num++;
}
BYTE[j]=IR_CODE;
IR_CODE=0x00;//得到一個數(shù)據(jù)后清零以便接收下一個數(shù)據(jù)
}
if(BYTE[2]=~BYTE[3])//判斷數(shù)據(jù)是否正確
trans_ok=1;
}
//主函數(shù)
void main()
{
init_lcd();
Init_EX0();
Init_T0();
while(1)
{
if(decode_ok)//解碼成功
{
decode_ok=0;//清零以備下次接收
Transform_Time();//開始執(zhí)行時間轉換
}
if(trans_ok)//時間轉換成功
{
trans_ok=0;//清零以備下次接收
write_16(1,11,HL_Time[2]);//顯示數(shù)據(jù)碼
}
}
}
//紅外中斷函數(shù)
void IR_Decode() interrupt 0
{
if(head_start==0)//按下按鍵后就開始進入第一次中斷
{
head_start=1;//標志著引導碼接受開始
Timer0_Count=0;//時間計數(shù)器清零
}
else if(head_start==1)//下面開始解碼
{
if((Timer0_Count>=52)&&(Timer0_Count<=56))//引導碼時間為13.5ms即13500us,是250us的54倍,故把Time_Count規(guī)定在51到57這個區(qū)間,提高容錯率
{
Init0_Count=0;//中斷計數(shù)器清零
}
HL_Time[Init0_Count]=Timer0_Count;//給時間數(shù)組賦值
//因為每過250us Timer0_Count就會增加1,而只有當外部中斷0產(chǎn)生中斷時Timer0_Count的值才會被
//記錄到HL_Time[]數(shù)組里,所以如果數(shù)組中的元素在3~5表示這次外部中斷接收的是0,
//在8~10表示此次外部中斷接收的是1
//也可以以6位分水嶺。Timer0_Count大于6是1,小于6是0
//邏輯0持續(xù)時間1.12ms,1120/250=4.48
//邏輯1持續(xù)時間2.25ms,2250/250=9
Timer0_Count=0;//為下存時間值做準備
Init0_Count++;
if(Init0_Count==33)
{
Init0_Count=0;//中斷計數(shù)清零
decode_ok=1;//存時間值的任務成功,即解碼成功
head_start=0;//清零以備下次解碼任務的完成
}
}
}
//定時器0中斷函數(shù)
void Timer0()interrupt 1
{
TH0=(65535-250*(11059200/12000000))/256; //設定計數(shù)初值,計數(shù)250us
TL0=(65535-250*(11059200/12000000))%256; //設定計數(shù)初值,計數(shù)250us
Timer0_Count++;
} |
|