我写了一个linux设备驱动程序,学习红外遥控的编码。
XINT0(GPIOF0)用于接收来自红外二极管的信号。在XINT0中断处理程序中使用Timer0进行计数,记录高电压和低电压的周期。
GPIO和定时器的配置是合适的。TCNTB的Timer0初始值为50000,有时电压电平周期正确,但有时TCNT0观察值为50000,说明定时器工作不正常。
在每个中断循环中,观察值打印如下。
<4>current observation value: 49786
<4>current observation value: 49702
<4>current observation value: 50000
<4>current observation value: 49969
<4>current observation value: 50000
<4>current observation value: 49996
<4>current observation value: 50000
<4>current observation value: 49998
<4>current observation value: 47827
<4>current observation value: 49392
<4>current observation value: 49906
<4>current observation value: 50000
<4>current observation value: 49970
<4>current observation value: 50000
<4>current observation value: 49997
<4>current observation value: 50000
<4>current observation value: 49998
<4>current observation value: 50000代码如下:
static irqreturn_t gpio_study_irq_handler(int irq, void *wbuf)
{
unsigned int *buf=(unsigned int *)wbuf;
unsigned int temp;
if(0==IrDA_cnt){
timer_setup(&Study_Timer,MAX_CODE_WIDTH);
timer_on(&Study_Timer);
IrDA_cnt++;
return IRQ_RETVAL(IRQ_HANDLED);
}
temp=ioread32(Study_Timer.tcnto);
timer_off(&Study_Timer);
printk("current observation value: %d\n",temp);
*(buf+IrDA_cnt-1)=MAX_CODE_WIDTH-read_timer_cnt(&Study_Timer);
iowrite32(MAX_CODE_WIDTH,Study_Timer.tcntb);
temp=ioread32(Study_Timer.tcon);
iowrite32(temp|0x02,Study_Timer.tcon);
temp=ioread32(Study_Timer.tcon);
iowrite32(temp&(~0x02),Study_Timer.tcon);
timer_on(&Study_Timer);
IrDA_cnt++;
if(IrDA_cnt > CODE_MAX_LEN)
{
wake_up_interruptible(&IrDA_Study_Queue);
return IRQ_RETVAL(IRQ_HANDLED);
}
return IRQ_RETVAL(IRQ_HANDLED);
}发布于 2014-08-27 15:52:29
系统函数IRQ 在服务处理程序中占用太多时间。当定时器最终开启时,中断请求已经到来,导致观察值的恒定值。
https://stackoverflow.com/questions/25518427
复制相似问题