Description
Corrupted display stm32h743 when trying to optimize performance
What MCU/Processor/Board and compiler are you using?
nucleo h743zi2
arduino ide
lcd 3.97inch 800x480 nt35510
What LVGL version are you using?
8.1.0
What do you want to achieve?
Error free display, optimized speed
What have you tried so far?
I’m working on piece of multifunctional test equipment, performance was sluggisch so i looked at the fps and cpu load, 33fps and close to 100% cpu load.
The touch screen routine seems to take about half of the load so i disabled that, when doing basically nothing cpu load was still up to 50%.
I eliminated as much as possible from my program including touch because that is taking a large portion of the cpu load in an attempt to find out why i have a high cpu load, code below is the core including display drivers,
Just a basic screen with one button and a number that counts up to get some action on the display.
I now get 0-1% cpu load which is great but the screen is distorted, the counter is not updated and next to it are random lines probably the counter updates. I get the same with the original code but with touch routines remarked out. So something in the touch screen routine makes it work.
I had this line in the touch driver:
lv_obj_invalidate(lv_scr_act());
If i add it to the loop, i dont get a corrupted screen but high cpu load, 50-60% instead of 0-1.
Second screen shows the project with the invalidate line remmed out, touch enabled, the voltage reading is not updated and a flickering block of lines are next to it.
Why would the invalidate call “make it work”?
I hate to use it because it increases the cpu load.
Code to reproduce
Add a code snippet which can run in the simulator. It should contain only the relevant code that compiles without errors when separated from your main code base.
The code block(s) should be formatted like:
#include <SPI.h>
#include <lvgl.h>
#define TIMER_INTERRUPT_DEBUG 0
#define _TIMERINTERRUPT_LOGLEVEL_ 0
#include "STM32TimerInterrupt.h"
#include "STM32_ISR_Timer.h"
#define TIMER_INTERVAL_MS 5
#define HW_TIMER_INTERVAL_MS 3
// LCD driver start
typedef int32_t s32;
typedef int16_t s16;
typedef int8_t s8;
typedef const int32_t sc32;
typedef const int16_t sc16;
typedef const int8_t sc8;
typedef __IO int32_t vs32;
typedef __IO int16_t vs16;
typedef __IO int8_t vs8;
typedef __I int32_t vsc32;
typedef __I int16_t vsc16;
typedef __I int8_t vsc8;
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;
typedef const uint32_t uc32;
typedef const uint16_t uc16;
typedef const uint8_t uc8;
typedef __IO uint32_t vu32;
typedef __IO uint16_t vu16;
typedef __IO uint8_t vu8;
typedef __I uint32_t vuc32;
typedef __I uint16_t vuc16;
typedef __I uint8_t vuc8;
#define ON 1
#define OFF 0
static u32 fac_us = 0;
typedef struct
{
u16 width;
u16 height;
u16 id;
u8 dir;
u16 wramcmd;
u16 rramcmd;
u16 setxcmd;
u16 setycmd;
} _lcd_dev;
//#define USE_HORIZONTAL 1
#define LCD_H 480
#define LCD_W 800
#define LCD_REGION_NUMBER MPU_REGION_NUMBER0
#define LCD_ADDRESS_START (0X60000000)
#define LCD_REGION_SIZE MPU_REGION_SIZE_256MB
#define LCD_RST 8 // PB8
#define LCD_RST_SET() HAL_GPIO_WritePin(GPIOB,1<<LCD_RST ,GPIO_PIN_SET)//GPIO_TYPE->BSRRL=1<<LCD_LED
#define LCD_RST_CLR() HAL_GPIO_WritePin(GPIOB,1<<LCD_RST,GPIO_PIN_RESET)
typedef struct
{
vu16 LCD_REG;
vu16 LCD_RAM;
} LCD_TypeDef;
#define LCD_BASE ((u32)(0x60000000 | 0x0007FFFE))
#define LCD ((LCD_TypeDef *) LCD_BASE)
SRAM_HandleTypeDef SRAM_Handler;
_lcd_dev lcddev;
u16 POINT_COLOR = 0x0000, BACK_COLOR = 0xFFFF;
u16 DeviceCode;
// LCD driver end
TIM_HandleTypeDef htim2;
static uint32_t HAL_RCC_ADC12_CLK_ENABLED = 0;
#define LVGL_TICK_PERIOD 2
// general
unsigned long loop_timer;
unsigned long test_timer;
lv_obj_t *lbl_mv_value;
byte testcount = 0;
// Init STM32 timer TIM1
STM32Timer ITimer(TIM1);
// Init STM32_ISR_Timer
// Each STM32_ISR_Timer can service 16 different ISR-based timers
STM32_ISR_Timer ISR_Timer;
void TimerHandler()
{
ISR_Timer.run();
}
void handle_timer_int()
{
lv_tick_inc(LVGL_TICK_PERIOD);
}
void my_disp_flush(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * color_p)
{
uint32_t w = (area->x2 - area->x1);
uint32_t h = (area->y2 - area->y1);
LCD_SetWindows(area->x1, area->y1, w, h);
int32_t x;
int32_t y;
for (y = area->y1; y <= area->y2; y++) {
for (x = area->x1; x <= area->x2; x++) {
LCD->LCD_RAM = color_p->full;
// Lcd_WriteData_16Bit(color_p->full);
color_p++;
}
}
lv_disp_flush_ready(disp);
}
void my_touchpad_read(lv_indev_drv_t * indev, lv_indev_data_t * data)
{
}
static lv_obj_t *tabview;
void setup() {
// setup LCD start
SCB_EnableICache();
SCB_DisableDCache();
HAL_Init();
Stm32_Clock_Init(120, 1, 2, 2);
delay_init(400);
LCD_Init();
// setup LCD end
MX_DMA_Init();
MX_TIM2_Init();
SPI.setMOSI(PB5);
SPI.setMISO(PA6);
SPI.setSCLK(PA5);
SPI.begin();
SPI.setClockDivider(128);
lv_init();
static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf1[800 * 480 / 10]; /*Declare a buffer for 1/10 screen size*/
lv_disp_draw_buf_init(&draw_buf, buf1, NULL, (800 * 480 / 10)); /*Initialize the display buffer.*/
static lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
disp_drv.flush_cb = my_disp_flush; /*Set your driver function*/
disp_drv.draw_buf = &draw_buf; /*Assign the buffer to the display*/
disp_drv.hor_res = 800; /*Set the horizontal resolution of the display*/
disp_drv.ver_res = 480; /*Set the verizontal resolution of the display*/
lv_disp_drv_register(&disp_drv); /*Finally register the driver*/
static lv_indev_drv_t indev_drv; /*Descriptor of a input device driver*/
lv_indev_drv_init(&indev_drv); /*Basic initialization*/
indev_drv.type = LV_INDEV_TYPE_POINTER; /*Touch pad is a pointer-like device*/
indev_drv.read_cb = my_touchpad_read; /*Set your driver function*/
lv_indev_drv_register(&indev_drv); /*Finally register the driver*/
// Interval in microsecs
ITimer.attachInterruptInterval(HW_TIMER_INTERVAL_MS * 1000, TimerHandler);
// interval msec
ISR_Timer.setInterval(3, handle_timer_int);
setupscreens();
HAL_TIM_Base_Start(&htim2);
__HAL_RCC_D2SRAM1_CLK_ENABLE();
__HAL_RCC_D2SRAM2_CLK_ENABLE();
__HAL_RCC_D2SRAM3_CLK_ENABLE();
loop_timer = millis();
test_timer = millis();
lv_label_set_text(lbl_mv_value, "9");
}
void loop() {
if (millis() - test_timer > 30) {
switch (testcount) {
case 0:
lv_label_set_text(lbl_mv_value, "0");
break;
case 1:
lv_label_set_text(lbl_mv_value, "1");
break;
case 2:
lv_label_set_text(lbl_mv_value, "2");
break;
case 3:
lv_label_set_text(lbl_mv_value, "3");
break;
}
testcount++;
if (testcount > 3) {
testcount = 0;
}
// lv_obj_invalidate(lv_scr_act());
test_timer = millis();
}
if (millis() - loop_timer >= 5) {
lv_task_handler(); /* let the GUI do its work */
loop_timer = millis();
}
}
void setupscreens(void) {
lv_obj_t * label;
// tabs
tabview = lv_tabview_create(lv_scr_act(), LV_DIR_TOP, 0);
lv_obj_t *tabmain = lv_tabview_add_tab(tabview, "");
lv_obj_set_style_bg_color (tabmain, lv_color_white(), LV_PART_MAIN | LV_STATE_DEFAULT );
lv_obj_set_style_bg_opa( tabmain, LV_OPA_COVER , LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_clear_flag(tabview, LV_OBJ_FLAG_SCROLLABLE);
static lv_style_t style12;
lv_style_set_text_color(&style12, lv_color_white());
lv_style_set_text_font(&style12, &lv_font_montserrat_28);
// main screen
lbl_mv_value = lv_label_create(tabmain);
lv_obj_align(lbl_mv_value, LV_ALIGN_TOP_LEFT, 200, 200);
lv_obj_t * btn1 = lv_btn_create(tabmain);
// lv_obj_add_event_cb(btn1, event_sigtracerscr, LV_EVENT_ALL, NULL);
lv_obj_align(btn1, LV_ALIGN_TOP_LEFT, 10, 0);
label = lv_label_create(btn1);
lv_label_set_text(label, "Button 1");
lv_obj_add_style(label, &style12, 0);
lv_obj_center(label);
lv_obj_set_width(btn1, 200);
lv_obj_set_height(btn1, 110);
}
// LCD routines start
void Stm32_Clock_Init(u32 plln, u32 pllm, u32 pllp, u32 pllq)
{
HAL_StatusTypeDef ret = HAL_OK;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
MODIFY_REG(PWR->CR3, PWR_CR3_SCUEN, 0);
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
while ((PWR->D3CR & (PWR_D3CR_VOSRDY)) != PWR_D3CR_VOSRDY) {}
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
RCC_OscInitStruct.CSIState = RCC_CSI_OFF;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLN = plln;
RCC_OscInitStruct.PLL.PLLM = pllm;
RCC_OscInitStruct.PLL.PLLP = pllp;
RCC_OscInitStruct.PLL.PLLQ = pllq;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;
ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | \
RCC_CLOCKTYPE_HCLK | \
RCC_CLOCKTYPE_D1PCLK1 | \
RCC_CLOCKTYPE_PCLK1 | \
RCC_CLOCKTYPE_PCLK2 | \
RCC_CLOCKTYPE_D3PCLK1);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV4;
ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
if (ret != HAL_OK) while (1);
__HAL_RCC_CSI_ENABLE() ;
__HAL_RCC_SYSCFG_CLK_ENABLE() ;
HAL_EnableCompensationCell();
// test voor adc
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADC;
PeriphClkInitStruct.PLL2.PLL2M = 1;
PeriphClkInitStruct.PLL2.PLL2N = 18;
PeriphClkInitStruct.PLL2.PLL2P = 2;
PeriphClkInitStruct.PLL2.PLL2Q = 2;
PeriphClkInitStruct.PLL2.PLL2R = 2;
PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_3;
PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOMEDIUM;
PeriphClkInitStruct.PLL2.PLL2FRACN = 6144;
PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLL2;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
}
void delay_init(u16 SYSCLK)
{
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
fac_us = SYSCLK;
}
void delay_us(u32 nus)
{
u32 ticks;
u32 told, tnow, tcnt = 0;
u32 reload = SysTick->LOAD;
ticks = nus * fac_us;
told = SysTick->VAL;
while (1)
{
tnow = SysTick->VAL;
if (tnow != told)
{
if (tnow < told)tcnt += told - tnow;
else tcnt += reload - tnow + told;
told = tnow;
if (tcnt >= ticks)break;
}
};
}
void delay_ms(u16 nms)
{
u32 i;
for (i = 0; i < nms; i++) delay_us(1000);
}
u16 LCD_read(void)
{
vu16 data;
data = LCD->LCD_RAM;
return data;
}
/*****************************************************************************
@name :void LCD_WR_REG(u16 data)
@function :Write an 16-bit command to the LCD screen
@parameters :data:Command value to be written
@retvalue :None
******************************************************************************/
void LCD_WR_REG(vu16 data)
{
data = data;
LCD->LCD_REG = data;
}
/*****************************************************************************
@name :void LCD_WR_DATA(u16 data)
@function :Write an 16-bit data to the LCD screen
@parameters :data:data value to be written
@retvalue :None
******************************************************************************/
void LCD_WR_DATA(vu16 data)
{
data = data;
LCD->LCD_RAM = data;
}
/*****************************************************************************
@name :u16 LCD_RD_DATA(void)
@function :Read an 16-bit value from the LCD screen
@parameters :None
@retvalue :read value
******************************************************************************/
u16 LCD_RD_DATA(void)
{
return LCD_read();
}
/*****************************************************************************
@name :void LCD_WriteReg(u16 LCD_Reg, u16 LCD_RegValue)
@function :Write data into registers
@parameters :LCD_Reg:Register address
LCD_RegValue:Data to be written
@retvalue :None
******************************************************************************/
void LCD_WriteReg(u16 LCD_Reg, u16 LCD_RegValue)
{
LCD->LCD_REG = LCD_Reg;
LCD->LCD_RAM = LCD_RegValue;
}
/*****************************************************************************
@name :void LCD_ReadReg(u16 LCD_Reg,u16 *Rval,int n)
@function :read value from specially registers
@parameters :LCD_Reg:Register address
@retvalue :read value
******************************************************************************/
void LCD_ReadReg(u16 LCD_Reg, u16 * Rval, int n)
{
LCD_WR_REG(LCD_Reg);
while (n--)
{
*(Rval++) = LCD_RD_DATA();
delay_us(5);
}
}
/*****************************************************************************
@name :void LCD_WriteRAM_Prepare(void)
@function :Write GRAM
@parameters :None
@retvalue :None
******************************************************************************/
void LCD_WriteRAM_Prepare(void)
{
LCD_WR_REG(lcddev.wramcmd);
}
/*****************************************************************************
@name :void LCD_ReadRAM_Prepare(void)
@function :Read GRAM
@parameters :None
@retvalue :None
******************************************************************************/
void LCD_ReadRAM_Prepare(void)
{
LCD_WR_REG(lcddev.rramcmd);
}
/*****************************************************************************
@name :void Lcd_WriteData_16Bit(u16 Data)
@function :Write an 16-bit command to the LCD screen
@parameters :Data:Data to be written
@retvalue :None
******************************************************************************/
void Lcd_WriteData_16Bit(u16 Data)
{
LCD->LCD_RAM = Data;
}
u16 Color_To_565(u8 r, u8 g, u8 b)
{
return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3);
}
/*****************************************************************************
@name :u16 Lcd_ReadData_16Bit(void)
@function :Read an 16-bit value from the LCD screen
@parameters :None
@retvalue :read value
******************************************************************************/
u16 Lcd_ReadData_16Bit(void)
{
u16 r, g, b;
//dummy data
r = LCD_RD_DATA();
delay_us(1);
//16bit:red and green data
r = LCD_RD_DATA();
delay_us(1);
//16bit:blue data
g = LCD_RD_DATA();
b = g >> 8;
g = r & 0xFF;
r = r >> 8;
return Color_To_565(r, g, b);
}
/*****************************************************************************
@name :void LCD_Clear(u16 Color)
@function :Full screen filled LCD screen
@parameters :color:Filled color
@retvalue :None
******************************************************************************/
void LCD_Clear(u16 Color)
{
unsigned int i;
u32 total_point = lcddev.width * lcddev.height;
LCD_SetWindows(0, 0, lcddev.width - 1, lcddev.height - 1);
for (i = 0; i < total_point; i++)
{
LCD->LCD_RAM = Color;
}
}
/*****************************************************************************
@name :void LCD_MPU_Config(void)
@function :Configure the region of the MPU, and configure
the external SRAM area to be in write-through mode.
@parameters :None
@retvalue :None
******************************************************************************/
void LCD_MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_Initure;
HAL_MPU_Disable();
MPU_Initure.Enable = MPU_REGION_ENABLE;
MPU_Initure.Number = LCD_REGION_NUMBER;
MPU_Initure.BaseAddress = LCD_ADDRESS_START;
MPU_Initure.Size = LCD_REGION_SIZE;
MPU_Initure.SubRegionDisable = 0X00;
MPU_Initure.TypeExtField = MPU_TEX_LEVEL0;
MPU_Initure.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_Initure.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
MPU_Initure.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_Initure.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_Initure.IsBufferable = MPU_ACCESS_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_Initure);
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
/*****************************************************************************
@name :void HAL_SRAM_MspInit(SRAM_HandleTypeDef *hsram)
@function :SRAM underlying driver, clock enable, pin assignment
This function will be called by HAL_SRAM_Init ()
@parameters :hsram:SRAM handle
@retvalue :None
******************************************************************************/
void HAL_SRAM_MspInit(SRAM_HandleTypeDef * hsram)
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_FMC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
//PD0,1,4,5,7,8,9,10,13,14,15
GPIO_Initure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_7 | GPIO_PIN_8 | \
GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
GPIO_Initure.Mode = GPIO_MODE_AF_PP; //¸´ÓÃ
GPIO_Initure.Pull = GPIO_PULLUP; //ÉÏÀ
GPIO_Initure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; //¸ßËÙ
GPIO_Initure.Alternate = GPIO_AF12_FMC; //¸´ÓÃΪFMC
HAL_GPIO_Init(GPIOD, &GPIO_Initure);
//PE7,8,9,10,11,12,13,14,15
GPIO_Initure.Pin = GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | \
GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
HAL_GPIO_Init(GPIOE, &GPIO_Initure);
}
/*****************************************************************************
@name :void LCD_GPIOInit(void)
@date :2018-08-09
@function :Initialization LCD screen GPIO
@parameters :None
@retvalue :None
******************************************************************************/
void LCD_GPIOInit(FMC_NORSRAM_TimingTypeDef FWT)
{
GPIO_InitTypeDef GPIO_Initure;
FMC_NORSRAM_TimingTypeDef FSMC_ReadWriteTim;
// FMC_NORSRAM_TimingTypeDef FSMC_WriteTim;
__HAL_RCC_GPIOB_CLK_ENABLE(); //¿ªÆôGPIOBʱÖÓ
GPIO_Initure.Pin = GPIO_PIN_5 | GPIO_PIN_8; //PB5,±³¹â¿ØÖÆ PB8,¸´Î»
GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP; //ÍÆÍìÊä³ö
GPIO_Initure.Pull = GPIO_PULLUP; //ÉÏÀ
GPIO_Initure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; //¸ßËÙ
HAL_GPIO_Init(GPIOB, &GPIO_Initure);
LCD_MPU_Config();
SRAM_Handler.Instance = FMC_NORSRAM_DEVICE; //BANK1
SRAM_Handler.Extended = FMC_NORSRAM_EXTENDED_DEVICE;
SRAM_Handler.Init.NSBank = FMC_NORSRAM_BANK1; //ʹÓÃNE1
SRAM_Handler.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE; //²»¸´ ÓÃÊý¾ÝÏß
SRAM_Handler.Init.MemoryType = FMC_MEMORY_TYPE_SRAM; //SRAM
SRAM_Handler.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16; //16λÊý¾Ý¿í¶È
SRAM_Handler.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE; //ÊÇ·ñʹÄÜÍ»·¢·ÃÎÊ,½ö¶Ôͬ²½Í»·¢´æ´¢Æ÷ÓÐЧ,´Ë´¦Î´Óõ½
SRAM_Handler.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW; //µÈ´ýÐźŵļ«ÐÔ,½öÔÚÍ»·¢Ä£Ê½·ÃÎÊÏÂÓÐÓÃ
SRAM_Handler.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS; //´æ´¢Æ÷ÊÇÔڵȴýÖÜÆÚ֮ǰµÄÒ»¸öʱÖÓÖÜÆÚ»¹ÊǵȴýÖÜÆÚÆÚ¼äʹÄÜNWAIT
SRAM_Handler.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE; //´æ´¢Æ÷дʹÄÜ
SRAM_Handler.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE; //µÈ´ýʹÄÜλ,´Ë´¦Î´Óõ½
SRAM_Handler.Init.ExtendedMode = FMC_EXTENDED_MODE_ENABLE; //¶ÁдʹÓò»Í¬µÄʱÐò
SRAM_Handler.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE; //ÊÇ·ñʹÄÜͬ²½´«ÊäģʽϵĵȴýÐźÅ,´Ë´¦Î´Óõ½
SRAM_Handler.Init.WriteBurst = FMC_WRITE_BURST_DISABLE; //½ûֹͻ·¢Ð´
SRAM_Handler.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ASYNC;
//FSMC
FSMC_ReadWriteTim.AddressSetupTime = 0x11; //µØÖ·½¨Á¢Ê±¼ä(ADDSET)Ϊ17¸öHCLK 1/216M=4.6ns*17=78ns
FSMC_ReadWriteTim.AddressHoldTime = 0x00;
FSMC_ReadWriteTim.DataSetupTime = 0x55; //Êý¾Ý±£´æʱ¼ä(DATAST)Ϊ85¸öHCLK =4.6*85=391ns
FSMC_ReadWriteTim.AccessMode = FMC_ACCESS_MODE_A; //ģʽA
//FSMC
FWT.AddressSetupTime = 0x15;
FWT.AddressHoldTime = 0x00;
FWT.DataSetupTime = 0x15;
FWT.AccessMode = FMC_ACCESS_MODE_A; //ģʽA
HAL_SRAM_Init(&SRAM_Handler, &FSMC_ReadWriteTim, &FWT);
}
void LCD_FSMC_Write_Time_Set(FMC_NORSRAM_TimingTypeDef FWT, uint32_t AST, uint32_t DST)
{
// FMC_NORSRAM_TimingTypeDef FSMC_WriteTim;
FWT.AddressSetupTime = AST;
FWT.DataSetupTime = DST;
FMC_NORSRAM_Extended_Timing_Init(SRAM_Handler.Extended, &FWT, SRAM_Handler.Init.NSBank, SRAM_Handler.Init.ExtendedMode);
}
/*****************************************************************************
@name :void LCD_RESET(void)
@function :Reset LCD screen
@parameters :None
@retvalue :None
******************************************************************************/
void LCD_RESET(void)
{
LCD_RST_CLR();
delay_ms(100);
LCD_RST_SET();
delay_ms(50);
}