|
大虾们好,我在本论坛里面找了一个定时器来解红外遥控器的解码程序,单步按下遥控器时,功能正常,但是进行连加、减操作后,再按其他的无用的遥控器上面的某个键时,他会随连加减的动作再来一次动作(之后再按时,才会变成无动作),程序找了好久,都没有找到问题的所在,如果不用练加减功能,遥控功能完全正常,程序代码如下:
采用松翰的单片机;4MHz
sn8f27e65
#define T0C_INIT 0X83 //SET TIME 0.125mS ,内部FCPU/4分频 MAX=256uS, MIN=1uS
#define T0M_INIT 0X60 //内部FCPU/4分频 MAX=256uS, MIN=1uS
#define REMOTE_OK 1
#define REMOTE_FAIL 0
#define IR_REPEAT_OK 1
#define IR_USER 0X00 //用户码
#define IR_USER_SHIFT 0XF7 //用户反码
#define IR_BASE_TIME 125
uchar rCodeTime,rCodeCnt;
uchar rIrData,rIrData1,rIrData2,rIrData3,rIrData4,rIrRepeat;
uchar rMute_dat,rMute_vol,rMute_dat_dealy,rMute_Delay;
uchar rDisp_Bai_Buf,rDisp_Shi_Buf,rDisp_Ge_Buf,rDisp_Interrupt1; //显示的个、十、百位数据
uchar rDisp_Ms,rDisp_S;
struct _bit
{
unsigned bi0:1;
unsigned bi1:1;
unsigned bi2:1;
unsigned bi3:1;
unsigned bi4:1;
unsigned bi5:1;
unsigned bi6:1;
unsigned bi7:1;
};
struct _bit b;
//#define IR_REPEAT (b.bi0) //遥控器连码标志,=1连码,=0没有连码
#define IR_OK (b.bi1) //=1解码成功,否则失败
#define HEADCODE_RECED (b.bi2) //=1头码接收成功,否则失败
#define IR_DEALED (b.bi3)
#define Irprot_LastState (b.bi4)
#define MUTE_FLAG (b.bi5)
#define MUTE_DISP_FLAG (b.bi6)
void t0_init_set_ir(void)
{
T0M = 0X00;
FT0IEN = OFF; // 禁止T0 中断。
FT0IRQ = OFF; // 清T0 中断请求标志。
T0M = T0M_INIT;
T0C = T0C_INIT;
FT0IEN = ON; //开启T0 的中断功能。
FT0ENB = ON; //启动T0 定时器
}
void remote_rx(void)
{
rCodeTime++;
if(rCodeTime >= 80)
{
rCodeTime = 80;
HEADCODE_RECED = REMOTE_FAIL; //80*125us=10ms时间未接收到低电平信号则清头码接收标志位
IR_DEALED = 0;
}
IR_IO = 1; //先给该口付1
if(IR_IO == 1)
{
Irprot_LastState = 1; //置接收端口为1状态标志
}
else //该口出现了低电平证明有可能是收到红外信号
{
if(Irprot_LastState) //出现低电平后如证实之前出现高电平,证明确实是有红外信号
{
Irprot_LastState=0;// 将接收状态清0
if(HEADCODE_RECED) //查询是否已接收过头码。有就进入解码,无就进入头码(4.5ms计时)
{
if(rCodeTime>OneMin && rCodeTime<OneMax) //若头码已接收过,则判断当前接收的是1码或0码 //FTM2->8-<16-11(125*11=1.375,示波器读出0为0.8ms\1为1.6ms)
{ //HFJ->15-<21--11(125*15=1.875,示波器读出0为1.2ms\1为2.4ms)
rIrData |= 0x80; //两个下降沿之间的时间大于125us*11=1.375ms,条件满足则接收的为1码
}
else if(rCodeTime>ZeroMin && rCodeTime<ZeroMax) //HFJ->6-<12
//FTN2->3-<8
{
rIrData &= 0x7f; //两个下降沿之间的时间小于125us*12=15ms条件不满足则接收的为0码
}
else
{
rIrData1=0;
rIrData2=0;
rIrData3=0;
rIrData4=0;
HEADCODE_RECED=0;
}
//==================================================
switch(rCodeCnt)
{
case 7: rIrData1=rIrData; rIrData=0;
case 15: rIrData2=rIrData; rIrData=0;
case 23: rIrData3=rIrData; rIrData=0;
case 31: rIrData4=rIrData; rIrData=0;
}
rIrData >>= 1;
rCodeCnt++;
if(rCodeCnt == 32)
{
rCodeCnt = 0;
rIrRepeat=0; //第一次解码成功后,连续吗变量清0
if(!IR_DEALED)
{
IR_OK = REMOTE_OK;
rIrRepeat = 0;
}
}
rCodeTime = 0; //接收完,将时间清0
}
else
{
if(rCodeTime>=HeaderMin && rCodeTime<HeaderMax) //30 46(FTM2--3.750~5.750计的是低电平+高电平的总时间,即两个下降沿时间.示波器读出是4.9ms)
{ // 80 120(HFJ--10~15ms 计的是低电平+高电平的总时间,即两个下降沿时间.示波器读出是13.6ms)
HEADCODE_RECED = 1;
rIrRepeat++;
}
else
{
HEADCODE_RECED = 0;
rIrRepeat = 0;
}
rCodeCnt = 0; //如果是第一次进入则将码计时时间rCodeTime与码位rCodeCnt清0
rCodeTime = 0;
}
}
}
}
void ir_scan()
{
if(IR_OK == REMOTE_OK)
{
IR_OK = REMOTE_FAIL;
if(rIrData1==IR_USER && rIrData2==IR_USER_SHIFT)
{
if(rIrData3 == IR_MASTER_VOLATE_MUTE)
{
mute_Function();
}
if(MUTE_FLAG == MUTE_OFF)
{
if(rIrData3 == IR_VOLATE_LOUD)
{
LOUDNESS_IO = !LOUDNESS_IO;
}
else if(rIrData3 == IR_VOLATE_3D)
{
AUDIO_3D = !AUDIO_3D;
}
volume_adj();
}
}
}
//------------------------连加开始---------------------------- 问题就出在此处连加减功能,不知道是何故??? 望高人指点
if(rIrRepeat == 27)
{
if(MUTE_FLAG == MUTE_OFF)
volume_adj();
rIrRepeat = 23;
}
}
void main()
{
t0_init_set_ir() ;
while(1)
{
ir_scan();
}
}
void __interrupt[T0_INTERRUPT_ADDR] T0_Inter(void) //IR 125us interrupt
{
FT0IRQ = 0;
T0C = T0C_INIT;
remote_rx();
}
|
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|