用STM8L152C4T6写了一个红外接收的程序,调试了一个礼拜了,目前能干活。。。。。莫名的是机子上电后第一次按按遥控器的时候总是没用,第二次及以后再按都会有用。。。。。
编程思路采用中断+定时器的做法(下降沿触发)
通过STVD仿真,发现上电后,第一次按遥控器时,第一个引导码测量的脉宽不对,实际测量只有9850us左右,而理论值应该在13500us左右,后面的16位用户码及16位正反数据码测量都没有问题,第二次再按遥控器时引导码的测量及用户码、数据码都不会有问题。
自已初步分析是不是第一次外部中断发生到进入中断函数得花比较长的时间,后面发生的中断再进入中断函数则时间比较短,可以忽略不计。。。。。。。
请写过的朋友看一下,帮分析分析,下面是我的源代码,谢谢。。。。。
//端口初始化
void GPIO_INIT(void)
{
//初始化端口A
//初始化端口B
PB_DDR|=0xc0; //PB7-6 out other input
PB_ODR|=0x00; //置低
PB_CR1|=0xf8; //
PB_CR2|=0x01; //PB0外部中断使能
EXTI_CR1=0x02; //Pb0仅下降沿触发
EXTI_CR3=0x02;
//初始化端口C
//初始化端口D
//初始化端口E
//初始化端口F
}
//定时器2初始化(用来做遥控脉的测量)
void TIM2_INIT(void)
{
CLK_PCKENR1|=0x01; //Enable TIMER2 clock
TIM2_PSCR=0x04; //定时器2时钟源FASMTER/16=1M
TIM2_ARRH=0xea; //
TIM2_ARRL=0x60;
TIM2_IER=0x00; //禁止更新中断
TIM2_CNTRH=0x00;
TIM2_CNTRL=0x00;
TIM2_DISBLE; //计数器关
}
//处部中断函数入口
@far @interrupt void EXTI0_IRQHandler(void)
{
TIM2_DISBLE; //定时器2关
HIGH_WORD=TIM2_CNTRH; //保存高低字节
LOW_WORD=TIM2_CNTRL;
TIM2_CNTRH=0;
TIM2_CNTRL=0;
TIM2_ENABLE; //定时器2开
SURGE_INTERVAL=0; //测量数据整理
SURGE_INTERVAL=(unsigned int)HIGH_WORD;
SURGE_INTERVAL=SURGE_INTERVAL<<8;
SURGE_INTERVAL=SURGE_INTERVAL|LOW_WORD;
//引导码捕捉
if(SURGE_INTERVAL>=13300&&SURGE_INTERVAL<=13700&&IR_GOT_HEAT==0)
{
IR_REPEAT_COUNT=0; //IR重复码清零
SURGE_COUNT=1; //下降沿计数器第一个脉冲
IR_GOT_HEAT=1; //遥控头获得位置1
}
//读用户码
else if(SURGE_COUNT>=1&&SURGE_COUNT<=16)
{
if(SURGE_INTERVAL>=1000&&SURGE_INTERVAL<=1300)//0码
{
USER_ID_CODE=USER_ID_CODE>>1;
SURGE_COUNT++;
}
else if(SURGE_INTERVAL>=2000&&SURGE_INTERVAL<=2450)//1码
{
USER_ID_CODE=USER_ID_CODE>>1;
USER_ID_CODE=USER_ID_CODE|0x8000;
SURGE_COUNT++;
}
}
//读键码
else if(SURGE_COUNT>16&&SURGE_COUNT<=24)
{
if(SURGE_INTERVAL>=1000&&SURGE_INTERVAL<=1300)//0码
{
KEY_CODE=KEY_CODE>>1;
SURGE_COUNT++;
}
else if(SURGE_INTERVAL>=2000&&SURGE_INTERVAL<=2450)//1码
{
KEY_CODE=KEY_CODE>>1;
KEY_CODE=KEY_CODE|0X80;
SURGE_COUNT++;
}
}
//读键码的反码
else if(SURGE_COUNT>24&&SURGE_COUNT<=32)
{
if(SURGE_INTERVAL>=1000&&SURGE_INTERVAL<=1300)//0码
{
KEY_CODE_COMPLEMENT=KEY_CODE_COMPLEMENT>>1;
SURGE_COUNT++;
}
else if(SURGE_INTERVAL>=2000&&SURGE_INTERVAL<=2450)
{
KEY_CODE_COMPLEMENT=KEY_CODE_COMPLEMENT>>1;
KEY_CODE_COMPLEMENT=KEY_CODE_COMPLEMENT|0X80;
SURGE_COUNT++;
}
}
else if((SURGE_COUNT>32)&&(IR_REPEAT_FOLLOW_UP==0))
{
IR_FOLLOW_UP=1;
SURGE_COUNT=0;
IR_GOT_HEAT=0;
}
//重复码
else if(SURGE_INTERVAL>=11000&&SURGE_INTERVAL<=11500)
{
IR_REPEAT_FOLLOW_UP=1;
if(IR_REPEAT_COUNT<250)
{
IR_REPEAT_COUNT++;
}
}
//清中断标志
EXTI_ClearITPendingBit(EXTI_IT_Pin0);
} |