完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
以检测按键输入为例:
如图一共有三个按键,WK-UP按键被按下会被拉到高电平,其它两个被按下会被拉到低电平。下面例子中如果key0被按下那就让led0状态反转,如果是key1被按下那就让led1状态反转,如果是wk-up被按下那就让蜂鸣器状态反转。 首先要说明的是按键有两种模式,一种就像是快进键,持续被按下就持续快进,就像是可重复触发的单稳态触发器,另外一种就是像关机一样的键,就算被持续按下也只是被判定为一次触发,就像是不可重复触发的单稳态触发器。在程序中用key_mode这个参数配置模式。 读取IO输入的库函数是: uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 在程序中直接使用了宏定义绕过库函数的使用达到操作寄存器的目的 1.key.h #ifndef __key_h_ #define __key_h_ #include "stm32f10x.h" #include "sys.h" #include "delay.h" #define wk_up PAin(0) //位操作参数宏,用多级宏映射寄存器 #define key0 PEin(4) #define key1 PEin(3) #define beep PBout(8) #define led0 PBout(5) #define led1 PEout(5) u8 key_scan(u8 key_mode); void key_init(void); #endif 2.key.c #include "key.h" void key_init() { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE);//使能PORTA,PORTE时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_3;//KEY0-KEY1 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入 GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE4,3 //初始化 WK_UP-->GPIOA.0 下拉输入 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0设置成输入,默认下拉 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.0 } u8 key_scan(u8 key_mode) { static u8 key_up = 1;//按键没有被按下 if(key_mode) key_up = 1;//key_mode为1时持续按下被判定为多次按下,key_mode为0时持续按下被判定为一次按下 if(key_up&&((wk_up==1)||(key0==0)||(key1==0))) { delay_ms(10);//延时,防止按键抖动带来误判 key_up = 0; if(wk_up==1) { return 1;//返回1代表wk_up被按下 } else if(key0==0) { return 2;//key0被按下返回2 } else if(key1==0) { return 3;//key1 被按下返回3 } } else if(key1==1&&key0==1&&wk_up==0)key_up=1;//按键没被判定按下 return 0; } 在这里有必要解释下key_scan这个函数: (1.) static u8 key_up = 1; if(key_mode) key_up = 1; 这两行代码可能会让人感到疑惑,会有人认为key_up重复被赋值为1,如果是在第一次调用这个函数,并且key_mode为1时确实是重复赋值,然而可能重复被赋值的次数只有这一次,因为static u8 key_up = 1;仅仅在第一次调用这个函数时执行。 如果按键处于持续按下被判定为多次按下模式时,当按键被按下key_up = 0;这段代码一定会执行,但是当下次再调用key_scan函数时key_up又被赋值为1,这样就能多次判定被按下。 如果是持续按下被判定为一次按下模式,当持续按下按键时,第一次监测到按键被按下后key_up 被赋值为0,下次再检测时虽然按键被按下,但是无法进入if(key_up&&((wk_up==1)||(key0==0)||(key1==0)))语句块,也就不会被判定为按下。 (2.) else if(key1==1&&key0==1&&wk_up==0)key_up=1; //该语句不能放入if(key_up&&((wk_up==1)||(key0==0)||(key1==0)))语句块之内, //虽然该语句放在if(key_up&&((wk_up==1)||(key0==0)||(key1==0)))看似合理, //但却会造成问题:当有按键被判定为按下后key_up被赋值为0,在下次检测 //时虽然按键已经被弹起了,但是却无法进入 //if(key_up&&((wk_up==1)||(key0==0)||(key1==0)))语句块,这样一来 //key_up就永远为0,之后任何按键按下去都不会被判定为按下。 3.led.h void led_init(void); 1 4.led.c #include "stm32f10x.h" #include "led.h" #include "sys.h" void led_init(void) { GPIO_InitTypeDef gpio_init_structure; //1.时钟使能 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE); //2.初始化 gpio_init_structure.GPIO_Mode=GPIO_Mode_Out_PP; gpio_init_structure.GPIO_Pin=GPIO_Pin_5; gpio_init_structure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOB,&gpio_init_structure); PBout(5)=1;//3.设置初始电平高,不亮 gpio_init_structure.GPIO_Mode=GPIO_Mode_Out_PP; gpio_init_structure.GPIO_Pin=GPIO_Pin_5; gpio_init_structure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOE,&gpio_init_structure); PEout(5)=1;//3.设置初始电平高,不亮 } 5.beep.h void beep_init(void); 1 6.beep.c #include #include void beep_init() { GPIO_InitTypeDef GPIOSetting_structure; //设置IO口模式,速度等信息 GPIOSetting_structure.GPIO_Mode=GPIO_Mode_Out_PP; GPIOSetting_structure.GPIO_Pin=GPIO_Pin_8; GPIOSetting_structure.GPIO_Speed=GPIO_Speed_50MHz; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使相应的时钟 GPIO_Init(GPIOB,&GPIOSetting_structure);//初始化相应的IO GPIO_ResetBits(GPIOB,GPIO_Pin_8);//默认推挽输出低 } 7.main.c #include "key.h" #include "led.h" #include "beep.h" int main(void) { u8 key = 0;//在mdk5里面,变量的声明要放在任何可执行语句之前,否则会报错 delay_init(); beep_init(); led_init(); key_init(); while(1){ key = key_scan(0);//传入1表示按键持续按下会被多次判定有效,传入0时即使按键持续被按下也只判定为被按下一次 if(key) { switch(key) { case 1: beep = !beep;break; case 2: PBout(5) = !PBout(5);break; case 3: PEout(5) = !PEout(5);break; } } delay_ms(10);//10ms扫描一次按键 } } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1851 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1647 浏览 1 评论
1122 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
746 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1704 浏览 2 评论
1959浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
769浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
598浏览 3评论
618浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
578浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-5 11:47 , Processed in 0.702514 second(s), Total 78, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号