STM32单片机项目实战:TouchGFX智能手表(9)底层驱动与UI关联

STM32单片机项目实战:TouchGFX智能手表(9)底层驱动与UI关联一、概述与代码添加在TouchGFX中,从Model类执行与应用非UI部分(这里称为后端系统)的通信。后端系统是从UI接收事件和将事件输入UI的

大家好,欢迎来到IT知识分享网。

一、概述与代码添加

在TouchGFX中,从Model类执行与应用非UI部分(这里称为后端系统)的通信。后端系统是从UI接收事件和将事件输入UI的软件组件,例如采集传感器的新测量值。后端系统可作为单独的任务在同一MCU、单独的处理器、云模块或其他硬件上运行。从TouchGFX的角度来看,这并不十分重要,只要它是能够与之通信的组件。

使用的特定通信协议不受TouchGFX管理。它只提供一个在每个TouchGFX嘀嗒时间调用一次的函数,可以在其中处理需要的通信。

STM32单片机项目实战:TouchGFX智能手表(9)底层驱动与UI关联

图 1-1 Model-View-Presenter和外部通信

Model 类是一个永远存在的单类,它有两个用途:

1. 保存UI的状态信息。 在切换屏幕时,View和Presenter的分配会被清除,因此它们不能用于存储在屏幕转换时应当保留的信息。 为此,使用Model保存信息。

2. 作为面向后端系统的接口,向/从当前活动屏幕发送事件。

Model类是自动设置的,具有指向当前活动Presenter的指针。当Model中发生变化时,将变化通知当前活动Presenter。这是通过应用中ModelListener接口中的方法来完成的。TouchGFX Designer生成的新应用将自动拥有可直接供UI使用的Model类。

采用STM32CubeMX配置TouchGFX后,需要打开TouchGFX 4.21.2 Designer软件重新生成以下代码,避免MDK编译报错。配置生成的代码中主要包含三个文件:Model.cpp、Model.hpp、ModelListener.hpp,在这个三个文件中添加与UI相关的数据交互接口。

Model.cpp文件:

#include <gui/model/Model.hpp> #include <gui/model/ModelListener.hpp> Model::Model() : modelListener(0) { } void Model::tick() { }

Model.hpp文件:

#ifndef MODEL_HPP #define MODEL_HPP class ModelListener; class Model { public: Model(); void bind(ModelListener* listener) { modelListener = listener; } void tick(); protected: ModelListener* modelListener; }; #endif // MODEL_HPP

ModelListener.hpp文件:

#ifndef MODELLISTENER_HPP #define MODELLISTENER_HPP #include <gui/model/Model.hpp> class ModelListener { public: ModelListener() : model(0) {} virtual ~ModelListener() {} void bind(Model* m) { model = m; } protected: Model* model; }; #endif // MODELLISTENER_HPP

在Model.cpp中增加与底层驱动关联代码,Model.hpp与ModelListener.hpp用于函数的声明。下面是基于TouchGFX的智能手表设计的Model.cpp中的底层关联代码:

