试验流程

  • 主要内容
    • cubemx配置
    • 代码部分
      • 1.普通功能
      • 2.模块化设计
        • 1
        • 2
    • 遇到的问题

主要内容

上一篇文章中采用了EXTI中断的方式控制小灯的亮灭。其实也可以不采用中断,直接使用GPIO配置即可实现按键对应小灯的状态,且效果几乎相同。同样本次例程试验采用正点原子阿波罗STM32F429IGT6开发板,debug采用STLink(后续的文章中将不再赘述)。
试验的主要内容有:
1.正常的配置流程
2.修改代码实现对功能的优化和模块化设计

cubemx配置

按照相同的步骤,选择芯片,配置时钟树,小灯和按键的配置都和上节相同,不再赘述。
(需要注意的是,延时的操作不可避免的要使用HAL_Delay()函数,故在SYS处Debug勾选Serial Wire确保延时函数的正确使用。同时注意延时函数的优先级,本节例程暂时不会有冲突,但后续的会有,错误的优先级会导致程序卡死,后续再强调)

代码部分

1.普通功能

初始化配置已经在cubemx基本完成,我们的思路是检测按键的电平状态,通过GPIO反转函数令小灯的电平翻转,实现亮灭
主体函数如下所示

while (1){if(HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_3) == GPIO_PIN_RESET)HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_0);if(HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_3) == GPIO_PIN_SET)HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_0);   if(HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_2) == GPIO_PIN_RESET)HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_1);if(HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_2) == GPIO_PIN_SET)HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_1);}

通过上电发现,并没有很好地实现功能,按键按下两个灯闪烁不定,此时考虑到没有对按键进行消抖处理。
按键消抖:由于采用的是机械按键,在按下瞬间的电平变化并不是理想的阶跃信号,具体的变化大致如图所示

延时的操作主要就是:在第一个if语句处再加嵌套,插入延时函数HAL_Delay(10)(大多数的前后抖动时长约为10ms,人为造成的刻意抖动也不过四五十ms),此处要求cubemx处配置好systick相关的初始化打开(前面强调过)调整后代码所示:

while (1){if(HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_3) == GPIO_PIN_RESET){HAL_Delay(10);if(HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_3) == GPIO_PIN_RESET){HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_0);}}if(HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_3) == GPIO_PIN_SET){HAL_Delay(10);if(HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_3) == GPIO_PIN_SET){              HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_0); }}if(HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_2) == GPIO_PIN_RESET){HAL_Delay(10);if(HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_2) == GPIO_PIN_RESET){HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_1);}}if(HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_2) == GPIO_PIN_SET && flag == 1){HAL_Delay(10);if(HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_2) == GPIO_PIN_RESET){HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_1);}}

烧录进开发板,效果甚至更糟了,分析之后得出,按键的按下不应该仅仅有硬件的配置环节,也需要存在程序中的“标志位”对应进行软件把控,才能实现按键按下瞬间的电平转换。
在cubemx生成的文件中,特定区域进行填写,可以保证工程在cubemx修改引脚初始化之后修改的工程仍可被保存。

  /* USER CODE BEGIN 2 */uint8_t flag=0;/* USER CODE END 2 */

flag为设定的标志位,当按键被按下的时候,一来检测按键的电平,二来直接检测标志位是否为0(前一状态为没按下),先将标志位置1,随后将小灯电平翻转,反之亦然,这样就不会存在逻辑错误。具体代码不再展示,烧录带开发板现象良好。

2.模块化设计

初学者拿到官方的例程,很多封装处理不好的函数,给阅读和理解造成很大难度,移植到自己的程序里也是bug百出。通过模块化的设计增强可移植性,便于理解和阅读。
将上一步骤最后的程序封装起来即可,具体过程大致思路:

1

在主函数下定义一个名为get_pin的函数,添加了两个个参数,以只点亮PB
具体代码所示:

