[STM32H5] 【NUCLEO-H563ZI测评】4.按键+定时器测试

[复制链接]
 楼主| yuyy1989 发表于 2023-7-21 15:51 | 显示全部楼层 |阅读模式
<
本帖最后由 yuyy1989 于 2023-7-21 15:54 编辑

#申请原创# @21小跑堂
4.按键+定时器测试
NUCLEO-H563ZI预置一个可编程按键,接在了PC13上,高电平触发,打开之前创建的工程,由于选择的是开发板,生成工程时已经将按键的初始化代码写进去了,我们只需要调用即可。
4.1按键轮询测试
按键轮询是间隔很短时间不断查询GPIO状态,从而得知是否有按键动作,按键在按下或释放的过程中,可能会伴随抖动如图示意
QQ截图20230720144441.png
在这抖动过程中,会产生多次高低电平,导致被识别为多次按键操作,因此为了避免误判需要进行去抖处理,软件上可以用延时来去抖
用扫描的方式写个按键程序,用按键控制3个LED的亮灭,代码实现
  1. void usercode_loop(void)
  2. {
  3.     if(HAL_GPIO_ReadPin(USER_BUTTON_GPIO_Port,USER_BUTTON_Pin) == GPIO_PIN_SET)
  4.     {
  5.         HAL_Delay(10);
  6.         while(HAL_GPIO_ReadPin(USER_BUTTON_GPIO_Port,USER_BUTTON_Pin) == GPIO_PIN_SET);
  7.         HAL_GPIO_TogglePin(LED1_GREEN_GPIO_Port,LED1_GREEN_Pin);
  8.         HAL_GPIO_TogglePin(LED2_YELLOW_GPIO_Port,LED2_YELLOW_Pin);
  9.         HAL_GPIO_TogglePin(LED3_RED_GPIO_Port,LED3_RED_Pin);
  10.     }
  11. }
编译烧录查看效果
WeChat_20230720160103 00_00_00-00_00_30.gif
4.2按键中断测试
与上面的轮询方法不同,这种方式并不用一直查询GPIO的状态,按键状态改变时会产生中断,程序在检测到中断后再判断按键状态,接下来用STM32CubeMX配置这个按键的中断
双击工程目录中的这个.ioc文件打开STM32CubeMX
QQ截图20230720152018.png
找到这个按键,发现已经设置为上升沿中断了
QQ截图20230720153911.png
切换到NVIC标签,发现有2个中断但是都没使能
QQ截图20230720153925.png
怎么判断哪一个是这个按键的中断呢,很简单,把鼠标停在右侧按键的GPIO上就能显示GPIO对应的中断名了
QQ截图20230720154039.png
把对应的中断Enable勾选上,点击GENERATE CODE,再重新打开MDK,可以看到中断初始化和中断处理方法都添加好了
QQ截图20230720155119.png QQ截图20230720155130.png
用中断再实现一下按键程序,这次改成每按一次按键改变一个LED的状态,代码实现
  1. uint8_t ledindex = 0;
  2. void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
  3. {
  4.     if(HAL_GPIO_ReadPin(USER_BUTTON_GPIO_Port,USER_BUTTON_Pin) == GPIO_PIN_SET)
  5.     {
  6.         switch(ledindex)
  7.         {
  8.             case 1:
  9.                 HAL_GPIO_TogglePin(LED2_YELLOW_GPIO_Port,LED2_YELLOW_Pin);
  10.                 break;
  11.             case 2:
  12.                 HAL_GPIO_TogglePin(LED3_RED_GPIO_Port,LED3_RED_Pin);
  13.                 break;
  14.             default:
  15.                 HAL_GPIO_TogglePin(LED1_GREEN_GPIO_Port,LED1_GREEN_Pin);
  16.                 ledindex = 0;
  17.                 break;
  18.         }
  19.         ledindex += 1;
  20.     }
  21. }