#include <gui/model/Model.hpp> #include <gui/model/ModelListener.hpp> #if defined LINK_HARDWARE //TuchGFX仿真与实际硬件操作隔离 //头文件包含 extern "C" { #include "user_app.h" } //底层数据 extern volatile SHT20_TemRH_Val gTemRH_Val; extern RTC_DateTypeDef gSystemDate; //获取日期结构体 extern RTC_TimeTypeDef gSystemTime; //获取时间结构体 extern gTask_BitDef gTaskStateBit; //任务执行过程中使用到的标志位 extern gTask_MarkEN gTaskEnMark; //系统任务使能标识 extern volatile StruAP3216C_Val gAP3216C_Val; //AP3216数据结构 extern volatile uint8_t gLastTimeSeconds; //上一次的时间 extern volatile float pitch,roll,yaw; //欧拉角 extern unsigned long gSportStep; //运动步数 extern wifiRSSI ao_wifiRSSI; extern uint8_t gFiveKeyFunc; //定义的五向按键值功能 extern volatile uint16_t gCurrentVal; //资源扩展板电流,通道IN8 extern volatile uint16_t gVoltageVal; //资源扩展板电压,通道IN9 extern volatile uint16_t gChipTempVal;//内部参考电压,通道IN12 extern volatile uint16_t gVrefVal; //内部参考电压,通道IN13 extern volatile uint16_t gVbatVal; //RTC电池电压,通道IN14 extern int32_t n_heart_rate; //heart rate value=n_heart_rate/4,采样率100sps,max30102设置4点求平均 extern int32_t n_sp02; //SPO2 value extern int8_t ch_spo2_valid; //indicator to show if the SP02 calculation is valid extern int8_t ch_hr_valid; //indicator to show if the heart rate calculation is valid extern uint8_t gWiFiInfo[40]; //用于通知View界面的Text文本显示 // volatile uint8_t gSwitchSpace = 0x00; //页面切换的时间间隙 static int32_t gHeartRate = 0; //表盘页面的心率数据 #else //Designer仿真 #include <ctime> #ifndef _MSC_VER #include <sys/time.h> #endif /* _MSC_VER*/ // volatile uint8_t gBacklightVal = 50; //背光值,默认50% #endif /**********************************TouchGFX与底层间的访问**********************************/ Model::Model() : modelListener(0) { } // void Model::tick() { static uint8_t tickCount = 0; //减少数据上传的次数,优化界面刷新 tickCount++; #if defined LINK_HARDWARE // if(gSwitchSpace != 0) gSwitchSpace--; /********************************硬件页面切换*********************************/ //表盘页面 if(gTaskEnMark.UPDATE_DIAL_EN && (gTaskStateBit.TouchPress == 0) && (!gSwitchSpace)) { modelListener->DialPageChange(gFiveKeyFunc); gSwitchSpace = 0x0F; //使能切换时间计数 } //应用页面 if(gTaskEnMark.UPDATE_APPPAGE && (gTaskStateBit.TouchPress == 0) && (!gSwitchSpace)) { modelListener->AppPageChange(gFiveKeyFunc); gSwitchSpace = 0x0F; //使能切换时间计数 } //六轴页面 if(gTaskEnMark.UPDATE_SIX_AXIS_EN && (gTaskStateBit.TouchPress == 0) && (!gSwitchSpace)) { modelListener->SixAxisPageChange(gFiveKeyFunc); gSwitchSpace = 0x0F; //使能切换时间计数 } //无线页面 if(gTaskEnMark.UPDATE_WIFIPAGE && (gTaskStateBit.TouchPress == 0) && (!gSwitchSpace)) { modelListener->WiFiPageChange(gFiveKeyFunc); gSwitchSpace = 0x0F; //使能切换时间计数 } //设置页面 if(gTaskEnMark.UPDATE_SETTINGPAGE && (gTaskStateBit.TouchPress == 0) && (!gSwitchSpace)) { modelListener->SettingPageChange(gFiveKeyFunc); gSwitchSpace = 0x0F; //使能切换时间计数 } //控制页面 if(gTaskEnMark.UPDATE_MOTORPAGE && (gTaskStateBit.TouchPress == 0) && (!gSwitchSpace)) { modelListener->MotorPageChange(gFiveKeyFunc); gSwitchSpace = 0x0F; //使能切换时间计数 } //信息页面,温度、湿度与光强度 if(gTaskEnMark.UPDATE_INFOPAGE && (gTaskStateBit.TouchPress == 0) && (!gSwitchSpace)) { modelListener->InfoPageChange(gFiveKeyFunc); gSwitchSpace = 0x0F; //使能切换时间计数 } //健康页面 if(gTaskEnMark.UPDATE_HEALTHPAGE && (gTaskStateBit.TouchPress == 0) && (!gSwitchSpace)) { modelListener->HealthPageChange(gFiveKeyFunc); gSwitchSpace = 0x0F; //使能切换时间计数 } //Chip页面 if(gTaskEnMark.UPDATE_CHIPPAGE && (gTaskStateBit.TouchPress == 0) && (!gSwitchSpace)) { modelListener->ChipPageChange(gFiveKeyFunc); gSwitchSpace = 0x0F; //使能切换时间计数 } //Battery页面 if(gTaskEnMark.UPDATE_BATTERYPAGE && (gTaskStateBit.TouchPress == 0) && (!gSwitchSpace)) { modelListener->BatteryPageChange(gFiveKeyFunc); gSwitchSpace = 0x0F; //使能切换时间计数 } //Sport页面退出 if(gTaskEnMark.UPDATE_SPORTPAGE && (gTaskStateBit.TouchPress == 0) && (!gSwitchSpace)) { modelListener->SportPageExit(gFiveKeyFunc); gSwitchSpace = 0x0F; //使能切换时间计数 } //Alipay页面退出 if(gTaskEnMark.UPDATE_ALIPAYPAGE && (gTaskStateBit.TouchPress == 0) && (!gSwitchSpace)) { modelListener->AlipayPageChange(gFiveKeyFunc); gSwitchSpace = 0x0F; //使能切换时间计数 } //Sport页面进入 if(!HAL_GPIO_ReadPin(USER_KEY_GPIO_Port,USER_KEY_Pin)) { modelListener->SportPageEnter(3); } /********************************更新各类信息*********************************/ //更新时间信息,为使表盘页面滑动操作正常,在屏幕被点按时不更新数据 if(gTaskEnMark.UPDATE_DIAL_EN && (gSystemTime.Seconds != gLastTimeSeconds)&&(gTaskStateBit.TouchPress == 0)) //每秒同步一次界面时间 { modelListener->updateDate(gSystemDate.Year,gSystemDate.Month,gSystemDate.Date,gSystemDate.WeekDay); modelListener->updateTime(gSystemTime.Hours, gSystemTime.Minutes, gSystemTime.Seconds); //更新新值 gLastTimeSeconds = gSystemTime.Seconds; //更新温度/步数/心率 modelListener->updateTempStepHeart(gTemRH_Val.Tem,gSportStep,gHeartRate); } //健康监测信息上传 if(gTaskEnMark.UPDATE_HEALTHPAGE && (gTaskStateBit.TouchPress == 0)) { //send samples and calculation result to terminal program through UART if(ch_hr_valid || ch_spo2_valid) { modelListener->updateHeartRateInfo(n_heart_rate/4, n_sp02); gHeartRate = n_heart_rate/4; //保存心率数据值表盘页面 } // if(gTaskStateBit.Max30102) //单次测量完成,清除标志 { ch_hr_valid =0; ch_spo2_valid=0; gTaskStateBit.Max30102 = 0; } } //更新欧拉角 if(gTaskEnMark.UPDATE_SIX_AXIS_EN) //六轴界面活动时上传 { modelListener->updateSixAxis(pitch, roll, yaw); } //获取WiFi模组的RSSI值 if((gTaskEnMark.UPDATE_WIFI_RSSI_EN)) //只有在系统主页时,才进行WiFi的RSSI数据读取 { modelListener->updateWiFiRSSI(gWiFiInfo, ao_wifiRSSI.gRSSI); } //更新温湿度信息 if(gTaskEnMark.UPDATE_INFOPAGE) //INFO面活动时上传 { modelListener->updateInfo(gTemRH_Val.Hum, gTemRH_Val.Tem, gAP3216C_Val.ALS); } //更新芯片参数 if(gTaskEnMark.UPDATE_CHIPPAGE && (!(tickCount % 5))) { modelListener->updateChipInfor(gChipTempVal, gVrefVal, gVbatVal); //更新芯片温度、参考电压、Vbat } //更新电压与电流 if(gTaskEnMark.UPDATE_BATTERYPAGE) { modelListener->updateBatteryPageInfo(gCurrentVal, gVoltageVal); //更新电压与电流 } #else //Designer仿真 timeval timenow; gettimeofday(&timenow, NULL); //仿真更新时间 modelListener->updateTime((timenow.tv_sec / 60 / 60) % 24,(timenow.tv_sec / 60) % 60,timenow.tv_sec % 60); #endif } //风扇操作 void Model::turnFanStatus(bool enable) { #if defined LINK_HARDWARE if(enable == true) HAL_GPIO_WritePin(EXT_FAN_GPIO_Port,EXT_FAN_Pin,GPIO_PIN_SET); //风扇状态的设置 else HAL_GPIO_WritePin(EXT_FAN_GPIO_Port,EXT_FAN_Pin,GPIO_PIN_RESET); #endif } //振动电机操作 void Model::setMotorStatus(bool enable) { #if defined LINK_HARDWARE if(enable == true) HAL_GPIO_WritePin(EXT_MOTOR_GPIO_Port,EXT_MOTOR_Pin,GPIO_PIN_SET); //振动电机状态的设置 else HAL_GPIO_WritePin(EXT_MOTOR_GPIO_Port,EXT_MOTOR_Pin,GPIO_PIN_RESET); #endif } //排水操作 void Model::drainWaterStatus(bool enable) { #if defined LINK_HARDWARE if(enable == true) HAL_GPIO_WritePin(EXT_MOTOR_GPIO_Port,EXT_MOTOR_Pin,GPIO_PIN_SET); //振动电机设置 else HAL_GPIO_WritePin(EXT_MOTOR_GPIO_Port,EXT_MOTOR_Pin,GPIO_PIN_RESET); #endif } //蜂鸣器操作 void Model::setBuzzerStatus(bool enable) { #if defined LINK_HARDWARE if(enable == true) HAL_GPIO_WritePin(RUN_BEEP_GPIO_Port,RUN_BEEP_Pin,GPIO_PIN_SET); //蜂鸣器状态的设置 else HAL_GPIO_WritePin(RUN_BEEP_GPIO_Port,RUN_BEEP_Pin,GPIO_PIN_RESET); #endif } /*********************gTaskEnMark赋值*************************/ //DialView的任务的状态 void Model::DialPageViewTask(bool enable) { #if defined LINK_HARDWARE if(enable == true) gTaskEnMark.UPDATE_DIAL_EN = 1; //任务使能 else gTaskEnMark.UPDATE_DIAL_EN = 0; //任务清除 #endif } //ApplicationPageView的任务的状态 void Model::ApplicationPageViewTask(bool enable) { #if defined LINK_HARDWARE if(enable == true) gTaskEnMark.UPDATE_APPPAGE = 1; //任务使能 else gTaskEnMark.UPDATE_APPPAGE = 0; //任务清除 #endif } //SixAxisPageView的任务的状态 void Model::SixAxisPageViewTask(bool enable) { #if defined LINK_HARDWARE if(enable == true) gTaskEnMark.UPDATE_SIX_AXIS_EN = 1; //任务使能 else gTaskEnMark.UPDATE_SIX_AXIS_EN = 0; //任务清除 #endif } //InfoPageView任务使能 void Model::InfoPageViewTask(bool newStatus) { #if defined LINK_HARDWARE if(newStatus == true) gTaskEnMark.UPDATE_INFOPAGE = 1; //任务使能 else gTaskEnMark.UPDATE_INFOPAGE = 0; //任务清除 #endif } //ChipPageViewTask的任务的状态 void Model::ChipPageViewTask(bool enable) { #if defined LINK_HARDWARE if(enable == true) gTaskEnMark.UPDATE_CHIPPAGE = 1; //任务使能 else gTaskEnMark.UPDATE_CHIPPAGE = 0; //任务清除 #endif } //设置健康监测任务 void Model::HealthPageViewTask(bool newStatus) { #if defined LINK_HARDWARE if(newStatus == true) gTaskEnMark.UPDATE_HEALTHPAGE = 1; //任务使能 else gTaskEnMark.UPDATE_HEALTHPAGE = 0; //任务清除 #endif } //WiFi连接的任务状态 void Model::WiFiLinkTask(bool enable) { #if defined LINK_HARDWARE if(enable == true) gTaskEnMark.UPDATE_WIFI_RSSI_EN = 1; //任务使能 else gTaskEnMark.UPDATE_WIFI_RSSI_EN = 0; //任务清除 #endif } //WiFi界面的任务状态 void Model::WiFiPageViewTask(bool enable) { #if defined LINK_HARDWARE if(enable == true) gTaskEnMark.UPDATE_WIFIPAGE = 1; //任务使能 else gTaskEnMark.UPDATE_WIFIPAGE = 0; //任务清除 #endif } //Setting界面的任务状态 void Model::SettingPageViewTask(bool enable) { #if defined LINK_HARDWARE if(enable == true) gTaskEnMark.UPDATE_SETTINGPAGE = 1; //任务使能 else gTaskEnMark.UPDATE_SETTINGPAGE = 0; //任务清除 #endif } //Motor界面的任务状态 void Model::MotorPageViewTask(bool enable) { #if defined LINK_HARDWARE if(enable == true) gTaskEnMark.UPDATE_MOTORPAGE = 1; //任务使能 else gTaskEnMark.UPDATE_MOTORPAGE = 0; //任务清除 #endif } //Battery界面的任务状态 void Model::BatteryPageViewTask(bool enable) { #if defined LINK_HARDWARE if(enable == true) gTaskEnMark.UPDATE_BATTERYPAGE = 1; //任务使能 else gTaskEnMark.UPDATE_BATTERYPAGE = 0; //任务清除 #endif } //运动界面的任务状态 void Model::SportPageViewTask(bool enable) { #if defined LINK_HARDWARE if(enable == true) gTaskEnMark.UPDATE_SPORTPAGE = 1; //任务使能 else gTaskEnMark.UPDATE_SPORTPAGE = 0; //任务清除 #endif } //Aliplay界面任务状态 void Model::AlipayPageViewTask(bool enable) { #if defined LINK_HARDWARE if(enable == true) gTaskEnMark.UPDATE_ALIPAYPAGE = 1; //任务使能 else gTaskEnMark.UPDATE_ALIPAYPAGE = 0; //任务清除 #endif }

