本帖最后由 lugl4313820 于 2024-2-6 15:13 编辑
【硬件】】
1、ST NUCLEO-U5A5ZJ-Q开发板
2、OLED
【开发软件】
1、STM32CubeIDE
2、TouchGFX 4.23.1
【实现步骤】
1、移植OLED到开发板上,在我的帖子已经实现:【ST NUCLEO-U5A5ZJ-Q开发板测评】深度体验I2C驱动OLED屏
2、配置CRC
3、打开TIM7为touchgfx提供刷新心跳:
同时开启中断。
4、配置TouchGFX为单色、宽度为128个像素,高度为64个像素
配置好后生成代码。
5、生成工程后,打开toucgfx Desiger,放入一背景为白色,同时添加一个数字时钟,然后生成代码。
到此工程配置结事。
【代码添加】
1、打开TouchFGXHAL.cpp添加ssd1306的头文件以及#include <touchgfx/hal/OSWrappers.hpp>获取像素头文件
2、更新void TouchGFXHAL::flushFrameBuffer(const touchgfx::Rect& rect)代码如下:
/**
* This function is called whenever the framework has performed a partial draw.
*
* @param rect The area of the screen that has been drawn, expressed in absolute coordinates.
*
* [url=home.php?mod=space&uid=418085]@see[/url] flushFrameBuffer().
*/
void TouchGFXHAL::flushFrameBuffer(const touchgfx::Rect& rect)
{
// Calling parent implementation of flushFrameBuffer(const touchgfx::Rect& rect).
//
// To overwrite the generated implementation, omit call to parent function
// and implemented needed functionality here.
// Please note, HAL::flushFrameBuffer(const touchgfx::Rect& rect) must
// be called to notify the touchgfx framework that flush has been performed.
// To calculate he start adress of rect,
// use advanceFrameBufferToRect(uint8_t* fbPtr, const touchgfx::Rect& rect)
// defined in TouchGFXGeneratedHAL.cpp
TouchGFXGeneratedHAL::flushFrameBuffer(rect);
const unsigned char* bitmap = (const unsigned char*) getClientFrameBuffer();
ssd1306_Fill(Black);
ssd1306_DrawBitmap(0, 0, bitmap, 128, 64, White);
ssd1306_UpdateScreen();
}
代码的主要功能是先创建一个bitmap的缓冲区,把touchgfx的图像读进这个数组,然后把图片写入ssd1306。
2、添加同步信号:
extern "C"
void touchgfxSignalVSync(void)
{
/* VSync has occurred, increment TouchGFX engine vsync counter */
touchgfx::HAL::getInstance()->vSync();
/* VSync has occurred, signal TouchGFX engine */
touchgfx::OSWrappers::signalVSync();
}
4、在main.c中添加TIM7的中断回调函数,内容如下:
/* USER CODE BEGIN 4 */
extern void touchgfxSignalVSync(void);
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM7)
{
touchgfxSignalVSync();
}
}
/* USER CODE END 4 */
在回调函数中,我们检测到定时回调,然后更新一次图像。
5、在主函数中我们调用MX_TouchGFX_Process();就可以实现即定功能。
while (1)
{
/* USER CODE END WHILE */
MX_TouchGFX_Process();
/* USER CODE BEGIN 3 */
}
6、添加时钟更新代码,先在screen.hpp中,声明handleTicktEven函数,并声明tick,秒时分四个变量:
class screenView : public screenViewBase
{
public:
screenView();
virtual ~screenView() {}
virtual void setupScreen();
virtual void tearDownScreen();
virtual void handleTickEvent();
protected:
int tickCounter;
int digitalHours;
int digitalMinutes;
int digitalSeconds;
};
7、在screenview.cpp中我们实现handleTickEvernt函数,计数到达1秒后更新数字时钟,从面实现数据时钟:
#include <gui/screen_screen/screenView.hpp>
screenView::screenView():tickCounter(0),digitalSeconds(0),digitalMinutes(0),digitalHours(0)
{
}
void screenView::setupScreen()
{
screenViewBase::setupScreen();
}
void screenView::tearDownScreen()
{
screenViewBase::tearDownScreen();
}
void screenView::handleTickEvent()
{
tickCounter++;
if (tickCounter % 60 == 0)
{
if (++digitalSeconds >= 60)
{
digitalSeconds = 0;
if (++digitalMinutes >= 60)
{
digitalMinutes = 0;
if (++digitalHours >= 24)
{
digitalHours = 0;
}
}
}
// Update the clock
digitalClock.setTime24Hour(digitalHours, digitalMinutes, digitalSeconds);
}
}
这样我们编译下载到开发板就可以实现基于touchGFX的数字时钟了: