对于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电平
}
}