| 
 
中级会员  
 
	积分384金钱384 注册时间2023-7-23在线时间89 小时 | 
 
4金钱 
| 最近为了练手,在网上找了一个按键实验的代码根据精英版的知识改造一下,没想到bug不少。以下是主函数的代码: 
 #include "sys.h"#include "usart.h"
 #include "delay.h"
 #include "key.h"
 //ALIENTEK精英STM32F103开发板 实验0
 //新建工程 实验
 //技术支持:www.openedv.com
 //广州市星翼电子科技有限公司
 
 /**
 * @brief  主函数
 * @param  无
 * @retval 无
 */
 int main(void)
 {
 
 Stm32_Clock_Init(9);        //系统时钟设置
 delay_init(72);                          //延时初始化
 uart_init(72,115200);         //串口初始化为115200
 /* LED端口初始化 开始*/
 // 开启GPIOB 端口时钟
 RCC->APB2ENR |= (1<<3);
 RCC->APB2ENR |= (1<<6);
 
 //清空控制PB5的端口位
 GPIOB->CRL &= ~( 0x0F<< (4*5));
 // 配置PB5为通用推挽输出,速度为10M
 GPIOB->CRL |= (1<<(4*5));
 GPIOB->ODR|=1<<5;
 //清空控制PE5的端口位
 GPIOE->CRL &= ~( 0x0F<< (4*5));
 // 配置PE5为通用推挽输出,速度为10M
 GPIOE->CRL |= (1<<(4*5));
 GPIOE->ODR|=1<<5;
 /* 按键端口初始化 */
 Key_GPIO_Config();
 /* LED端口初始化 结束*/
 PEout(5)=!PEout(5);
 PBout(5)=!PBout(5);
 /* 轮询按键状态,若按键按下则反转LED */
 while(1)
 {
 
 if( Key_Scan(PEin(3)) == KEY_ON  )
 {
 /*LED2反转*/
 PBout(5)=!PBout(5);
 }
 
 if( Key_Scan(PEin(4)) == KEY_ON  )
 {
 /*LED1反转*/
 PEout(5)=!PEout(5);
 }
 }
 }
这是key.c的代码
 
 
 #include "key.h"  #include "sys.h"
 /**
 * @brief  配置按键用到的I/O口
 * @param  无
 * @retval 无
 */
 void Key_GPIO_Config(void)
 {
 
 /*开启按键端口的时钟*/
 RCC->APB2ENR|=1<<6;
 GPIOE->CRL &= ~( 0x0F<< (4*4));
 GPIOE->CRL |= (0X8<<(4*4));
 GPIOE->ODR |= (1<<4);
 GPIOE->CRL &= ~( 0x0F<< (4*3));
 GPIOE->CRL |= (0X8<<(4*3));
 GPIOE->ODR |= (1<<3);
 }
 
 /*
 * 函数名:Key_Scan
 * 描述  :检测是否有按键按下
 * 输入  :GPIOx:x 可以是 A,B,C,D或者 E
 *                     GPIO_Pin:待读取的端口位
 * 输出  :KEY_OFF(没按下按键)、KEY_ON(按下按键)
 */
 u8 Key_Scan(u8 KEYxIDR)
 {
 /*检测是否有按键按下 */
 if(KEYxIDR == KEY_ON )
 {
 /*等待按键释放 */
 while(KEYxIDR == KEY_ON);
 return         KEY_ON;
 }
 else
 return KEY_OFF;
 }
以下是key。h的代码:
 
  #include "sys.h"
 #define KEY_ON 1
 #define KEY_OFF 0
 
 void Key_GPIO_Config(void);
 u8 Key_Scan(u8 KEYxIDR);
