基于STM32F746使用FreeRTOS移植TouchGFX,学习图形界面开发,通过STM32CubeMX直接配置FreeRTOS和TouchGFX,利用TouchGFX Designer设计界面。
硬件平台:STM32F746 Discovery Kit
开发环境:MDK V5.28
工程配置:STM32CubeMX V5.6
界面设计:TouchGFX 4.13
打开STM32CubeMX,通过芯片型号选择STM32F746NGHx,开始工程。
选择RCC
配置晶振:HSE选择BYPASS Clock Source
,LSE选择Crystal/Ceramic Resonator
,点击NVIC Settings
勾选RCC global interrupt
选择SYS
配置系统时间:Debug选择Serial Wire
,开启仿真,SWD接口;Timebase Source选择TIM6
用于给系统提供时间基准
选择FMC
并展开SDRAM 1
栏,Clock and chip enable选择SDCKE0 + SDNE0
,Internal bank number选择4 banks
,Address选择12 bits
,Data选择16 bits
,Byte enable选择16-bit byte enable
点击SDRAM 1
项配置SDRAM的相关参数,点击NVIC Settings
勾选FMC global interrupt
,点击GPIO Setttings
确定接口与实际电路一致
选择DMA2D
勾选Mode栏下的Actived
,点击Parameter Settings
选择适合自己的Color Mode,点击NVIC Settings
勾选DMA2D global interrupt
选择LTDC
并下拉Display Type选择与硬件对应的屏幕类型,此处选择RGB888(24 bits)
,点击Parameter Settings
设置对应参数
设置Layer Settings
对应参数
点击NVIC Settings
勾选LTDC global interrupt
,点击GPIO Settings
确定接口是否与实际电路一致
点击顶栏Clock Configuration
下方的Additional Software
准备开启TouchGFX,要提前下载好TouchGFX包
第2步确定后选择左侧栏新增加的Additional Software
并点击TouchGFX.4.13.0勾选Graphics Application
,配置TouchGFX的参数
LCD需要增加三个GPIO,PI12控制显示使能,低电平进入Sleep模式,高电平进入正常模式;PK3控制背光,低电平关闭背光,高电平打开背光;PI1控制LD1。GPIO output level选择High
,GPIO mode选择Output Push Pull
,默认拉高。
点击界面上方Clock Configuration
配置系统时钟
点击界面上方Project Manager
设置工程名称和路径,以及IDE的类型,点击右上角GENERATE CODE
生成工程代码
打开工程根目录下的/Src/ApplicationTemplate.touchgfx.part
文件开始制作界面,编辑完成后点击右上角的Generate Code
按钮生成代码,此时.part
文件同目录下会生成.touchgfx
文件,以后可以直接打开该文件进行界面设计
/* USER CODE BEGIN PD */
#define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001)
#define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002)
#define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0004)
#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008)
#define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020)
#define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030)
#define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200)
/* USER CODE END PD */
SDRAM初始化代码
static void MX_SDRAM_Init(void)
{
__IO uint32_t tmpmrd = 0;
FMC_SDRAM_CommandTypeDef Command;
/* Step 1: Config clock */
Command.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command.AutoRefreshNumber = 1;
Command.ModeRegisterDefinition = 0;
HAL_SDRAM_SendCommand(&hsdram1, &Command, 0xFFFF);
/* Step 2: Insert Delay */
HAL_Delay(1);
/* Step 3: Config pall */
Command.CommandMode = FMC_SDRAM_CMD_PALL;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command.AutoRefreshNumber = 1;
Command.ModeRegisterDefinition = 0;
HAL_SDRAM_SendCommand(&hsdram1, &Command, 0xFFFF);
/* Step 3: Config auto refresh */
Command.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command.AutoRefreshNumber = 8;
Command.ModeRegisterDefinition = 0;
HAL_SDRAM_SendCommand(&hsdram1, &Command, 0xFFFF);
/* Step 4: Config memory mode */
tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 | //设置突发长度:1(可以是1/2/4/8)
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL | //设置突发类型:连续(可以是连续/交错)
SDRAM_MODEREG_CAS_LATENCY_3 | //设置CAS值:3(可以是2/3)
SDRAM_MODEREG_OPERATING_MODE_STANDARD | //设置操作模式:0,标准模式
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE; //设置突发写模式:1,单点访问
Command.CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command.AutoRefreshNumber = 1;
Command.ModeRegisterDefinition = tmpmrd;
HAL_SDRAM_SendCommand(&hsdram1, &Command, 0xFFFF);
/* Step 5: Set refresh rate */
HAL_SDRAM_ProgramRefreshRate(&hsdram1, 1800);
}
void StartDefaultTask(void const * argument)
{
/* USER CODE BEGIN 5 */
MX_TouchGFX_Process();
/* Infinite loop */
for(;;)
{
osDelay(1);
}
/* USER CODE END 5 */
}
/* USER CODE BEGIN PV */
osThreadId userTaskHandle;
/* USER CODE END PV */
void StartUserTask(void const *argument);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
osThreadDef(userTask, StartUserTask, osPriorityNormal, 0, 128);
userTaskHandle = osThreadCreate(osThread(userTask), NULL);
/* USER CODE END RTOS_THREADS */
void StartUserTask(void const *argument)
{
for(;;)
{
HAL_GPIO_WritePin(LD1_GPIO_Port, LD1_Pin, GPIO_PIN_SET);
osDelay(500);
HAL_GPIO_WritePin(LD1_GPIO_Port, LD1_Pin, GPIO_PIN_RESET);
osDelay(500);
}
}
工程中配置的代码要卸载BEGIN END
两行之间,避免重新生成代码后被清除。