蓝桥杯嵌入式KEY配置(中断、扫描)

您所在的位置:网站首页 stm32按键外部中断反应慢 蓝桥杯嵌入式KEY配置(中断、扫描)

蓝桥杯嵌入式KEY配置(中断、扫描)

2024-06-02 09:15| 来源: 网络整理| 查看: 265

按键–在众多外设中也是仅此于led的最基本的、简单的外设。 在本文介绍两种方法进行按键的驱动(中断、循环扫描)。 对于中断不懂的可以看下我另外一篇文章:STM32中断 蓝桥杯嵌入式的板子里面有四个按键,在原理图上我们可以看出当GPIO输入为低电平时导通。连接的IO口为PA0、PA8、PB1、PB2四个口。 在这里插入图片描述 在这里插入图片描述 1、循环扫描 key.c

#include "key.h" #include "lcd.h" void key_init(void) { GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING; GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_8; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStruct); GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING; GPIO_InitStruct.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_1; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_InitStruct); } unsigned char key_scanf(void) { unsigned char key_but=0; if(key0==0||key1==0||key2==0||key3==0) { Delay_LCD(100); if(key0==0) key_but=1; if(key1==0) key_but=2; if(key2==0) key_but=3; if(key3==0) key_but=4; } return key_but; }

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