回答

收藏

[评测分享] 【STM32H735-DK 测评】⑧TouchGFX滑块控制舵机角度

#板卡评测 #板卡评测 2127 人阅读 | 0 人回复 | 2024-04-14

本帖最后由 eefocus_3880118 于 2024-4-19 00:00 编辑

今天玩一下Slider控件,用它来控制一下舵机的角度。借此来熟悉一下TouchGFX软件的MVP架构设计

工程还是沿用上一篇的,就不新创建了

一、TouchGFX工程界面设计
先新建一个新的Screen

把新的screen调整为主界面

这样代表主界面的“播放的三角形”图标就在新建的screen上了

放个壁纸,这就是上一篇的内容了,就不详细介绍了
再放一个Slider控件



在Image中可以更换slider的样式,可以更换条子的背景图、被覆盖时的背景图、滑块样式。
背景图更换时要注意两张背景图的尺寸要一致,否则会出现**色感叹号的警告
我这边就更换一个滑块样式吧

还有一个注意点是滑块的value,可以调整他的最大值、最小值、默认值。
我要用滑块控制舵机,那么value就用来表示舵机角度,取值范围应该是0°-180°,默认值就设置为90°

界面基本上就绘制好了
然后还要增加一下事件,当滑块被移动时,就要把当前滑块的值给出去这里我把触发源设置为滑块的value被改变时
对应的动作是调用一个虚函数,回头我们就要在这个函数中去改变PWM值,从而控制舵机
函数名我就不改了,就用默认的好了


然后点击生成代码,接下来就要去cubemx中配置外设去输出PWM波了

二、CUBEMX配置外设
因为Arduino的引脚在开发板的背面,用那边的引脚就没有办法把开发板放平稳,正好套件中有STMOD+的扩展板,他上头正好有我所需的5V、GND、PWM引脚

然后掏出原理图,看一下这个标了PWM的引脚对应的是STM32H735的那个引脚





这个PWM的引脚对应的是PD14,他对应的是TIME4_CH3
在CUBEMX中找到TIM4,然后把CH3配置成PWM输出


接下来开始计算PWM的频率,控制舵机需要的PWM的频率是50hz
那么公式为:频率=时钟/((Prescaler + 1) * (Counter Period + 1))
时钟频率可以看一下技术手册,TIM4挂在APB1时钟下的
APB1的时钟如图,为275Mhz

那么配置如下

这样就得到了50Hz的PWM波

控制舵机的PWM脉宽要求0.5ms-2.5ms,对应舵机的0°-180°,那么,Pulse的值对应的就是25-125.我这边默认值设置为75,对应舵机的90°


三、编写代码
在编写代码前,我们需要了解一下TouchGFX的MVP架构,我把官方的指导文档连接放在这里:Model-View-Presenter设计模式 | TouchGFX Documentation


我理解了一下,简单来说就是
model与用户的APP交互,接收APP要求显示什么内容的指令,或者把屏幕这边的事件给app(例如触摸)
view负责界面显示,由Presenter通知view显示新的内容。当屏幕被触摸等时,把这个触摸的事件给到Presenter
Presenter是model和view之间桥梁,起到收发数据,逻辑转换的作用

这样全部拆开的架构,每个模块都有自己主要负责内容,简单易维护。
model只有一个,view和Presenter每个screen都各有一个,但是同一时间只会存在一个view和Presenter,他们使用动态分配的方式,这样可以较少的占用内存
自动生成的代码结构如图所示


简单了解了架构后,就去代码中实操一下在Screen2ViewBase.hpp中可以看到自动创建的虚函数function1

在Screen2ViewBase.cpp中可以看到slider value改变后的回调函数,它里面会调用function1,这些都是自动生成的,不需要我们去做


然后在Screen2View.hpp中声明一下function1

  1. virtual void function1(int value);
复制代码


然后在Screen2View.cpp中实现它
  1. #include "stm32h7xx_hal.h"
复制代码
  1. void Screen2View::function1(int value)
  2. {
  3.     TIM4->CCR3 = 125 * value / 180;
  4. }
复制代码


我这边为了快速验证功能的可行性,非常简单粗暴的在这里直接修改寄存器的CCR的值来改变占空比。测试了一下,是可以工作的。

但是按照MVP架构,应该是在VIEW中获取slider的value,然后把这个value传递给Presenter,然后由Presenter再给到model,然后再去改变占空比。所以这边还需要再修改一下
首先是在view中获取slider的value
把刚才的function1函数里面的内容修改一下(记得把刚才的#include "stm32h7xx_hal.h"删除掉,那个已经没用了)
  1. void Screen2View::function1(int value)
  2. {
  3.     /* 把slider的值(舵机角度)传给presenter */
  4.     presenter->ServoAngleToTimerRCC(value);
  5. }
复制代码

然后我们去Screen2Presenter.cpp里面写一下ServoAngleToTimerRCC函数
  1. void Screen2Presenter::ServoAngleToTimerRCC(int angle)
  2. {
  3.     /* 根据angle(舵机角度)计算出timer RCC需要被设置的值 */
  4.     int timerRccValue = 125 * angle / 180;
  5.     /*把计算出来的timer RCC的值给到model,去控制舵机角度*/
  6.     model->settimerRccValue(timerRccValue);
  7. }
复制代码


Screen2Presenter.hpp中声明一下ServoAngleToTimerRCC函数
  1. void ServoAngleToTimerRCC(int value);
复制代码


最后来到model.cpp中去控制舵机的角度
  1. #include "stm32h7xx_hal.h"
复制代码
  1. void Model::settimerRccValue(int angle)
  2. {
  3.     TIM4->CCR3 = angle;
  4. }
复制代码

然后在model.hpp对这个函数声明
  1. void settimerRccValue(int angle);
复制代码


最后在mian中要把PWM启动一下
  1. HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_3);
复制代码
这样我们就可以通过滑动slider控制舵机的角度了

效果如下





演示视频.rar (8.81 MB, 下载次数: 0)















分享到:
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条