本帖最后由 nicholasldf 于 2010-4-30 19:35 编辑
现象为:我设置9260的FIQ为由PC13管脚的上升沿触发,但是实际上是下降沿和上升沿都会触发FIQ中断。
9260的外部中断触发只有4种情况:
Low level Sensitive、Negative edge triggered、High level Sensitive、Positive edge triggered
也就是低电平、下降沿、高电平、上升沿,,,所以上升沿和下降沿都会触发中断的情况是不可能同时实现的。
要么是下降沿,要么是上升沿,二选一。
FIQ的输入由有一个传感器控制,,,传感器从“被码盘挡住”到“未被码盘挡住”时FIQ输入上升沿,,,
传感器从“未被码盘挡住”到“被码盘挡住”时FIQ输入下升沿,,,其实FIQ输入波形就是类似于一个方波。
用示波器看了FIQ的输入波形很好,没有什么毛刺干扰之类的。
拿纸片手动去操作传感器:拿纸片挡住,再拿开,,手动的产生方波波形,,测试也是一样,,在下降沿产生了FIQ中断。
FIQ的初始化代码如下:
AT91C_BASE_PIOC->PIO_PDR = AT91C_PC13_FIQ; //设置PC13引脚为功能引脚,而不是IO口
AT91C_BASE_PIOC->PIO_ASR = AT91C_PC13_FIQ; //设置PC13为FIQ输入中断引脚
AIC_ClearIT(AT91C_ID_FIQ); //清空FIQ中断
//配置FIQ中断向量:最低优先级(对FIQ无用,对普通IRQ起作用),外部中断类型,上升沿触发,中断服务函数为IntVectReactDishPassOneCup
AIC_ConfigureIT(AT91C_ID_FIQ, AT91C_AIC_PRIOR_LOWEST | \
AT91C_AIC_SRCTYPE_EXT_POSITIVE_EDGE, IntVectReactDishPassOneCup);
//使能FIQ中断
AIC_EnableIT(AT91C_ID_FIQ);
FIQ中断服务函数为:
void IntVectReactDishPassOneCup(void)
{
DEBUG("CurPassing: %2d CurrentCup: %2d\n\r", pReactDishModule->CurPassing, pReactDishModule->CurrentCup);
pReactDishModule->CurPassing++;
pReactDishModule->CurrentCup++;
AIC_ClearIT(AT91C_ID_FIQ);
}
下面是uCOS官方移植代码中断处理部分:
void BSP_IntSched(CPU_INT08U int_type)
{
CPU_FNCT_VOID p_isr;
if (int_type == BSP_INT_CTRL_TYPE_FIQ) {
p_isr = (CPU_FNCT_VOID)BSP_INT_AIC_FVR; /* Read the interrupt vector from the VIC */
while (p_isr != (CPU_FNCT_VOID)0) { /* Make sure we don't have a NULL pointer */
(*p_isr)();
BSP_INT_AIC_EOICR = DEF_BIT_NONE; /* End of handler */
p_isr = (CPU_FNCT_VOID)BSP_INT_AIC_FVR; /* Read the interrupt vector from the VIC */
}
BSP_INT_AIC_EOICR = DEF_BIT_NONE; /* End of handler */
}
if (int_type == BSP_INT_CTRL_TYPE_IRQ) {
p_isr = (CPU_FNCT_VOID)BSP_INT_AIC_IVR; /* Read the interrupt vector from the VIC */
while (p_isr != (CPU_FNCT_VOID)0) { /* Make sure we don't have a NULL pointer */
(*p_isr)();
BSP_INT_AIC_EOICR = DEF_BIT_NONE; /* End of handler */
p_isr = (CPU_FNCT_VOID)BSP_INT_AIC_IVR; /* Read the interrupt vector from the VIC */
}
BSP_INT_AIC_EOICR = DEF_BIT_NONE; /* End of handler */
}
}
被调用到的三个中断API函数AIC_ClearIT,AIC_ConfigureIT,AIC_EnableIT是atmel提供的开发包at91lib_softpack_1.5的aic.c文件里面的函数:
void AIC_ConfigureIT( unsigned int source, unsigned int mode, void (*handler)(void) )
{
// Disable the interrupt first
AT91C_BASE_AIC->AIC_IDCR = 1 << source;
// Configure mode and handler
AT91C_BASE_AIC->AIC_SMR[source] = mode;
AT91C_BASE_AIC->AIC_SVR[source] = (unsigned int) handler;
// Clear interrupt
AT91C_BASE_AIC->AIC_ICCR = 1 << source;
}
void AIC_EnableIT(unsigned int source)
{
AT91C_BASE_AIC->AIC_IECR = 1 << source;
}
void AIC_ClearIT(unsigned int source)
{
AT91C_BASE_AIC->AIC_ICCR = 1 << source;
} |