void get_pin(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin)
{static uint8_t flag= 0;if(HAL_GPIO_ReadPin(GPIOx,GPIO_Pin) == GPIO_PIN_RESET && flag == 0){HAL_Delay(20);if(HAL_GPIO_ReadPin(GPIOx,GPIO_Pin) == GPIO_PIN_RESET  && flag== 0){flag= 1;HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_0);}}if(HAL_GPIO_ReadPin(GPIOx,GPIO_Pin) == GPIO_PIN_SET && flag== 1){HAL_Delay(20);if(HAL_GPIO_ReadPin(GPIOx,GPIO_Pin) == GPIO_PIN_SET && flag== 1){
//          HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_0);   flag= 0;}}

在主函数中 while(1)中调用

/* USER CODE BEGIN WHILE */while (1){get_pin(GPIOH,GPIO_PIN_2);}/* USER CODE END WHILE */

烧录到板子中,没有问题,显示状态和按键对应都很好

2

这种通过构建函数的调用方式有一些鸡肋,也没有很好地起到可读性加强的作用,通过在工程中加入.h文件,通过一些参数的加入和弱定义函数的实现使得程序更简洁
首先在工程目录下加入名为add_key.h文件,并在keil中添加,target -> C/C++处勾选路径,并在主函数声明,如图所示



编译通过,没有报错。
第二步,在.h文件中声明函数,并添加函数成分中结构体的来源:stm32f4xx_hal.h(具体查询可以先输入函数,F12跳转到报错部分添加即可)
需要注意的是,.h文件提供了弱定义函数的整理和存放,最后这些文件的声明都需要在main.c文件下进行人为编写,具体功能类似于中断中的回调函数,在上篇文章中有介绍,下篇文章会详细说一下
具体代码所示:

void get_pin(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin,uint8_t i)
{static uint8_t flag[2] = {0};if(HAL_GPIO_ReadPin(GPIOx,GPIO_Pin) == GPIO_PIN_RESET && flag[i] == 0){HAL_Delay(20);if(HAL_GPIO_ReadPin(GPIOx,GPIO_Pin) == GPIO_PIN_RESET  && flag[i] == 0){flag[i] = 1;key_up_to_down(i);}}if(HAL_GPIO_ReadPin(GPIOx,GPIO_Pin) == GPIO_PIN_SET && flag[i] == 1){HAL_Delay(20);if(HAL_GPIO_ReadPin(GPIOH,GPIO_Pin) == GPIO_PIN_SET && flag[i] == 1){
//          HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_0);   flag[i] = 0;key_down_to_up(i);}}if(flag[i] == 0) key_up(i);if(flag[i] == 1) key_down(i);

此处将两个按键的功能集成到一个函数中,通过数组的选择来实现按键对灯的控制
之后完善弱定义函数部分的代码

void key_up_to_down(uint8_t i)
{if(i == 0) HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_0);
}
void key_down_to_up(uint8_t i)
{if(i == 0) HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_0);
}void key_up(uint8_t i)
{if(i == 1) HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET);
}void key_down(uint8_t i)
{if(i == 1) HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET);
}

经过上面一系列的操作,最后在while中实现的就很简单了

while (1){get_pin(GPIOH,GPIO_PIN_2,1);get_pin(GPIOH,GPIO_PIN_3,0);}

这样对应的是:PH2(KEY1)–PB1(RED),PH3(KEY0)–PB0(GREEN)
烧录到开发板上,现象很好,实现了预期的功能
而且需要对换对应关系,只需要getpin最后参数1/0即可

遇到的问题

在调试板子的过程中,发现一个小问题。设置了软件消抖,但这样会导致小灯的亮灭出现肉眼可见的频闪,这是超出预期之外的。取消消抖又会由于机械按键的抖动使得点亮状态的对应出现问题。通过外加函数的递归调用,可以消除这个问题,使得二者都达到预期的效果。
为了找到问题的原因,第一次调整了cubemx上对灯识别沿的选项,并没有明显的效果,后来写的弱定义的小灯状态函数,通过主函数的调用将问题解决。这个问题暂时还么有找到原因,后续的学习中会再注意。有可能是硬件的问题,但更多应该是软件的配置出现问题。在检查上一篇文章的代码时也发现了类似的问题,如果有大神可以指点一二,不胜感谢。
(ps:本文是根据露神六鸽的视频自己手打了一遍的学习历程,tql)

【零基础学STM32】CubeMx+HAL配置按键点灯实验相关推荐

  1. 零基础学stm32要多久?stm32应该怎么学?

    STM32由于资料丰富.稳定.性价比高深得广大工程师和企业的喜爱. 现在随便在招聘平台上搜索单片机开发或者嵌入式开发,基本都要求会STM32. 我用STM32也有很多年了,基本上是围绕着F103.F0 ...

  2. 【零基础学STM32】CubeMX+HAL玩转电机控制

    Motor 主要内容 前置知识 CubeMX配置 代码 出现的问题 参考文献 主要内容 基于被我鸽了的电控作业 主控 STM32F429IGT6 电机TT小黄 模拟小车所以两路编码器 前置知识包括 P ...

  3. 【零基础学STM32】CubeMX+HAL 喂狗小教程

    IWDG&WWDG 内容简介 一点小原理 CubeMX配置 工程代码 出现的问题 参考文献 内容简介 IWDG独立看门狗&WWDG窗口看门狗作为特殊的两类定时器,在检测异常,定期复位有 ...

  4. 《零基础学JavaScript(全彩版)》学习笔记

    <零基础学JavaScript(全彩版)>学习笔记 二〇一九年二月九日星期六0时9分 前期: 刚刚学完<零基础学HTML5+CSS3(全彩版)>,准备开始学习JavaScrip ...

  5. 零基础学Java需要做哪些准备

    想要成为一名合格的java工程师,那么好好学习java技术是非常重要的,对于零基础同学们来说,大家比较关注的就是"零基础学Java需要做哪些准备"这个问题,下面小编就来为大家做下详 ...

  6. proteus仿真micropython_【雕爷学编程】MicroPython动手做(04)——零基础学MaixPy之尝试运行...

    1.hello micropython #MicroPython动手做(04)--零基础学MaixPy之基本示例 #程序之一:hellomicropython #MicroPython动手做(04)- ...

  7. python入门到精通需要学多久-廖雪峰python教程要学多久-零基础学Python需要多久...

    零基础学python大约需要多久 看不同的人,不同的学习能和基础. 像我通java,vc ,javascript,groovy,vb,c 接触过c#,delphi,asp,E语言, 用过dreamwa ...

  8. python零基础入门教程学习要多久-廖雪峰python教程要学多久-零基础学Python需要多久...

    零基础学python大约需要多久 看不同的人,不同的学习能和基础. 像我通java,vc ,javascript,groovy,vb,c 接触过c#,delphi,asp,E语言, 用过dreamwa ...

  9. python学起来难不难-零基础学Python爬虫难不难?要怎么学?

    零基础学Python爬虫难不难?要怎么学?众所周知,Python是最容易上手的编程语言,如果有一定基础,学会Python爬虫也是分分钟钟的事.对于零基础的学习者来说,Python爬虫也是比较简单的,只 ...

最新文章

  1. mxnet基础到提高(24)-C++-符号,变量读写
  2. python调用ffmpeg_Python - FFmpeg
  3. bootstrap 栅栏剧中_Bootstrap 栅栏布局中 col-xs-*、col-sm-*、col-md-*、col-lg-* 区别及使用方法...
  4. Maze(BFS处理)
  5. Kaggle新赛 | 医学影像插管分类,总奖池 5 万美金
  6. 如何确定图片名未改变 php,这里未改变的是数据库中默认的数据,比如修改时间?,还有发布用户名?...
  7. [裴礼文数学分析中的典型问题与方法习题参考解答]4.4.8
  8. 美团团购订单系统优化记
  9. 电脑清灰过后,CPU温度下降,显卡温度却上升了
  10. H5音乐播放器(小清新版)
  11. 强化云原生基础服务,焱融科技 YRCloudFile 与秒云完成产品兼容性互认证
  12. 解决dataTable在element下的tab切换时表头与内容错位问题
  13. 联想hx系列服务器,联想ThinkAgile HX系列 融合
  14. 【论文笔记】Image Manipulation Detection by Multi-View Multi-Scale Supervision
  15. 英语 计算机水平怎么填写,计算机水平一般怎么填
  16. 北京 matlab,北京交通大学Matlab.ppt
  17. 系统架构_软件架构风格概述
  18. 华南理工广州学院 计算机专业,华南理工大学广州学院学子在“中国高校计算机...
  19. 记一次获取QQ音乐播放源链接地址
  20. w10系统,怎样调整应用的分辨率

热门文章

  1. 侯教授的JAVA 2011-03-10
  2. python字体变方格_解决Python数据可视化中文部分显示方块问题
  3. python机器学习classification_report()函数 输出模型评估报告
  4. carthage踩坑
  5. 不抬杠!高通华为,5G时代谁厉害?
  6. 中国超融合厂商三甲出炉,华为、华云数据、新华三再次稳居中国超融合市场领导者
  7. cocos creator编写《皇家守卫军》开场UI之场景切换开关门动画
  8. 干货|合法练习黑客技术?这7个网站一定可以帮到你
  9. arduino架子鼓_【Arduino中级系列教程】项目六 互动电子鼓
  10. mysql getgeneratedkeys,JDBC获得数据库生成的主键(JDBC、Primary Key)