📄 1838yaokongjiemac51.c
字号:
/************************************
红外遥控解码函数
遥控器发射距离:有效距离》8M ,用户码“00FF”
振荡频率:455KHZ
载波频率:37.92+-0.18KHZ
红外波长:940NM
功能键数:15个
适用环境:-10-+60
接收器:一体化红外接收器MDK-1838B
接收器输出脉冲宽度:Tpwl[500,700](600US典型值,Tpwh=[500,900]
波形图为:低电平脉冲宽度600US,高电平900US
//----------------------------------------------
键码分布图
1 2 3
4 5 6
7 8 9
* 0 #
EXIT ADD CALL
对应的码值表为
0X00 0X01 0X02
0X04 0X05 0X06
0X08 0X09 0X0A
0X0C 0X0D 0X0E
0X10 0X11 0X12
//-------------------------
/****************************************************************/
#define YKTh05MS 0XD8 //D8
#define YKTl05MS 0XF0 // F0
#define YKTh03MS 0XE8 //E8 3MS
#define YKTl03MS 0X90 // 90
#define YKTh004MS 0xFC //400US FCE0
#define YKTl004MS 0xE0
#define YKTh01MS 0xF8 //1MS F830
#define YKTl01MS 0X30
#define YKTh01MS5 0XF4 //1MS5 F448
#define YKTl01MS5 0X48
#define YKOneBit 0X80//数据1标识
#define YKZeroBit 0X00//数据0标识
#define YKNoBit 0XFF//无效数据
#define YKBit1 1
#define YKBit0 0
#define XKey 0x10//*
#define CALLKey 0x11//CALL
#define EXITKey 0x12//EXIT
#define ADDKey 0X13//ADD
#define BKey 0x14//#
#define BadPro 0x00
#define SecussPro 0x88
#define EXITPro 0xff
#define Secuss6 0x60
/*************************************************************/
/**********************************************************
*函数功能:将码值转换成数值
*入口参数:码值
*返回值:已转换的值
*********************************************************/
INT8U YKCodeValueTRA(INT8U CodeNum)
{
switch (CodeNum)
{
case 0X00:
return(0x01); //1
break;
case 0x01:
return (0x02); //2
break;
case 0X02:
return(0x03); //3
break;
case 0x04:
return (0x04); //4
break;
case 0X05:
return(0x05); //5
break;
case 0x06:
return (0x06); //6
break;
case 0X08:
return(0x07); //7
break;
case 0x09:
return (0x08); //8
break;
case 0X0A:
return(0x09); //9
break;
case 0x0C:
return (XKey); //*
break;
case 0X0D:
return(0x00); //0
break;
case 0x0E:
return (BKey); //#
break;
case 0X10:
return(EXITKey); //EXIT
break;
case 0x11:
return (ADDKey); //ADD
break;
case 0X12:
return(CALLKey); //CALL
break;
default: return (YKNoBit);//无效数据
break;
}
}
/*************************************************************
* YKt0initial()
*函数功能:定时器0初始化,T0与普通51一样,不倍频
*入口参数:无
*返回:无 (9MS检测)
*************************************************************/
void YKt0initial(void)
{TF0 = 0;
TR0 = 0;
TMOD = (TMOD|0X0F)&0XF1;//不影响定时器1,定时器0工作模式为M1,M0=01
//------AUXR = 0X5F; //T0不倍频,与普通51一致 ,当作波特率发生器时,T1要倍频
// AUXR = 0X0F; //T0不倍频,与普通51一致
CKCON = 0X00;//T0,T1设置为普通12T时钟
TH0 = YKTh05MS;
TL0 = YKTl05MS;
TR0 = 1;
}
/************************************************************
* RYKDt0start()
*函数功能:启动定时器0
*入口参数:定时时间值
*返回:无
*************************************************************/
void YKt0start(INT8U YKTH0,INT8U YKTL0)
{ TR0 = 0;
TF0 = 0;
TH0 = YKTH0;
TL0 = YKTL0;
TR0 = 1;
}
/**************************************************************
RYKDt0Off
关定时器0
函数功能:关定时器0,读出TH0,TL0
入口参数:无
返回:无
**************************************************************/
void YKt0Off(void)
{
TF0 = 0;
TR0 = 0;
}
//---------抽样判断电平信号是1还是0--------------------
bit YKbitCHK(void)
{
INT8U YKcont1;
INT8U YKcont0;
YKcont1 = 0xff;
YKcont0 = 0xff;
while (1){
//WDT_CONTR=0x3C;
if (YKDATA==1)
YKcont1--;
else
YKcont0--;
if (YKcont1<0xF8)
return (YKBit1);
else
if (YKcont0<0xF8) //e8
return (YKBit0);
else continue;
}
}
//----------检测560US低电平是否有效函数
//-------调用前已经启动T0
bit YKLowbitCHK(void)
{
YKt0start(YKTh004MS,YKTl004MS);//检测低电平的时间
while (TF0==0){
if (YKbitCHK()==YKBit1) { //低电平时间不够400US,则退出
YKt0Off();
return(ERR); }
}
YKt0start(YKTh004MS,YKTl004MS);//等待高电平
while (YKbitCHK()==YKBit0){
if (TF0==1) { //低电平总时间超过800US,则退出
YKt0Off();
return(ERR); }
}
return (OK);
}
/**************************************************************
YKCODEbitCHK
函数功能:读一个键值码位,
入口参数:无
返回:读到数据1,1;数据0,返回0;不对,返回0FF
使用时必须先调用 YKHeadCHK()函数
**************************************************************/
INT8U YKCODEbitCHK(void)
{
if (YKLowbitCHK()==ERR){ //检测低电平时间是否正确!
YKt0Off();
return(YKNoBit); }
//----检测高电平时间
YKt0start(YKTh004MS,YKTl004MS);//检测高电平的时间
while (TF0==0){
if (YKbitCHK()==YKBit0) { //高电平时间不够400US,则退出
YKt0Off();
return(YKNoBit); }
}
YKt0start(YKTh004MS,YKTl004MS);//等待低电平
while (YKbitCHK()==YKBit1){
if (TF0==1) //高电平总时间超过800US,则检测是否是数据1
break;
}
if (TF0!=1){
YKt0Off();
return(YKZeroBit); //高电平的时间在400-800US之间,则是数据0
}
else{
YKt0start(YKTh01MS5,YKTl01MS5); //1.5MS内检测高电平!
while (YKbitCHK()==YKBit1){
if (TF0==1){
YKt0Off();
return(YKNoBit);
}
}
YKt0Off();
return ( YKOneBit);
}
}
/*************************************************************
* YKHeadCHK()
*函数功能:找遥控的引导码和用户码,引导码为9MS低电平+4.5MS高电平+“用户码16位”
用户码默认为 00FF
*入口参数:无
*返回:正确OK,无效ERR,
注:红外发射数据的格式是:引导码9MS+4.5MS关断时间+用户码+键值+键值反码
************************************************************/
bit YKHeadCHK(void)
{ INT8U YKcon;//计数器
if (YKbitCHK()==YKBit0){
YKt0initial();
while(TF0==0){ //低电平的时间要是9MS,不够9MS则退出
if (YKbitCHK()==YKBit1){
YKt0Off();
return(ERR); }
}
YKt0start(YKTh05MS,YKTl05MS); //等待变为高电平
while (YKbitCHK()==YKBit0){
if (TF0==1){
YKt0Off();
return(ERR);
} //低电平时间超时,则退出!
}
//-------------------------检测关断时间
YKt0start(YKTh03MS,YKTl03MS);//引导码9MS后,检测4.5MS的关断时间(高电平)
while (TF0==0) { //高电平时间4.5MS
if (YKbitCHK()==YKBit0){
YKt0Off();
return(ERR); }
}
YKt0start(YKTh03MS,YKTl03MS); //等待变为低电平
while (YKbitCHK()==YKBit1){
if (TF0==1){
YKt0Off();
return(ERR);
} //高电平时间超时,则退出!
}
//-开始读用户码00FF
for (YKcon=0;YKcon<8;YKcon++){
if (YKCODEbitCHK()!=YKZeroBit){
YKt0Off();
return (ERR); }
}
for (YKcon=0;YKcon<8;YKcon++){
if (YKCODEbitCHK()!=YKOneBit) {
YKt0Off();
return (ERR); }
}
return (OK);
}
return (ERR);
}
/********************************************************************
YKCODEByte()
函数功能:解键值码 ,从低位到高位发送
入口参数:无
出口参数:返回键值,无效返回0XFF
********************************************************************/
INT8U YKCODEByte(void)
{
INT8U YKCBCont;//计数器
INT8U YKCBDataTmp;
INT8U YKCBDataJM;////键值码
INT8U YKCBDataFM; //键值反码
YKCBDataTmp=0xFF;
YKCBDataFM=0xFF;
YKCBDataJM=0xFF;
if (YKHeadCHK()==OK){
//先解键值码
for (YKCBCont=0x00;YKCBCont<8;YKCBCont++){
YKCBDataTmp=YKCODEbitCHK();
if (YKCBDataTmp!=YKNoBit){
YKCBDataJM=(YKCBDataJM>>1)&0x7F;
YKCBDataJM=YKCBDataJM|YKCBDataTmp;}
else{
YKt0Off();
return (YKNoBit);
}
}
//---再解键值反码
for (YKCBCont=0x00;YKCBCont<8;YKCBCont++){
YKCBDataTmp=YKCODEbitCHK();
if (YKCBDataTmp!=YKNoBit)
YKCBDataFM=((YKCBDataFM>>1)&0x7f)|YKCBDataTmp;
else{
YKt0Off();
return (YKNoBit);
}
}
if (YKCBDataJM==~YKCBDataFM){
SFDisplayOK();//按键解码成功提示
return(YKCodeValueTRA(YKCBDataJM)); }
else
return (YKNoBit);
}
return (YKNoBit);
}
//-------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -