本帖最后由 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时钟下的
那么配置如下
这样就得到了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
- virtual void function1(int value);
复制代码
然后在Screen2View.cpp中实现它 - #include "stm32h7xx_hal.h"
复制代码- void Screen2View::function1(int value)
- {
- TIM4->CCR3 = 125 * value / 180;
- }
复制代码
我这边为了快速验证功能的可行性,非常简单粗暴的在这里直接修改寄存器的CCR的值来改变占空比。测试了一下,是可以工作的。
但是按照MVP架构,应该是在VIEW中获取slider的value,然后把这个value传递给Presenter,然后由Presenter再给到model,然后再去改变占空比。所以这边还需要再修改一下 首先是在view中获取slider的value 把刚才的function1函数里面的内容修改一下(记得把刚才的#include "stm32h7xx_hal.h"删除掉,那个已经没用了) - void Screen2View::function1(int value)
- {
- /* 把slider的值(舵机角度)传给presenter */
- presenter->ServoAngleToTimerRCC(value);
- }
复制代码
然后我们去Screen2Presenter.cpp里面写一下ServoAngleToTimerRCC函数 - void Screen2Presenter::ServoAngleToTimerRCC(int angle)
- {
- /* 根据angle(舵机角度)计算出timer RCC需要被设置的值 */
- int timerRccValue = 125 * angle / 180;
- /*把计算出来的timer RCC的值给到model,去控制舵机角度*/
- model->settimerRccValue(timerRccValue);
- }
复制代码
Screen2Presenter.hpp中声明一下ServoAngleToTimerRCC函数 - void ServoAngleToTimerRCC(int value);
复制代码
最后来到model.cpp中去控制舵机的角度 - #include "stm32h7xx_hal.h"
复制代码- void Model::settimerRccValue(int angle)
- {
- TIM4->CCR3 = angle;
- }
复制代码
然后在model.hpp对这个函数声明 - void settimerRccValue(int angle);
复制代码
最后在mian中要把PWM启动一下- HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_3);
复制代码 这样我们就可以通过滑动slider控制舵机的角度了
效果如下
演示视频.rar
(8.81 MB, 下载次数: 0)
|