nicholasldf 发表于 2010-4-30 19:42:18

很奇怪的问题:关于at91sam9260 FIQ中断 的触发

现象为:我设置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: %2dCurrentCup: %2d\n\r", pReactDishModule->CurPassing, pReactDishModule->CurrentCup);
    pReactDishModule->CurPassing++;
    pReactDishModule->CurrentCup++;

    AIC_ClearIT(AT91C_ID_FIQ);
}

下面是uCOS官方移植代码中断处理部分:
voidBSP_IntSched(CPU_INT08Uint_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 = mode;
    AT91C_BASE_AIC->AIC_SVR = (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;
}
页: [1]
查看完整版本: 很奇怪的问题:关于at91sam9260 FIQ中断 的触发