你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【STM32U599】4.引入RTC与MVP开发

[复制链接]
奇迹 发布时间:2023-12-28 21:10

前一篇完成了界面开发,这一篇我们把界面与单片机RTC硬件联合起来。

首先打开STM32CubeMX进行配置。 打开外部低频时钟。

微信截图_20231228204946.png

配置RTC模块

微信截图_20231228205021.png

修改时钟树

微信截图_20231228205032.png

点击生成代码,回到软件进行开发。 暂时我们只关注时间的读取,主要涉及两个函数

读取时间

HAL_StatusTypeDef HAL_RTC_GetTime(const RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format)

读取日期

HAL_StatusTypeDef HAL_RTC_GetDate(const RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format)

普通模式

首先我们先聊一下普通的界面开发模式,界面与逻辑控制混合到一起。 这种方式很简单,只要在界面里面动手脚就可以了

mainView.cpp

#include <gui/main_screen/mainView.hpp>

mainView::mainView()
{

}
#ifndef SIMULATOR
#include "main.h"
extern RTC_HandleTypeDef hrtc;
RTC_TimeTypeDef GetTime;
RTC_DateTypeDef GetData;
#endif
void mainView::setupScreen()
{
#ifndef SIMULATOR
    HAL_RTC_GetTime(&hrtc, &GetTime, RTC_FORMAT_BIN);
    HAL_RTC_GetDate(&hrtc, &GetData, RTC_FORMAT_BIN);
    analogHours = GetTime.Hours;
    analogMinutes = GetTime.Minutes;
    analogSeconds = GetTime.Seconds;
#endif
    mainViewBase::setupScreen();
}

void mainView::tearDownScreen()
{
    mainViewBase::tearDownScreen();
}

void mainView::handleTickEvent()
{
    tickCounter++;

    if (tickCounter % 60 == 0)
    {
        if (++analogSeconds >= 60)
        {
            analogSeconds = 0;
            if (++analogMinutes >= 60)
            {
                analogMinutes = 0;
                if (++analogHours >= 24)
                {
                    analogHours = 0;
                }
            }
        }

        // Update the clocks
        analogClock.setTime24Hour(analogHours, analogMinutes, analogSeconds);
    }
}

代码都很好懂,这里主要介绍一下SIMULATOR宏,主要用来限定代码的运行范围。 当我们只希望代码在模拟器运行的时候就

#ifdef SIMULATOR
  // 代码
#endif

不希望代码在模拟器运行的时候

#ifndef SIMULATOR
  // 代码
#endif

这个宏就可以实现加入用户控制硬件逻辑,但是又不影响原本的界面开发。 编译下载到板卡中,运行正常。试试vs仿真,也是正常运行。

MVP模式

接下来聊一下MVP开发。 MVP是TouchGFX建议的一种代码架构,全称是Model-View-Presenter,主要实现用户代码-UI界面-UI逻辑分离的一种开发模式。

下面进行代码编写

Model.hpp

#ifndef MODEL_HPP
#define MODEL_HPP

#include <stdint.h>

class ModelListener;

class Model
{
public:
    Model();

    void bind(ModelListener* listener)
    {
        modelListener = listener;
    }

    void tick();

    void getRTCTime(int *hours, int *minutes, int *seconds);
protected:
    ModelListener* modelListener;
};

#endif // MODEL_HPP

Model.cpp

#include <gui/model/Model.hpp>
#include <gui/model/ModelListener.hpp>

#ifndef SIMULATOR
#include "main.h"
extern "C"
{
    extern RTC_HandleTypeDef hrtc;
}
#endif
Model::Model() : modelListener(0)
{

}

void Model::tick()
{

}

void Model::getRTCTime(int *hours, int *minutes, int *seconds)
{
    *hours = 0;
    *minutes = 0;
    *seconds = 0;
#ifndef SIMULATOR
    RTC_TimeTypeDef GetTime;
    RTC_DateTypeDef GetData;
    HAL_RTC_GetTime(&hrtc, &GetTime, RTC_FORMAT_BIN);
    HAL_RTC_GetDate(&hrtc, &GetData, RTC_FORMAT_BIN);
    *hours = GetTime.Hours;
    *minutes = GetTime.Minutes;
    *seconds = GetTime.Seconds;
#endif
}

这一部分是Model内容,主要实现对接RTC部分(至于为啥没用日期却又读了日期呢?因为ST RTC一直有个bug,不这样读,RTC就装死给你看)。

mainPresenter.hpp

#ifndef MAINPRESENTER_HPP
#define MAINPRESENTER_HPP

#include <gui/model/ModelListener.hpp>
#include <mvp/Presenter.hpp>

using namespace touchgfx;

class mainView;

class mainPresenter : public touchgfx::Presenter, public ModelListener
{
public:
    mainPresenter(mainView& v);

    /**
     * The activate function is called automatically when this screen is "switched in"
     * (ie. made active). Initialization logic can be placed here.
     */
    virtual void activate();

    /**
     * The deactivate function is called automatically when this screen is "switched out"
     * (ie. made inactive). Teardown functionality can be placed here.
     */
    virtual void deactivate();

    virtual ~mainPresenter() {}

    void getTime(int *hours, int *minutes, int *seconds);

private:
    mainPresenter();

    mainView& view;
};

#endif // MAINPRESENTER_HPP

mainPresenter.cpp

#include <gui/main_screen/mainView.hpp>
#include <gui/main_screen/mainPresenter.hpp>

mainPresenter::mainPresenter(mainView& v)
    : view(v)
{

}

void mainPresenter::activate()
{

}

void mainPresenter::deactivate()
{

}

void mainPresenter::getTime(int *hours, int *minutes, int *seconds)
{
    model->getRTCTime(hours, minutes, seconds);
}

这一部分是Presenter内容,用于对接Model,为View提供接口。

mainView.cpp

#include <gui/main_screen/mainView.hpp>

mainView::mainView()
{

}

void mainView::setupScreen()
{
    presenter->getTime(&analogHours, &analogMinutes, &analogSeconds);
    mainViewBase::setupScreen();
}

void mainView::tearDownScreen()
{
    mainViewBase::tearDownScreen();
}

void mainView::handleTickEvent()
{
    tickCounter++;

    if (tickCounter % 60 == 0)
    {
        if (++analogSeconds >= 60)
        {
            analogSeconds = 0;
            if (++analogMinutes >= 60)
            {
                analogMinutes = 0;
                if (++analogHours >= 24)
                {
                    analogHours = 0;
                }
            }
        }

        // Update the clocks
        analogClock.setTime24Hour(analogHours, analogMinutes, analogSeconds);
    }
}

这一部分是View内容,调用Presenter里面的函数配置时钟时间。

编译下载到板卡中,运行正常。试试vs仿真,也是正常运行。

23ea6a559135e802286a37dddd33064.jpg

收藏 评论0 发布时间:2023-12-28 21:10

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版