Model.hpp中的函数声明:

#ifndef MODEL_HPP #define MODEL_HPP class ModelListener; class Model { public: Model(); void bind(ModelListener* listener) { modelListener = listener; } void tick(); //SettingPageView的任务的状态 void SettingPageViewTask(bool enable); //DialPageView的任务的状态 void DialPageViewTask(bool enable); //FiveKeyPageView的任务的状态 void FiveKeyPageViewTask(bool enable); //ApplicationPageView的任务的状态 void ApplicationPageViewTask(bool enable); //SixAxisPageView的任务的状态 void SixAxisPageViewTask(bool enable); //InfoPageView的任务的状态 void InfoPageViewTask(bool enable); //ChipPageView的任务的状态 void ChipPageViewTask(bool enable); //WiFiPageView的任务的状态 void WiFiPageViewTask(bool enable); //MotorPageView的任务的状态 void MotorPageViewTask(bool enable); //BatteryPageView的任务的状态 void BatteryPageViewTask(bool enable); //SportPageView的任务的状态 void SportPageViewTask(bool enable); //Aliplay界面任务状态 void AlipayPageViewTask(bool enable); //控制事件 void turnFanStatus(bool enable); void setMotorStatus(bool enable); void setBuzzerStatus(bool enable); void drainWaterStatus(bool enable); //HealthPageView的任务的状态 void HealthPageViewTask(bool enable); //无线连接任务 void WiFiLinkTask(bool enable); protected: ModelListener* modelListener; }; #endif // MODEL_HPP

