|
楼主 |
发表于 2010-3-25 13:23:54
|
显示全部楼层
回复【楼主位】gongziwuyou
-----------------------------------------------------------------------
#include <stdio.h>
#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "alt_types.h"
#include "sys/alt_irq.h"
#include "priv/alt_busy_sleep.h"
volatile alt_u32 done = 0; // 信号量:通知外部中断事件发生
/********************************************************************
* 名 称:KeyDown_interrupts()
* 功 能:键按下事件中断服务子程序,当键按下时,通过done标志
* 告知外界
* 入口参数:context,一般用于传递中断状态寄存器的值,这里未使用
* id,中断号,这里未使用
* 出口参数:无
********************************************************************/
static void KeyDown_interrupts(void* context, alt_u32 id)
{
/* 清中断捕获寄存器 */
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(BUTTON_PIO_BASE, 0);
/* 通知外部有中断事件发生 */
done++;
}
/********************************************************************
* 名 称:InitPIO()
* 功 能:初始化LED_PIO为输出,KEY为输入,开中断,清边沿捕获寄存器
* 入口参数:无
* 出口参数:无
********************************************************************/
void InitPIO(void)
{
/* 初始化LED_PIO为输出,KEY为输入 */
IOWR_ALTERA_AVALON_PIO_DIRECTION(LED_PIO_BASE, 0xFF);
IOWR_ALTERA_AVALON_PIO_DIRECTION(BUTTON_PIO_BASE, 0x00);
/* 开KEY的中断 */
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(BUTTON_PIO_BASE, 0xFF);
/* 清边沿捕获寄存器 */
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(BUTTON_PIO_BASE, 0x00);
/* 注册中断服务子程序 */
alt_irq_register(BUTTON_PIO_IRQ, NULL, KeyDown_interrupts);
}
/********************************************************************
* 名 称:main()
* 功 能:等待按键中断,并输出控制相应的LED。
********************************************************************/
int main(void)
{
volatile alt_u32 key_state,old_state,new_state;
old_state = 0xff;
IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, old_state);//初始化LED全灭
InitPIO();
while(1)
{
if(0 != done)
{
/* 中断事件数量减1 */
done--;
alt_busy_sleep(5000); //延时5ms
key_state = IORD_ALTERA_AVALON_PIO_DATA(BUTTON_PIO_BASE)&0xFF;
if(key_state == 0xff) //如果是由短暂脉冲引起的中断则忽略
continue;
new_state = ~(old_state ^ key_state); // 按键按下时对应的LED取反
old_state = new_state; // 保存LED的状态
IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, new_state);
}
}
return(0);
} |
|