配置请参考链接:TouchGFX超低配置移植教程-CSDN博客
裸机
一,显示配置
1.适当增加堆栈大小:
2.适当增大缓冲大小:
二,硬件配置
1.开启I2C1用于连接触摸芯片,(PB6,PB7):
2.开启SPI1(Transmit Only Master)用于LCD 串行数据传输,(PB3,PB5),开启DMA
开启SPI中断用于屏幕刷新完成时调用函数:
3.开启QSPI 4线模式用于读写W25Q64:
4.开启tim6 定时器为TouchGFX提供时钟源,开启中断:
5.不生成QSPI初始化函数:
三,C/C++ 基础示例
1.在cpp文件中的c函数外部函数声明:
extern "C" int touchgfxDisplayDriverTransmitActive();
2.在c文件中的cpp函数外部函数声明:
extern void touchgfxTickHandler(void);//也可以省略extern
3.使cpp文件中的函数兼容c文件使用:
extern "C"
void DisplayDriver_TransferCompleteCallback()
{
PartialFrameBufferManager::tryTransmitBlockFromIRQ();
}
在其它C文件中使用在 TouchGFXGeneratedHAL.cpp 中定义的DisplayDriver_TransferCompleteCallback 函数,你需要确保以下几点:声明函数原型:在需要使用该函数的 C 文件中声明该函数的原型。 确保链接:确保在编译和链接时包含 TouchGFXGeneratedHAL.cpp 文件,以便链接器能够找到该函数的定义。
由于DisplayDriver_TransferCompleteCallback 函数被声明为 extern "C",它具有 C 链接约定,因此可以在 C 文件中直接使用。在需要使用 DisplayDriver_TransferCompleteCallback 函数的 C 文件中声明该函数的原型。你可以通过创建一个头文件来包含这个声明,或者直接在 C 文件中声明。
4.extern外部声明:
无论是函数还是全局变量,在一个文件中定义了,在另一个文件中如果要使用只需要extern外部声明一下就行了,其中函数可以省略extern,在.h文件中声明只是为了方便管理而已。
四,显示移植
1.st7789
点击TouchGFXGeneratedHAL.cpp,其位于Application/User/TouchGFX/target/generated一栏中,在该点cpp文件的开头就可以看到四个函数声明,前三个都是需要用户自己提供。
//st7789.c
volatile uint8_t IsTransmittingBlock_=0;
/**
* Check if a Frame Buffer Block is beeing transmitted.
* TouchGFX获取当前屏幕刷新状态的函数,返回值1表示屏幕正在刷新,返回值0标志屏幕已刷新完成。
*/
int touchgfxDisplayDriverTransmitActive(void)
{
return IsTransmittingBlock_;
}
/**
* Check if a Frame Buffer Block ending at bottom may be sent.
* TouchGFX获取当前屏幕刷新状态的函数,返回值1表示屏幕正在刷新,返回值0标志屏幕已刷新完成。
*/
int touchgfxDisplayDriverShouldTransferBlock(uint16_t bottom)
{
return 1;
}
/**
* Transmit a Frame Buffer Block.
* 屏幕刷新的接口函数,用户需要在此函数中调用自己屏幕的刷屏函数。
*/
void touchgfxDisplayDriverTransmitBlock(const uint8_t* pixels, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
{
IsTransmittingBlock_=1;
ST7789_DrawImage(x,y,w,h,(uint16_t*)pixels);
}
2.spi_it
除了上述三个函数,还需要注意一个函数DisplayDriver_TransferCompleteCallback,用户需要在屏幕刷新完成时调用该函数。
//spi.c
extern volatile uint8_t IsTransmittingBlock_;
extern void DisplayDriver_TransferCompleteCallback(void);
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{
if (hspi->Instance == SPI1) {
IsTransmittingBlock_ = 0;
DisplayDriver_TransferCompleteCallback();
}
}
3.time_it
TouchGFX正常工作的前提条件是需要一个外部的时钟源,由于本例程使用的屏为SPI屏,STM32CubeMX中配置的时钟源选项默认为Custom,即需要用户自己为TouchGFX提供时钟源
//tim.c
extern void touchgfxTickHandler(void);
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
static int counter=0;
if (htim->Instance == TIM6)
{
touchgfxTickHandler();
if(++counter%200==0)
HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
}
}
4.TouchGFXHAL
#include <touchgfx/hal/OSWrappers.hpp>
#include "norflash.h"
#include <touchgfx/hal/PartialFrameBufferManager.hpp>
#include <touchgfx/bitmap.hpp>
using namespace touchgfx;
extern "C" {
uint8_t isInited = 0;
}
extern uint8_t isInited;
isInited = 1;
//TouchGFXHAL.cpp
extern "C"
void touchgfxTickHandler()
{
static uint8_t ms = 0;
static uint8_t isHigh = 0;
if(isInited)
{
ms++;
if(ms==20)
{
ms = 0;
isHigh = !isHigh;
if(isHigh)
{
OSWrappers::signalVSync();
}else
{
HAL::getInstance()->frontPorchEntered();
}
}
}
}
五,触控移植
#include "ns2009.h"
unsigned int pos[2]={0};
bsp_ns2009_getPos(pos);
if(pos[0]||pos[1])
{
x=pos[0];
y=pos[1];
pos[0]=0;
pos[1]=0;
return true;
}
else
return false;
六,MDK初始化
1.不勾选MicroLIB,不对printff重定向。确保MX_QUADSPI_Init,屏幕初始化,触摸芯片初始化等中不使用printf()。
2.main.c初始化。
#include "quadspi.h"
七,分散加载
1.编译。
*.o (ExtFlashSection)
2.先单独下载内部flash(不要勾选复位)。
3.后下载外部flash。
注:编译与下载算法无关,可以只用内部flash算法调试。
八,修改显示方向
注:方向不正确会出现控件花屏。
RTOS
FMC和SPI显示接口 | TouchGFX Documentation
实时操作系统 | TouchGFX Documentation
一,RTOSV1
1.FreeRTOS配置
2.仍使用tim6为TGFX时钟源
static int counter=0;
if (htim->Instance == TIM6)
{
touchgfxTickHandler();
if(++counter%200==0)
toggle_led();
}