at91rm9200的io口电平中断简单理解

 对于PQFP封装的9200的PIOA、PIOB和PIOC三组32 *3 =64个io口 ,他们的io中断有这样的特性【在9200文档上有详细介绍】PIO的中断AT91C_AIC_SRCTYPE_EXT_HIGH_LEVEL和AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE都是电平中断 ,对于PIO来说没有区别 ,在PIO中断处理函数里边通过检测发生io中断的相应io引脚输入值为0还是为1 ,来判断是高电平中断还是低电平中断 ,PIO的PIO_IER使能的相应io口线上输入变化中断 - -注意是变化中断 ,所以对于io电平中断也必须存在电平变化之后才能被9200捕获到 ,也才能引发中断 ,执行中断处理函数 ,io口线上无电平变化也就无电平中断会被触法 ,这和51单片机的io电平中断机制不同 ,51单片机当启用外部电平中断之后 ,51处理器每个clk都会检测io的电平 ,如果符合中断电平 ,那么立即触发电平中断 ,所以对于51单片机 ,只要io口上的电平为中断电平值 ,那么就会不断的触法51的中断处理程序 ,直到io口电平变为非中断电平值51处理器才会停止触法中断 ,9200即便配置io为电平中断 ,但是也需要io线上只有发上了电平变化 ,9200才会触法电平变化中断 ,至于这个变化中断最终是变为了低电平还是变为了高电平 ,那么需要在处理程序中读取io值才可以进一步判断 ,不过如果存在其他irq中断屏蔽I时间比较长 ,同时io电平中断变化持续时间又比较短 ,那么很可能出现 ,到执行io电平中断处理程序时 ,读取到的io口数据已经不是引发中断的电平值了 ,所以io电平中断不是很好用 ,可以使用AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED双边沿中断或者AT91C_AIC_SRCTYPE_EXT_POSITIVE_EDGE上升沿中断来完成 ,对于io口最好使用AT91C_AIC_SRCTYPE_EXT_POSITIVE_EDGE上升沿中断机制 ,这不会出现误数据 ,最坏仅仅是可能会丢掉后面的1 ~2个上升沿 [gliethttp_20080104 ]

以PIOB的PB0为例 :
# define LEVEL_IRQ_PIN     (0x01 < < 0 )
AT91F_PMC_EnablePeriphClock (AT91C_BASE_PMC , ( ( unsigned int )1 < <AT91C_ID_PIOB ) ) ; //先要使能PIOB的控制器时钟
AT91F_PIO_CfgInput ( AT91C_BASE_PIOB , LEVEL_IRQ_PIN ) ; //将PB0配置为input输入
AT91F_AIC_ConfigureIt (AT91C_BASE_AIC ,
                     AT91C_ID_PIOB ,
                     1 ,
                     AT91C_AIC_SRCTYPE_EXT_POSITIVE_EDGE ,
                     //AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED,//双边沿
                     //AT91C_AIC_SRCTYPE_EXT_HIGH_LEVEL,
                     //AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE,//
                     ( void ( * ) ( void ) )piob_interrupt_proc ) ;
{ volatile dummy ;dummy = AT91C_BASE_PIOB - >PIO_ISR ; }
AT91F_PIO_InterruptEnable (AT91C_BASE_PIOB ,LEVEL_IRQ_PIN ) ; //使能PB0变化中断
{ volatile dummy ;dummy = AT91C_BASE_PIOB - >PIO_ISR ; }
AT91F_AIC_EnableIt (AT91C_BASE_AIC , AT91C_ID_PIOB ) ; //使能PIOB控制器中断
以上就完成了PB0的上升沿中断启动 ,来看看中断处理函数 [ads1 .2 ]
void __irq piob_interrupt_proc ( void )
{
     { volatile dummy ;dummy = AT91C_BASE_PIOB - >PIO_ISR ; }
    AT91C_BASE_AIC - >AIC_EOICR = 0 ;
     if (AT91F_PIO_GetInput (AT91C_BASE_PIOB ) & LEVEL_IRQ_PIN )
     {
         //...1电平
     } else
         {
             //...0电平
         }
}

你可能感兴趣的:(at91rm9200的io口电平中断简单理解)