ModelListener.hpp中的函数声明:

#ifndef MODELLISTENER_HPP #define MODELLISTENER_HPP #include <gui/model/Model.hpp> extern "C" { #include "stdint.h" } class ModelListener { public: ModelListener() : model(0) {} virtual ~ModelListener() {} void bind(Model* m) { model = m; } //更新日期和时间 virtual void updateDate(uint8_t Year, uint8_t Month, uint8_t Date, uint8_t WeekDay) {} virtual void updateTime(uint8_t Hours, uint8_t Minutes, uint8_t Seconds) {} //页面跳转 virtual void SettingPageChange(uint8_t newFiveKeyFunc){} virtual void DialPageChange(uint8_t newFiveKeyFunc){} virtual void AppPageChange(uint8_t newFiveKeyFunc){} virtual void SixAxisPageChange(uint8_t newFiveKeyFunc){} virtual void ChipPageChange(uint8_t newFiveKeyFunc){} virtual void MotorPageChange(uint8_t newFiveKeyFunc){} virtual void InfoPageChange(uint8_t newFiveKeyFunc){} virtual void HealthPageChange(uint8_t newFiveKeyFunc){} virtual void WiFiPageChange(uint8_t newFiveKeyFunc){} virtual void BatteryPageChange(uint8_t newFiveKeyFunc){} virtual void SportPageEnter(uint8_t newKeyFunc){} virtual void SportPageExit(uint8_t newFiveKeyFunc){} virtual void AlipayPageChange(uint8_t newFiveKeyFunc){} //温度/步数/心率上传 virtual void updateTempStepHeart(float newTem, unsigned long newStep, uint32_t newHeartRate){} //更新姿态信息参数 virtual void updateSixAxis(float pitchVal,float rollVal,float yawVal) {} //更新芯片内部参数 virtual void updateChipInfor(uint16_t ChipTempVal, uint16_t VrefVal, uint16_t VbatVal) {} //健康监测信息上传 virtual void updateHeartRateInfo(uint32_t newHeartRate, uint32_t newSPO2) {} //更新温湿度、光照度数据上传 virtual void updateInfo(float newHum, float newTem, uint16_t newALS) {} //获取WiFi模组的RSSI值 virtual void updateWiFiRSSI(uint8_t (&pWiFiInfo)[40], uint16_t newRSSI) {} virtual void updateWalkStep(unsigned long newStep){} //更新电压、电流 virtual void updateBatteryPageInfo(uint16_t CurrentVal, uint16_t VoltageVal) {} protected: Model* model; }; #endif // MODELLISTENER_HPP

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/72626.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信