本次使用双边沿中断解码,定时器设定100us
1:紫色脚-解码完成之后进入io翻转,直观知道在哪帧数据解的码,对比数据是否正确
2:蓝色脚-每bit位进翻转,知道每bit位哪里有没有进入解码或者杂波退出
3:绿色脚-外部中断解码脚:得到码值知道每帧数据值,实现解码

1:解码
要解码之前先了解波形,本次波形步骤为:起始位--24位码值--结束位
1.1:起始位
高电平约为295us 低电平约为9.5ms 周期约为9.8ms

1.2:码值
每位码值周期:
高电平约为930us 低电平约为320us 周期约为1.25ms 为高电平
高电平约为915us 低电平约为320us 周期约为1.23ms 为低电平


1.3:结束位

低电平约为38ms,高电平约10ms
2:代码实现
知道了波形,开始写函数
2.1:初始化外部中断
cpp
/***********************************************************************************
函数名称: Timer4_Init
功能描述: 外部中断
输入参数: 无
返 回 值: 无
***********************************************************************************/
void INT4_init(void)
{
P15F = INPUT; //P15设置为输入功能
EP2CON = EPIE(1) | EPPL(2) | EPPSEL(P15_INDEX); //双边沿检测
INT4EN = 1; //外部中断4中断使能
}
2.2:定时器初始化
cpp
/***********************************************************************************
函数名称: Timer0_Init
功能描述: 100us
输入参数: 无
返 回 值: 无
***********************************************************************************/
void Timer0_Init(void)
{
TMOD = (TMOD&0xFC)|0x00; //模式选择: 定时器0,模式0。
TH0 = TH_VAL; //高8位装初值
TL0 = TL_VAL; //低8位装初值
TR0 = 1; //定时器0使能
ET0 = 1; //定时器0中断使能
}
2.3:初始化结构体
cpp
typedef struct
{
uint8_t Pair; //配对标志位
uint8_t HFlag; //高位标志位
uint8_t LFlag; //低标志位
uint8_t C_Flag; //记录位数
uint8_t S_Flag; //状态标志
uint8_t Bits; //移位
uint8_t HCycleFalg; //高周期标志位
uint8_t LCycleFalg; //低周期标志位
uint32_t HTime; //高时间
uint32_t LTime; //低时间
uint32_t RHTime; //记录高时间
uint32_t RLTime; //记录低时间
uint32_t O_Count; //100us+1
uint64_t RValue; //码值
uint64_t Remotes; //遥控器码
}Control;
extern xdata Control Control_T;
2.4:定时器中断
cpp
void TIMER0_ISR (void) interrupt 1 //每100us产生中断
{
TH0 = TH_VAL;
TL0 = TL_VAL;
if(Control_T.HFlag)Control_T.HTime++;
else Control_T.HTime=0;
if(Control_T.LFlag)Control_T.LTime++;
else Control_T.LTime=0;
}
2.5:外部中断
cpp
void INT4_ISR (void) interrupt 6
{
#if DEBUG
I2C_ISR();
#endif
#ifdef UART2_EN
UART2_ISR();
#endif
RemoteControl();
}
2.6:开始解码
cpp
/************************************************************************
* RemoteControl
* 遥控器
* 双边沿
************************************************************************/
void RemoteControl(void)
{
if(EPIF & 0x04) //判断外部中断4中断标志
{
EPIF = 0x04; //中断标志写1清0
if(P15) //上升沿
{
Control_T.RLTime = Control_T.LTime; //记录低位时间
Control_T.HFlag=1;//更新高位计数
Control_T.LFlag=0;//更新低位标志位
Control_T.LTime=0;//停止低位计数
Control_T.LCycleFalg=1;
}
else
{
Control_T.RHTime = Control_T.HTime; //记录高位时间
Control_T.HFlag=0;//更新高位计数
Control_T.LFlag=1;//更新低位标志位
Control_T.HTime=0;//停止高位计数
Control_T.HCycleFalg=1;
if(Control_T.S_Flag)
{
Control_T.O_Count = (Control_T.RHTime + Control_T.RLTime);
if(Control_T.RHTime > 13|| Control_T.RLTime > 13|| Control_T.O_Count <= 2 || Control_T.O_Count >= 18 ) //杂波
{
Control_T.RHTime =0;
Control_T.RLTime =0;
Control_T.LCycleFalg=0;
Control_T.HCycleFalg=0;
Control_T.C_Flag=0;
Control_T.RValue=0;
Control_T.S_Flag=0;
Control_T.O_Count=0;
return ;
}
if(Control_T.RHTime >= 5 && Control_T.RHTime <= 13)//高电平
{
Control_T.Bits=1;
}
else
{
Control_T.Bits=0;
}
P00 =!P00; //每bit位翻转
Control_T.LCycleFalg=0;
Control_T.HCycleFalg=0;
Control_T.RValue = ((Control_T.RValue << 1) | Control_T.Bits ) & 0x00FFFFFF ;
Control_T.C_Flag++;
if( Control_T.C_Flag == 24)
{
Mode_L.Count=0;
if( Mode_L.SFalg != 1) //延时100ms解码,防止连续发送
{
P03 =!P03; //解码完整翻转
Control_T.Pair=1;
Control_T.Remotes = Control_T.RValue & 0x00FFFFFF;
Control_T.RValue=0;
Control_T.C_Flag=0;
Control_T.S_Flag=0;
Mode_L.SFalg=1; //信号标志
Control_T.O_Count=0;
Control_T.LCycleFalg=0;
Control_T.HCycleFalg=0;
Control_T.RLTime=0;
Control_T.LTime=0;
Control_T.RHTime=0;
Control_T.HTime=0;
Control_T.O_Count=0;
}
}
}
}
//起始位
if(Control_T.RLTime >= 60 && Control_T.RLTime <= 140)
{
Control_T.S_Flag=1;
Control_T.C_Flag=0;
Control_T.LCycleFalg=0;
Control_T.HCycleFalg=0;
Control_T.RLTime=0;
Control_T.RHTime=0;
Control_T.O_Count=0;
}
//结束
if(Control_T.RLTime >= 300 && Control_T.RLTime <= 800)
{
Control_T.LCycleFalg=0;
Control_T.HCycleFalg=0;
Control_T.RLTime=0;
Control_T.LTime=0;
Control_T.RHTime=0;
Control_T.HTime=0;
Control_T.O_Count=0;
}
}
}
2.7:步骤
1:抓取波形,了解起始周期,码值周期,结束周期
2:借助其他io口在进入每位翻转,解码完整翻转,知道哪里出错,知道解码某一帧数据,很多遥控器发送一帧数据不止一个信号,而是多个信号,这样也是为了防止码值出错或被干扰
3:测试定时器是否精准,可以使用iO口翻转测试
4:可以根据自己的情况调宽松起始位,结束位,判断码值的时间。

码值为--0x98E691
如有更优,可以评论区发表意见。