结果是灯会亮,但是不能根据按键闪。
 然后我有根据原子代码在基础上稍作修改结果灯灵敏度很差。这是主程序代码
 
 #include "sys.h"#include "usart.h"
 #include "delay.h"
 #include "key.h"
 //ALIENTEK精英STM32F103开发板 实验0
 //新建工程 实验
 //技术支持:www.openedv.com
 //广州市星翼电子科技有限公司
 
 /**
 * @brief  主函数
 * @param  无
 * @retval 无
 */
 int main(void)
 {
 /* LED端口初始化开始 */
 
 Stm32_Clock_Init(9);        //系统时钟设置
 delay_init(72);                          //延时初始化
 uart_init(72,115200);         //串口初始化为115200
 // 开启GPIOB 端口时钟
 RCC->APB2ENR |= (1<<3);
 RCC->APB2ENR |= (1<<6);
 
 //清空控制PB5的端口位
 GPIOB->CRL &= ~( 0x0F<< (4*5));
 // 配置PB5为通用推挽输出,速度为10M
 GPIOB->CRL |= (1<<(4*5));
 GPIOB->ODR|=1<<5;
 //清空控制PE5的端口位
 GPIOE->CRL &= ~( 0x0F<< (4*5));
 // 配置PE5为通用推挽输出,速度为10M
 GPIOE->CRL |= (1<<(4*5));
 GPIOE->ODR|=1<<5;
 //led初始化结束
 /* 按键端口初始化 */
 Key_GPIO_Config();
 PEout(5)=!PEout(5);
 PBout(5)=!PBout(5);
 /* 轮询按键状态,若按键按下则反转LED */
 while(1)
 {
 
 if( key_scan(0) == KEY0_PRES  )
 {
 /*LED0反转*/
 PBout(5)=!PBout(5);
 }
 
 if( key_scan(0) == KEY1_PRES  )
 {
 /*LED1反转*/
 PEout(5)=!PEout(5);
 }
 }
 }
以下是key。h的内容
 
  #include "sys.h"
 #define KEY1 PEin(3)
 #define KEY0 PEin(4)
 #define KEY0_PRES  2
 #define KEY1_PRES  1
 
 void Key_GPIO_Config(void);
 uint8_t key_scan(uint8_t mode);
以下是key.c的内容
 
 #include "key.h"  #include "sys.h"
 /**
 * @brief  配置按键用到的I/O口
 * @param  无
 * @retval 无
 */
 void Key_GPIO_Config(void)
 {
 
 /*开启按键端口的时钟*/
 RCC->APB2ENR|=1<<6;
 GPIOE->CRL &= ~( 0x0F<< (4*4));
 GPIOE->CRL |= (0X8<<(4*4));
 GPIOE->ODR |= (1<<4);
 GPIOE->CRL &= ~( 0x0F<< (4*3));
 GPIOE->CRL |= (0X8<<(4*3));
 GPIOE->ODR |= (1<<3);
 }
 
 /*
 * 函数名:Key_Scan
 * 描述  :检测是否有按键按下
 
 */
 uint8_t key_scan(uint8_t mode)
 {
 static uint8_t key_up = 1;  /* 按键按松开标志 */
 uint8_t keyval = 0;
 
 if (mode) key_up = 1;   /* 支持连按 */
 
 if (key_up && (KEY0 == 0 || KEY1 == 0 ))  /* 按键松开标志为1, 且有任意一个按键按下了 */
 {
 delay_ms(10);       /* 去抖动 */
 key_up = 0;
 
 if (KEY0 == 0)  keyval = KEY0_PRES;
 
 if (KEY1 == 0)  keyval = KEY1_PRES;
 
 
 }
 else if (KEY0 == 1 && KEY1 == 1) /* 没有任何按键按下, 标记按键松开 */
 {
 key_up = 1;
 }
 
 return keyval;  /* 返回键值 */
 }
我的板子梅问题用原子的代码按键灵敏很合适。
 
 | 
 
最佳答案
查看完整内容[请看2#楼] 这个while等待抬起一股51的味道
我按着不放你怎么处理呢?
你测试的时候应该是没有按着不放的
那代码也没有什么卡顿,他灵敏度也没有什么问题的
你现在的现象应该是不跟手
你可以试试先两个按键控制一个灯,不要用翻转了 ,一个按键亮一个按键灭
如果这样没有问题的话,那就是重复触发的问题了
你缺少一个消除抖动和只执行一次的标志位
你按下一次按键他可能翻转了10次 那就是还在原来的状态,所以你会感觉卡顿 |