請問這個程序有問題嗎???好像解不了42位的,但是我的42位紅外發射也是自己做的,不知道是解碼問題,還是發射問題???謝謝。
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define RdCommand 0x01 //定義ISP的操作命令
#define PrgCommand 0x02
#define EraseCommand 0x03
#define Error 1
#define Ok 0
#define WaitTime 0x01 //定義CPU的等待時間
sfr ISP_DATA=0xe2; //寄存器申明
sfr ISP_ADDRH=0xe3;
sfr ISP_ADDRL=0xe4;
sfr ISP_CMD=0xe5;
sfr ISP_TRIG=0xe6;
sfr ISP_CONTR=0xe7;
sbit dula=P2^6; //申明U1鎖存器的鎖存端
sbit wela=P2^7; //申明U2鎖存器的鎖存端
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
uchar f;
#define Imax 14000 //此處為晶振為11.0592時的取值,
#define Imin 8000 //如用其它頻率的晶振時,
#define Inum1 1450 //要改變相應的取值。
#define Inum2 700
#define Inum3 3000
uchar Im[6]={0x00,0x00,0x00,0x00,0x00,0x00};
uchar Im1[2]={0x00,0x00};
uchar Im2[3]={0x00,0x00,0x00};
uchar show[6]={0,0,0,0,0,0};
//uchar Eim[4]={0,0,0,0};
unsigned long m,Tc;
unsigned char IrOK;
uchar IR;//分辨32位還是42位
void delay(uchar i)
{
uchar j,k;
for(j=i;j>0;j--)
for(k=125;k>0;k--);
}
void display()
{
dula=0;
P0=table[show[0]];
dula=1;
dula=0;
wela=0;
P0=0xfe;
wela=1;
wela=0;
delay(5);
P0=table[show[1]];
dula=1;
dula=0;
P0=0xfd;
wela=1;
wela=0;
delay(5);
}
/* ================ 打開 ISP,IAP 功能 ================= */
void ISP_IAP_enable(void)
{
EA = 0; /* 關中斷 */
ISP_CONTR = ISP_CONTR & 0x18; /* 0001,1000 */
ISP_CONTR = ISP_CONTR | WaitTime; /* 寫入硬件延時 */
ISP_CONTR = ISP_CONTR | 0x80; /* ISPEN=1 */
}
/* =============== 關閉 ISP,IAP 功能 ================== */
void ISP_IAP_disable(void)
{
ISP_CONTR = ISP_CONTR & 0x7f; /* ISPEN = 0 */
ISP_TRIG = 0x00;
EA = 1; /* 開中斷 */
}
/* ================ 公用的觸發代碼 ==================== */
void ISPgoon(void)
{
ISP_IAP_enable(); /* 打開 ISP,IAP 功能 */
ISP_TRIG = 0x46; /* 觸發ISP_IAP命令字節1 */
ISP_TRIG = 0xb9; /* 觸發ISP_IAP命令字節2 */
_nop_();
}
/* ==================== 字節讀 ======================== */
unsigned char byte_read(unsigned int byte_addr)
{
ISP_ADDRH = (unsigned char)(byte_addr >> 8);/* 地址賦值 */
ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
ISP_CMD = ISP_CMD & 0xf8; /* 清除低3位 */
ISP_CMD = ISP_CMD | RdCommand; /* 寫入讀命令 */
ISPgoon(); /* 觸發執行 */
ISP_IAP_disable(); /* 關閉ISP,IAP功能 */
return (ISP_DATA); /* 返回讀到的數據 */
}
/* ================== 扇區擦除 ======================== */
void SectorErase(unsigned int sector_addr)
{
unsigned int iSectorAddr;
iSectorAddr = (sector_addr & 0xfe00); /* 取扇區地址 */
ISP_ADDRH = (unsigned char)(iSectorAddr >> 8);
ISP_ADDRL = 0x00;
ISP_CMD = ISP_CMD & 0xf8; /* 清空低3位 */
ISP_CMD = ISP_CMD | EraseCommand; /* 擦除命令3 */
ISPgoon(); /* 觸發執行 */
ISP_IAP_disable(); /* 關閉ISP,IAP功能 */
}
/* ==================== 字節寫 ======================== */
void byte_write(unsigned int byte_addr, unsigned char original_data)
{
ISP_ADDRH = (unsigned char)(byte_addr >> 8); /* 取地址 */
ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
ISP_CMD = ISP_CMD & 0xf8; /* 清低3位 */
ISP_CMD = ISP_CMD | PrgCommand; /* 寫命令2 */
ISP_DATA = original_data; /* 寫入數據準備 */
ISPgoon(); /* 觸發執行 */
ISP_IAP_disable(); /* 關閉IAP功能 */
}
//外部中斷解碼程序
void intersvr1(void) interrupt 2 using 1
{
Tc=TH0*256+TL0; //提取中斷時間間隔時長
TH0=0;
TL0=0; //定時中斷重新置零
if((Tc>Imin)&&(Tc<Imax))
{
m=0;
f=1;
return;
} //找到啟始碼
if(f==1)
{
if(Tc>Inum1&&Tc<Inum3)
{
Im[m/8]=Im[m/8]>>1|0x80; m++;
}
if(Tc>Inum2&&Tc<Inum1)
{
Im[m/8]=Im[m/8]>>1; m++; //取碼
}
if(m>=16)
{
if(Im[0]!=~Im[1]) //判定32位或42位
{
if(m==42)
m=0;
f=0;
if((Im[3]<<2|Im[4]>>6)==~(Im[4]<<2|Im[5]>>6))
{
IrOK=1;
IR=42;
Im2[0]=Im[0];
Im2[1]=Im[1]>>3;
Im2[2]=Im[3]<<2|Im[4]>>6 ;
}
else
IrOK=0;
}
else {
if(m==32)
{
m=0;
f=0;
if(Im[2]==~Im[3])
{
IrOK=1;
IR=32;
Im1[0]=Im[0];
Im1[1]=Im[2];
}
else IrOK=0; //取碼完成后判斷讀碼是否正確
}
}
}
}
}
/*演示主程序*/
void main(void)
{
unsigned int a;
m=0;
f=0;
EA=1;
IT1=1;EX1=1;
TMOD=0x11;
TH0=0;TL0=0;
TR0=1;//ET0=1;
while(1)
{
if(IrOK==1)
{
SectorErase(0x2000);//擦除扇區
if(IR==32)
{
byte_write(0x2000,Im1[1]);//重新寫入數據
byte_write(0x2001,Im1[0]);
}
if(IR==42)
{
byte_write(0x2000,Im2[2]);//重新寫入數據
byte_write(0x2001,Im2[0]);
byte_write(0x2002,Im2[1]);
}
}
Im[2]=byte_read(0x2000);
show[1]=Im[2] & 0x0F; //取鍵碼的低四位
show[0]=Im[2] >> 4;
IrOK=0;
for(a=100;a>0;a--)
{
display();
}
}
}
|