📄 ir.c
字号:
/*
* FILE:
* ir.c (rev. 1.0 - 21.04.2006)
*
* PROJECT:
* IR Learn System
*
* DESCRIPTION:
* See "ir.h" for description
*
*/
#include "AT89C51ED2.h"
#include "types.h"
#include "ir.h"
#include "eeprom.h"
#define TMR2_Restart TR2=0; TF2=0; TL2=IR_TMR_Lo; TH2=IR_TMR_Hi; TR2=1;
volatile BOOL IR_StartCatch; // Start IR catch flag
volatile U8 IR_CodeLen; // Length of captured sequence (bits)
volatile U8 IR_KeyLen; // Length of key sequence
volatile U8 IR_KeyPtr; // Pointer to current key
xdata U8 IR_CodeSeq[8]; // Captured code
xdata U8 IR_tmpSeq[8]; // Captured code (temporary version)
xdata U8 IR_MaskSeq[8]; // Captured code mask
xdata U8 IR_KeySeq[16]; // Keyboard sequence
U16 IR_len0; // Length of last 0 pulse of IR receiver
U16 IR_len1; // Length of last 1 pulse of IR receiver
U16 IR_tmp; // Length of current 0 pulse of IR receiver
// Initialize IR data and EXT0 interrupt
void IR_Init(void) {
IR_StartCatch=0;
IR_CodeLen=0; IR_KeyLen=0; IR_KeyPtr=0;
IR_len0=0; IR_len1=0;
EA=0; // Disable system interrupts
IT0=1; // Edge-triggered interrupt
IPH0|=1; IPL0|=1; // Set highest priority for INT0 interrupt
T2CON=0; T2MOD=0; // Initialize Timer 2
EA=1; EX0=1; // Enable INT0 interrupt
}
// TMR2 Interrupt Routine
void TMR2_Interrupt(void) interrupt 5 using 3 {
TR2=0; TF2=0; ET2=0;
IR_StartCatch=0;
// Accept only codes with at least 10 transitions
if (IR_CodeLen<10) {IR_CodeLen=0; return;}
}
// External INT0 Interrupt Routine
void IR_Interrupt(void) interrupt 0 using 3 {
if (IR_StartCatch==0) return;
TR2=0;
IR_tmp=TH2; IR_tmp<<=8; IR_tmp+=TL2;
TMR2_Restart
EA=0;
if (TF2) {TF2=0; IR_StartCatch=0; IR_CodeLen=0; EA=1; return;}
IR_tmp-=IR_TMR_Val;
if (IR_CodeLen==0) {
IR_len0=0; IR_len1=0;
for (IR_tmp=0;IR_tmp<8;IR_tmp++) IR_CodeSeq[IR_tmp]=0;
}
else {
if (IR_tmp<IR_len1) IR_len1-=IR_tmp;
else IR_len1=IR_tmp-IR_len1;
// Check difference (accuracy: 25%)
if ((IR_tmp>>2)>IR_len1) IR_CodeSeq[IR_CodeLen>>3]|=(0x80>>(IR_CodeLen&7));
IR_len1=IR_tmp; IR_CodeLen++;
}
while (TF2==0) {
P3_2=1;
if (P3_2==1) break;
}
TR2=0;
// if low pulse is too long (>20 msec)
if (TF2) {TF2=0; IR_StartCatch=0; IR_CodeLen=0; EA=1; return;}
// if 64 pulses were catched
if (IR_CodeLen>=64) {IR_StartCatch=0; EA=1; return;}
IR_tmp=TH2; IR_tmp<<=8; IR_tmp+=TL2;
IR_tmp-=IR_TMR_Val;
if (IR_tmp<IR_len0) IR_len0-=IR_tmp;
else IR_len0=IR_tmp-IR_len0;
// Check difference (accuracy: 25%)
if ((IR_tmp>>2)>IR_len0) IR_CodeSeq[IR_CodeLen>>3]|=(0x80>>(IR_CodeLen&7));
IR_len0=IR_tmp; IR_CodeLen++;
TMR2_Restart
EA=1; ET2=1;
}
// Right-click Menu->IR Assign
void IR_Assign() {
U8 i,j;
MENU_pFunc=NULL;
MENU_pMenuBack=NULL;
i=GetDigit(1); // Get IR sequence number
if (i==0xFF) return;
if (GetIRseq()==0xFF) return;
for (j=0;j<16;j++) {
EEPROM_Write(MAP_IR_Seq+i*16+j,buf[j]);
if (buf[j]==0) break;
}
}
// Right-click Menu->IR Learn
void IR_Learn() {
U8 i,j,k;
MENU_pFunc=NULL;
MENU_pMenuBack=NULL;
i=GetDigit(1); // Get IR sequence number
if (i==0xFF) return;
for (j=0;j<8;j++) {
IR_CodeSeq[j]=0;
IR_MaskSeq[j]=0;
}
IR_CodeLen=0;
for (j=0;j<5;) {
if (GetIRcode(j)==0xFF) return;
if (IR_CodeLen!=0) {
LED_Msg_Blink();
if (j!=0)
for (k=0;k<8;k++) IR_MaskSeq[k]|=(IR_CodeSeq[k]^IR_tmpSeq[k]);
for (k=0;k<8;k++) IR_tmpSeq[k]=IR_CodeSeq[k];
j++;
}
TMR_Delay(10000);
}
// Calculate number of mask bit
k=0;
for (j=0;j<IR_CodeLen;j++) {
if (IR_MaskSeq[j>>3]&(0x80>>(j&7))) k++;
}
// if less than 25%
if (k<(IR_CodeLen>>2)) {
EEPROM_Write(MAP_IR_Cmd+i*18,IR_CodeLen);
for (j=1;j<9;j++) {
EEPROM_Write(MAP_IR_Cmd+i*18+j,IR_CodeSeq[j-1]);
EEPROM_Write(MAP_IR_Cmd+i*18+9+j,~IR_MaskSeq[j-1]);
}
print(MSG_IRLearned[MENU_Lang]);
}
else print(MSG_IRProblem[MENU_Lang]);
IR_CodeLen=0;
TMP_Timer=20000;
i=0;
while(i==0 && TMP_Timer) i=getkey();
}
// Check current captured IR code with learned codes
void IR_Check() {
U8 i,j,k;
if (IR_CodeLen<10) {
IR_CodeLen=0;
IR_StartCatch=1;
return;
}
for (i=0;i<10;i++) {
j=EEPROM_Read(MAP_IR_Cmd+i*18);
if (j!=IR_CodeLen) continue;
for (j=0;j<8;j++) {
k=EEPROM_Read(MAP_IR_Cmd+i*18+10+j);
if ((IR_CodeSeq[j]&k)!=(EEPROM_Read(MAP_IR_Cmd+i*18+j+1)&k)) break;
}
if (j==8) break;
}
if (i==10) {
IR_CodeLen=0;
LED_Arm_Blink();
IR_StartCatch=1;
return;
}
IR_CodeLen=0;
LED_Msg_Blink();
// load key sequence
for (j=0;j<16;j++) {
k=EEPROM_Read(MAP_IR_Seq+i*16+j);
IR_KeySeq[j]=k;
if (k==0) break;
if (k==0xFF) {
IR_KeySeq[j]=0;
break;
}
}
IR_KeyLen=j; IR_KeyPtr=0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -