在gpio.c 中有:
void GPIO_EnableIRQ( GPIO_PORT port, GPIO_PIN pin, IRQn_Type irq, bool low_input,bool release_wait, uint8_t
debounce_ms )
参数说明:
port : GPIO 端口 Port
pin : GPIO 端口 Pin
IRQn_Type 中断类型
low_input 触发类型: true,下降沿触发;false,上升沿触发
release_wait :是否锁住中断,直到按键放开。如果输入true,即使按键一直保持,也只会触发一次中断;如果输入false,则按键保持期间会不断触发中断,直到松开按键。
debounce_ms : 设定按键防抖控制的时间,单位毫秒ms
原函数:gpio.c--358行
/**
****************************************************************************************
* @brief Function to set the interrupt generated by the GPIO pin
*
* @param[in] port GPIO port
* @param[in] pin GPIO pin
* @param[in] irq GPIO IRQ
* @param[in] low_input TRUE generates an IRQ if the input is low
* @param[in] release_wait TRUE waits for key release after interrupt was reset
* @param[in] debounce_ms duration of a debounce sequence before an IRQ is generated
*
* @return void
****************************************************************************************
*/
void GPIO_EnableIRQ( GPIO_PORT port, GPIO_PIN pin, IRQn_Type irq, bool low_input,
bool release_wait, uint8_t debounce_ms )
{
#if DEVELOPMENT_DEBUG
#ifndef GPIO_DRV_PIN_ALLOC_MON_DISABLED
if ( !(GPIO_status & ( ((uint64_t)1 << pin) << (port * 16) )) )
__asm("BKPT #0\n"); // this pin has not been previously reserved!
#endif //GPIO_DRV_PIN_ALLOC_MON_DISABLED
#endif //DEVELOPMENT_DEBUG
const uint8_t KBRD_IRQn_SEL_BASE[] = {
1,
9,
15,
25
};
GPIOSetBits16(GPIO_DEBOUNCE_REG, (DEB_ENABLE0 << (irq-GPIO0_IRQn)), (debounce_ms > 0) );
GPIOSetBits16(GPIO_DEBOUNCE_REG, DEB_VALUE, debounce_ms);
GPIOSetBits16(GPIO_INT_LEVEL_CTRL_REG, EDGE_LEVELn0 << (irq-GPIO0_IRQn), release_wait);
GPIOSetBits16(GPIO_INT_LEVEL_CTRL_REG, INPUT_LEVEL0 << (irq-GPIO0_IRQn), low_input);
GPIOSetBits16(GPIO_IRQ0_IN_SEL_REG + 2*(irq-GPIO0_IRQn), KBRD_IRQn_SEL, KBRD_IRQn_SEL_BASE[port] + pin);
NVIC_SetPriority(irq, 2);
NVIC_EnableIRQ(irq);
}
关键点就是对GPIO的配置:
//KEY_CLAMP
//配置成下拉输入
GPIO_ConfigurePin(KEY_CLAMP_PORT, KEY_CLAMP_PIN, INPUT_PULLDOWN, PID_GPIO, false );
//开启中断
GPIO_EnableIRQ( KEY_CLAMP_PORT, KEY_CLAMP_PIN, KEY_CLAMP_IRQ_TYPE, false, true, 120 );
//注册中断回调函数
GPIO_RegisterCallback(KEY_CLAMP_IRQ_TYPE, KEY_CLAMP_callback);
要注意的是,一个port口,只能设置一个中断回调函数, 就是说P2_0~P2_8 如果这九个都是按键,就只能是P2端口这一个回调函数,需要在中断回调函数里在具体判断是哪一个按键按下了(采用读IO口状态的形式。)。
使用案例:
按键key接在 io端口 P2_5上默认是下拉, 按下后IO高电平。
功能: 每按下KYE 一次,LED灯翻转一次
//LED--Green
#define RGB_LED_G_PORT GPIO_PORT_1
#define RGB_LED_G_PIN GPIO_PIN_2
/* KEY 按键 */
//KEY_CLAMP 开关 P2_5
#define KEY_CLAMP_PORT GPIO_PORT_2
#define KEY_CLAMP_PIN GPIO_PIN_5
#define KEY_CLAMP_IRQ_TYPE GPIO2_IRQn //中断IO类型
bool led_flag=0;
void KEY_CLAMP_callback(void)
{
led_flag=!led_flag;
{
if(led_flag==1)
{
GPIO_SetActive(RGB_LED_G_PORT,RGB_LED_G_PIN);
}
else
{
GPIO_SetInactive(RGB_LED_G_PORT,RGB_LED_G_PIN);
}
}
GPIO_ResetIRQ(KEY_CLAMP_IRQ_TYPE);
}
void KEY_CLAMP_Seting(void)
{
//KEY_CLAMP
//配置成下拉输入
GPIO_ConfigurePin(KEY_CLAMP_PORT, KEY_CLAMP_PIN, INPUT_PULLDOWN, PID_GPIO, false );
//开启中断
GPIO_EnableIRQ( KEY_CLAMP_PORT, KEY_CLAMP_PIN, KEY_CLAMP_IRQ_TYPE, false, true, 120 );
//注册中断回调函数
GPIO_RegisterCallback(KEY_CLAMP_IRQ_TYPE, KEY_CLAMP_callback);
}
int main (void)
{
system_init();
periph_init();
KEY_CLAMP_Seting();
while(1);
}
参考:http://ju.outofmemory.cn/entry/263109
http://www.mamicode.com/info-detail-2238192.html
https://wenku.baidu.com/view/f907182aae1ffc4ffe4733687e21af45b307fed1.html