蓝桥杯嵌入式KEY配置(中断、扫描) |
您所在的位置:网站首页 › stm32按键外部中断反应慢 › 蓝桥杯嵌入式KEY配置(中断、扫描) |
按键–在众多外设中也是仅此于led的最基本的、简单的外设。 在本文介绍两种方法进行按键的驱动(中断、循环扫描)。 对于中断不懂的可以看下我另外一篇文章:STM32中断 蓝桥杯嵌入式的板子里面有四个按键,在原理图上我们可以看出当GPIO输入为低电平时导通。连接的IO口为PA0、PA8、PB1、PB2四个口。 key.h #include "stm32f10x.h" #define key0 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) #define key1 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8) #define key2 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) #define key3 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_2) void key_init(void); unsigned char key_scanf(void);在key_scanf()函数上我们可以看出当检测到第一个按键按下的时候,函数返回1;检测到第二个按键按下的时候,函数返回2,以此类推。 因此我们用扫描的方法的时候,我们要一个中间存储按键的值进行操作。例如: unsigned char key_val; int main(void) { key_init(); .... while(1) { key_val=key_scanf(); if(key_val==1) //检测到第一个按键按下 { ......... //要执行的操作 } if(key_Val==2) //第二个按键按下 { ......... } ........... } }2、中断 #include "key.h" #include "lcd.h" void key_Init() { EXTI_InitTypeDef EXTI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); EXTI_InitStructure.EXTI_Line = EXTI_Line0; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource8); EXTI_InitStructure.EXTI_Line = EXTI_Line8; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1); EXTI_InitStructure.EXTI_Line = EXTI_Line1; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource2); EXTI_InitStructure.EXTI_Line = EXTI_Line2; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void EXTI0_IRQHandler(void) { Delay_LCD(100); if(EXTI_GetITStatus(EXTI_Line0) != RESET) { EXTI_ClearITPendingBit(EXTI_Line0); } } void EXTI9_5_IRQHandler(void) { Delay_LCD(100); if(EXTI_GetITStatus(EXTI_Line8) != RESET) { EXTI_ClearITPendingBit(EXTI_Line8); } } void EXTI1_IRQHandler(void) { Delay_LCD(100); if(EXTI_GetITStatus(EXTI_Line1) != RESET) { EXTI_ClearITPendingBit(EXTI_Line1); } } void EXTI2_IRQHandler(void) { Delay_LCD(100); if(EXTI_GetITStatus(EXTI_Line2) != RESET) { EXTI_ClearITPendingBit(EXTI_Line2); } }在中断上,我们就没有扫描这个环节,我们可以直接在中断里面执行按键的操作。但我们使能中断后要对按键进行操作的时候要加上中断服务函数,并且中断服务函数不能写错,不然会执行不了中断。虽然编译时没问题的,但就是执行不了中断。 例: void EXTI0_IRQHandler(void) { Delay_LCD(100); if(EXTI_GetITStatus(EXTI_Line0) != RESET) { .......... //这里编写第一个按键按下要进行的操作 EXTI_ClearITPendingBit(EXTI_Line0); } } |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |