十年專注單片機方案開發的方案公司英銳恩,分享3010T的解碼程序。英銳恩現提供服務產品涉及主控芯片:8位單片機、16位單片機、32位單片機及各類運算放大器等。
#include
#include
#include
//###############################################
//晶體頻率選擇參數(遙控脈沖寬度計數用)
#define FHZ 1 //12M=1,24M=2
//###############################################
//**********************************
//12M
#define FMS 6 //標準值
#define FMSL 5 //離散值
#define FMSH 7 //離散值
#define FMM 9 //標準值
#define FMML 8 //離散值
#define FMMH 10 //離散值
#define FMBL 11
#define FMBH 15
/*遙控器鍵值*/
unsigned char code ykbiao[64]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
0x08,0x09,0x0A,0x7F,0x8A,0x7F,0x8C,0x84,
0x85,0x86,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,
0x7F,0x7F,0x7F,0x7F,0x89,0x7F,0x0B,0x7F,
0x88,0x82,0x7F,0x7F,0x7F,0x7F,0x86,0x7F,
0x7F,0x7F,0x7F,0x81,0x87,0x7F,0x7F,0x7F,
0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,
0x83,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x8A};
unsigned char ykcd; //遙控接收碼(查表后碼)?
unsigned char bzjsok;
bit bzjsone;
static unsigned char ykcode; //遙控接收碼存放
static unsigned char ykbnum; //接收到的遙控位數
static unsigned char ykcodetemp; //遙控第一組接收碼存放
static unsigned char ykhz; //遙控頻率選擇用(用來確定在2組信號之間的中斷次數,12M一次,24M二次)
//12M 遙控接收碼標記 (=1為在定時器1中斷前剛剛接收完一組碼,=0表示沒有接收碼)
//24M 遙控接收碼標記 (=2為在定時器1中斷前剛剛接收完一組碼;=1表示第二次時鐘中斷;=0表示沒有接收碼)
//************************************************************
//外部中斷0,使用寄存器組2
//遙控接收分析
void int1() interrupt 0 using 2
{unsigned char ykbtc;
ykbtc=TH1/FHZ;
TH1=0;TL1=0;TR1=1;ET1=1;
ykhz=FHZ;
//由于每次發送2組一樣的代碼,其間隔為50*1.778ms,只能引起一次(12M)或二次(24M)定時器1中斷,此處設ykhz=FHZ
// 在定時器1第一次中斷時,當ykhz=FHZ,說明是剛剛接收了信號,若ykbit5=0暫存信號;若ykbit5=1,處理信號
//12M時 如果在外部中斷發生前再來一次定時中斷(此時ykhz=0),說明先前接收的為代碼的第二組,無法校驗,故刪掉
//24M時 如果在外部中斷發生前再來一次中斷(此時ykhz=1),ykhz--,不處理;再來一次中斷(ykhz=0) 說明先前接收
//的為代碼的第二組,無法校驗,故刪掉
switch(ykbnum) //ykbnum 接收的遙控信號位數
{case(0):ykbnum=1; //開始, 第一位 "1"
break;
case(1):if(((ykbtc>=FMSL)&&(ykbtc<=FMSH)))ykbnum=2; //第二位 同相 "1"
else ykbnum=0;
break;
case(2):if(((ykbtc>=FMSL)&&(ykbtc<=FMSH))||((ykbtc>=FMML)&&(ykbtc<=FMMH)))ykbnum=3; //第三位 同相 "1" 或反相 "0"
else ykbnum=0;
break;
case(3):if(((ykbtc>=FMSL)&&(ykbtc<=FMSH))||((ykbtc>=FMML)&&(ykbtc<=FMMH))){ykbnum=4;} //第四位 反相 "0" 或同相"1"
else ykbnum=0;
break;
default:if(ykbnum<7){if((ykbtc>=FMSL)&&(ykbtc<=FMSH))ykbnum++; //第五--七位 同相 "0"
else ykbnum=0;
}
else {if((ykbtc>=FMSL)&&(ykbtc<=FMSH))
{if(ykcode&1)ykcode=ykcode*2+1; //同相 遙控接收碼上一位為"1",則此位也為"1"
else ykcode=ykcode*2; //上一位為"0",此位也為"0"
ykbnum++;
}
//9的情況 上位1 此一位0 上位0 此二位0 1
// | "1"| "0" | "0"| "0"|"1" |
// __ __ __ ____ __
// __| |____| |__ __| |__| |__|
//檢測位址 | 9 | | 9 |
else if((ykbtc>=FMML)&&(ykbtc<=FMMH))
{if(ykcode&1){ykbnum++;ykcode=ykcode*2;} //9-反相 上一位為"1",此位為"0"
else {ykbnum+=2;ykcode=ykcode*2;ykcode=ykcode*2+1;}//上一位為"0",加2位,"0","1"
}
//11~15的情況 上位1 此二位0 1 上位0 不可能出現13
// | "1"| "0"|1 |
// __ ____
// __| |____| |__
//檢測位址 | 13 |
else if(ykbtc>FMBL&&ykbtc<fmbh){ykbnum+=2;ykcode=ykcode*2;ykcode=ykcode*2+1;}
else ykbnum=0;
}
}
}
//****************************************************************
//定時器中斷1 使用寄存器組3
//
void int2() interrupt 3 using 3
{if(ykhz==FHZ) // 在定時器1中斷時,當ykhz=FHZ,說明是剛剛接收了信號,若ykbit5=0暫存信號;ykbit5=1,處理信號
//24M時 如果在外部中斷發生前再來一次中斷(此時ykhz=1),不處理.再來一次中斷(ykhz=0)
//說明 先前接收的為代碼的第二組,無法校驗,故刪掉
{ykhz--;
if(bzjsone==0) //ykbit5=0, 說明接收的應該是第一組代碼
{if(ykbnum==13){ykcode*=2; //ykbnum=13,說明最后一位"0"丟失
ykcodetemp=ykcode; //第一組代碼暫存
bzjsone=1; //設第一組代碼以存標志位
}
else if(ykbnum==14){ykcodetemp=ykcode;bzjsone=1;}
else EX0=1;
ykbnum=0;
ykcode=0;
}
else{if(ykbnum==13) //以下應該為第二組代碼
{ykcode*=2; // ykbnum=13,說明最后一位"0"丟失 ykcd=ykbiao[ykcode*=2];
if(ykcode==ykcodetemp) //兩組代碼一樣,代碼有效
{//buf[0]=ykcode/0x10; //調試遙控過程中顯示接收的碼
//buf[1]=ykcode%0x10;
ykcd=ykbiao[ykcode];
bzjsok=1;
}
else {/*buf[0]=0;buf[1]=0;*/} //兩組代碼不一樣,代碼無效
}
else if(ykbnum==14)
{
if(ykcode==ykcodetemp)
{//buf[0]=ykcode/0x10;
//buf[1]=ykcode%0x10;
ykcd=ykbiao[ykcode];
bzjsok=1;
}
else {/*buf[0]=0;buf[1]=0;*/}
}
bzjsone=0;
ykbnum=0;
ykcode=0;
}
}
else {if(ykhz==0){bzjsone=0;ykbnum=0;ykcode=0;}
//12M時 如果在外部中斷發生前再來一次中斷(此時ykhz=0),說明先前接收的為代碼的第二組,
//無法校驗,故刪掉刪掉原先接收的代碼,清零
else ykhz--; //24m時允許二次時鐘中斷,ykhz-1,不作別的處理
}
}