编译烧录查看效果
WeChat_20230720161238 00_00_00-00_00_30.gif
4.3定时器测试
STM32H563有多达24个timer可用,接下来选一个timer来写个流水灯程序,用按键调速度
双击工程目录中的这个.ioc文件打开STM32CubeMX,找到Timers,这里选择TIM1,Clock Source选择Internal Clock,预分频设置为249计数周期最大值设置为999,这样就得到了一个1毫秒的定时器
QQ截图20230720171323.png
开启中断
QQ截图20230720164600.png
点击GENERATE CODE,打开工程,找到Timer1的初始化方法,这里并没有开启定时中断,需要手动加入开启代码
QQ截图20230720171659.png
流水灯代码
  1. uint8_t ledindex = 0;
  2. uint16_t timer1count = 0;
  3. uint16_t timer1countmax = 1000;
  4. void runled()
  5. {
  6.     switch(ledindex)
  7.     {
  8.         case 1:
  9.             HAL_GPIO_TogglePin(LED2_YELLOW_GPIO_Port,LED2_YELLOW_Pin);
  10.             break;
  11.         case 2:
  12.             HAL_GPIO_TogglePin(LED3_RED_GPIO_Port,LED3_RED_Pin);
  13.             break;
  14.         default:
  15.             HAL_GPIO_TogglePin(LED1_GREEN_GPIO_Port,LED1_GREEN_Pin);
  16.             ledindex = 0;
  17.             break;
  18.     }
  19.     ledindex += 1;
  20. }

  21. void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
  22. {
  23.     if(HAL_GPIO_ReadPin(USER_BUTTON_GPIO_Port,USER_BUTTON_Pin) == GPIO_PIN_SET)
  24.     {
  25.         if(timer1countmax == 1000)
  26.             timer1countmax = 500;
  27.         else if(timer1countmax == 500)
  28.             timer1countmax = 250;
  29.         else if(timer1countmax == 250)
  30.             timer1countmax = 100;
  31.         else
  32.             timer1countmax = 1000;
  33.     }
  34. }

  35. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  36. {
  37.     timer1count+=1;
  38.     if(timer1count >= timer1countmax)
  39.     {
  40.         timer1count = 0;
  41.         runled();
  42.     }
  43. }
编译烧录查看效果
WeChat_20230720172303 00_00_00-00_00_30.gif
4.4PWM输出测试
从STM32CubeMX里看了一下这三个LED的GPIO,绿色的可以用PWM输出,用这个LED做个PWM调光程序,按键修改亮度
点击GPIO选择TIM3_CH3
QQ截图20230720200009.png
在左边的Timers里选择TIM3,Channel3设置为PWM,其它的设置保持和之前TIM1一样即可
QQ截图20230720200137.png
同样PWM也要手动开启输出
QQ截图20230720200525.png
按键控制占空比代码

  1. uint16_t timer3pwm = 0;
  2. void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
  3. {
  4.     if(HAL_GPIO_ReadPin(USER_BUTTON_GPIO_Port,USER_BUTTON_Pin) == GPIO_PIN_SET)
  5.     {
  6.         if(timer3pwm == 0)
  7.             timer3pwm = 50;
  8.         else if(timer3pwm == 50)
  9.             timer3pwm = 100;
  10.         else if(timer3pwm == 100)
  11.             timer3pwm = 250;
  12.         else if(timer3pwm == 250)
  13.             timer3pwm = 500;
  14.         else if(timer3pwm == 500)
  15.             timer3pwm = 1000;
  16.         else
  17.             timer3pwm = 0;
  18.         
  19.         __HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_3,timer3pwm);
  20.     }
  21. }
编译烧录,看看效果
WeChat_20230721081901 00_00_00-00_00_30.gif
数据采集存储 发表于 2023-8-17 17:07 | 显示全部楼层
按键去抖动,还是很不好做的,干扰很大,我看楼主做的很不错哦。
明天真的好 发表于 2023-8-18 17:00 | 显示全部楼层
直接使用中断的模式,是不是会好一些呢?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:同飞软件研发工程师
简介:制冷系统单片机软件开发,使用PID控制温度

161

主题

815

帖子

10

粉丝
快速回复 在线客服 返回列表 返回顶部