本帖最后由 mcsgy 于 2011-9-25 23:55 编辑
(一)硬件电路:
很简单就是两个按键连接到MCU的中断,KEY1连接GPB15也就是INT1,KEY2连接GPB14也就是INT0。如下图:
(二)中断初始化:
这里要调用函数void DrvGPIO_EnableEINT0(E_DRVGPIO_INT_TYPE TriggerType, E_DRVGPIO_INT_MODE Mode, GPIO_EINT0_CALLBACK pfEINT0Callback)
{
volatile uint32_t u32Reg;
if ((TriggerType == E_IO_BOTH_EDGE) && (Mode == E_MODE_LEVEL))
return ;
u32Reg = (uint32_t)&GPIOA->IEN + (E_GPB*PORT_OFFSET);
if (TriggerType == E_IO_RISING)
{
outpw(u32Reg, inpw(u32Reg) | (1UL<<(14+16)));
}
else if (TriggerType == E_IO_FALLING)
{
outpw(u32Reg, inpw(u32Reg) | (1UL<<(14)));
}
else if (TriggerType == E_IO_BOTH_EDGE)
{
outpw(u32Reg, inpw(u32Reg) | (1UL<<(14))|(1UL<<(14+16)));
}
/* Configure to be level trigger or edge trigger */
u32Reg = (uint32_t)&GPIOA->IMD + (E_GPB*PORT_OFFSET);
if (Mode == E_MODE_EDGE)
outpw(u32Reg, inpw(u32Reg) & ~(1<<14));
else if(Mode == E_MODE_LEVEL)
outpw(u32Reg, inpw(u32Reg) | (1<<14));
_pfEINT0Callback = pfEINT0Callback;
NVIC_EnableIRQ(EINT0_IRQn);
}
其中,第一个参数是选择边沿触发方式(上升沿,下降沿),第二个参数是选择触发方式(边沿触发,电平触发),第三个参数是中断回调函数的地址,从DrvGPIO.c开头的函数声明
static void (*_pfEINT0Callback)(void);
static void (*_pfEINT1Callback)(void);
可以看到,定义了指向函数的指针变量,可以用来存储回调函数的地址。
中断响应函数:
void EINT0_IRQHandler(void)
{
/* EINT0 = GPB14. Clear the interrupt */
GPIOB->ISRC = 1UL << 14;
if ( _pfEINT0Callback )
_pfEINT0Callback();
}
(三)main()函数:
/////////////////////////////////////////////////
//工程:中断实验
//日期:2011年9月25日
////////////////////////////////////////////////
#include <stdio.h>
#include "NUC1xx.h"
#include "DrvGPIO.h"
#include "DrvSYS.h"
void pfEINT0Callback(void);
void pfEINT1Callback(void);
int main(void)
{
UNLOCKREG();
DrvSYS_Open(48000000); //将时钟设定为48MHz
//GPIO端口配置 可以是GPA, GPB , GPC , GPD , GPE
//GPIO端口bit 可以是 0~15.
//GPIO端口模式 可设定为IO_INPUT , IO_OUTPUT ,IO_OPENDRAIN 或者IO_QUASI
DrvGPIO_Open(E_GPB, 10, E_IO_OUTPUT); // 设置GPB10端口为输出模式
DrvGPIO_ClrBit(E_GPB, 10); // 清GPB10端口 蜂鸣器不叫唤
//---------------------------------------------------------
DrvGPIO_Open(E_GPA, 2, E_IO_OUTPUT); // 设置GPA2端口为输出模式
DrvGPIO_Open(E_GPA, 3, E_IO_OUTPUT); // 设置GPA3端口为输出模式
DrvGPIO_Open(E_GPA, 4, E_IO_OUTPUT); // 设置GPA4端口为输出模式
DrvGPIO_Open(E_GPA, 5, E_IO_OUTPUT); // 设置GPA5端口为输出模式
// DrvGPIO_Open(E_GPB,14,E_IO_INPUT);
// DrvGPIO_Open(E_GPB,14,E_IO_INPUT);
DrvGPIO_EnableEINT0(E_IO_FALLING,E_MODE_EDGE,&pfEINT0Callback); //初始化INT0中断方式
DrvGPIO_EnableEINT1(E_IO_FALLING,E_MODE_EDGE,&pfEINT1Callback); //初始化INT1中断方式
// 经过测试,以上Open注释掉程序也能用
while(1);
}
void pfEINT0Callback(void)
{
DrvSYS_Delayms(10);
if(0==DrvGPIO_GetBit(E_GPB,14))
{
DrvGPIO_ClrBit(E_GPA,2); //点亮LED1
DrvGPIO_SetBit(E_GPB,10); //打开蜂鸣器
DrvSYS_Delayms(200); //延时200ms
DrvGPIO_SetBit(E_GPA,2); //关灯
DrvGPIO_ClrBit(E_GPB,10); //关蜂鸣器
}
}
static void pfEINT1Callback(void)
{
DrvSYS_Delayms(10);
if(0==DrvGPIO_GetBit(E_GPB,15))
{
DrvGPIO_ClrBit(E_GPA,3);
DrvGPIO_SetBit(E_GPB,10);
DrvSYS_Delayms(200);
DrvGPIO_SetBit(E_GPA,3);
DrvGPIO_ClrBit(E_GPB,10);
}
}
(四)工程包:
中断实验.rar
(198 KB)
|