prettyprint

2024年8月16日 星期五

STM32 HAL|| 16 bit parallel LCD-TFT driver using FSMC interface for LVGL || DMA

 本文章介紹如何移植LVGL graphic library 到STM32上,另外說明有關LCD-TFT的driver使用STM32F4xx 的FSMC介面,STM32透過FSMC external memory access的方式驅動LCD-TFT。

一、使用硬體:

  • LCD-TFT


  • 開發版STM32_F4VE

二、STM32F4xx Bus matrix:


CPU or DMA透過Bus Matrix可直接存取FSMC。

三、STM407xx memory map:

使用FSMC bank1 其範圍為0x6000 0000~0x6fff ffff。

四、 FSMC write waveform and LCD-TFT write cycle sequence 的時序圖。
LCD-TFT D/CX:  Low時為command, High 實為GRAM data or commana的parameter data。相對於FSMC_A[25:0]的某一個address pin。

五、LCD-TFT Command&DATA address

本文章專案的FSMC設定如下圖:

LCD register select使用A18, 16 bits Data。因此A18為low時Address 為0x6000 0000代表command(D/CX low),。當A18為high 時Address 為0x6008 0000代表Data。
A[18]=HADDR[19]

六、移植LVGL library到STM32上:

  1. copy lvgl中的scr資料夾與lvgl.h和lv_conf.h(由lv_conf_template.h更改檔名)檔案到專案中,並將檔案加到include paths中。
  2. 設定定期呼叫lv_tick_inc(x)的timer,本專案設定為5ms。

  3. 在main loop:定期呼叫lv_timer_handler()。
  4. 呼叫lv_init()並設定display與input device的driver。
詳細程式碼附於文末。

七、成果展示:


八、程式碼:
  • lcd_fsmc.c
#include <lcd_fsmc.h>
#include <stdlib.h>
#include <stdio.h>

static uint8_t LCD_Orientation=0;
static uint16_t lcd_width = LCD_WIDTH; //default 240
static uint16_t lcd_height = LCD_HEIGHT; //default 320

// MADCTL register: 			MY,MX,MV,ML,BGR,MH,x,x
static uint8_t LCD_MADCTL_PORTRAIT  		=	0b01001000;
static uint8_t LCD_MADCTL_LANDSCAPE  		=	0b00101000;
static uint8_t LCD_MADCTL_PORTRAIT_MIRROR  =	0b10001000;
static uint8_t LCD_MADCTL_LANDSCAPE_MIRROR = 	0b11101000;

void lcd_cmd_write(unsigned char command)
{
	LCD_CMD_WRITE(command);
}

void lcd_data_write(unsigned short data)
{
	LCD_DATA_WRITE(data);
}

uint16_t lcd_get_width() {
	return lcd_width;
}

uint16_t lcd_get_height() {
	return lcd_height;
}

static void lcd_reset(void)
{
	lcd_cmd_write(LCD_SOFTRESET);
	HAL_Delay(50);
}

void lcd_set_window(unsigned short x0, unsigned short y0, unsigned short x1, unsigned short y1)
{
  lcd_cmd_write(LCD_COLADDRSET);
  lcd_data_write((x0 >> 8) & 0xFF);
  lcd_data_write(x0 & 0xFF);
  lcd_data_write((x1 >> 8) & 0xFF);
  lcd_data_write(x1 & 0xFF);
  lcd_cmd_write(LCD_PAGEADDRSET);
  lcd_data_write((y0 >> 8) & 0xFF);
  lcd_data_write(y0 & 0xFF);
  lcd_data_write((y1 >> 8) & 0xFF);
  lcd_data_write(y1 & 0xFF);
  lcd_cmd_write(LCD_MEMORYWRITE);
}

void lcd_init(void)
{
  lcd_reset();

  lcd_cmd_write(LCD_DISPLAYOFF);

  lcd_cmd_write(0xCF);
  lcd_data_write(0x00);
  lcd_data_write(0x83);
  lcd_data_write(0x30);

  lcd_cmd_write(0xED);
  lcd_data_write(0x64);
  lcd_data_write(0x03);
  lcd_data_write(0x12);
  lcd_data_write(0x81);

  lcd_cmd_write(0xE8);
  lcd_data_write(0x85);
  lcd_data_write(0x01);
  lcd_data_write(0x79);

  lcd_cmd_write(0xCB);
  lcd_data_write(0x39);
  lcd_data_write(0x2C);
  lcd_data_write(0x00);
  lcd_data_write(0x34);
  lcd_data_write(0x02);

  lcd_cmd_write(0xF7);
  lcd_data_write(0x20);

  lcd_cmd_write(0xEA);
  lcd_data_write(0x00);
  lcd_data_write(0x00);

  lcd_cmd_write(LCD_POWERCONTROL1);
  lcd_data_write(0x26);

  lcd_cmd_write(LCD_POWERCONTROL2);
  lcd_data_write(0x11);

  lcd_cmd_write(LCD_VCOMCONTROL1);
  lcd_data_write(0x35);
  lcd_data_write(0x3E);

  lcd_cmd_write(LCD_VCOMCONTROL2);
  lcd_data_write(0xBE);

  lcd_cmd_write(LCD_MEMCONTROL);
  lcd_data_write(LCD_MADCTL_PORTRAIT);
  LCD_Orientation = LCD_ORIENTATION_PORTRAIT; // set TFT orientation default

  lcd_cmd_write(LCD_PIXELFORMAT);
  lcd_data_write(0x55);

  lcd_cmd_write(LCD_FRAMECONTROLNORMAL);
  lcd_data_write(0x00);
  lcd_data_write(0x1B);

  lcd_cmd_write(0xF2);
  lcd_data_write(0x08);

  lcd_cmd_write(LCD_GAMMASET);
  lcd_data_write(0x01);

  lcd_cmd_write(LCD_POSITIVEGAMMCORR);
  lcd_data_write(0x1F);
  lcd_data_write(0x1A);
  lcd_data_write(0x18);
  lcd_data_write(0x0A);
  lcd_data_write(0x0F);
  lcd_data_write(0x06);
  lcd_data_write(0x45);
  lcd_data_write(0x87);
  lcd_data_write(0x32);
  lcd_data_write(0x0A);
  lcd_data_write(0x07);
  lcd_data_write(0x02);
  lcd_data_write(0x07);
  lcd_data_write(0x05);
  lcd_data_write(0x00);

  lcd_cmd_write(LCD_NEGATIVEGAMMCORR);
  lcd_data_write(0x00);
  lcd_data_write(0x25);
  lcd_data_write(0x27);
  lcd_data_write(0x05);
  lcd_data_write(0x10);
  lcd_data_write(0x09);
  lcd_data_write(0x3A);
  lcd_data_write(0x78);
  lcd_data_write(0x4D);
  lcd_data_write(0x05);
  lcd_data_write(0x18);
  lcd_data_write(0x0D);
  lcd_data_write(0x38);
  lcd_data_write(0x3A);
  lcd_data_write(0x1F);

  lcd_cmd_write(LCD_COLADDRSET);
  lcd_data_write(0x00);
  lcd_data_write(0x00);
  lcd_data_write(0x00);
  lcd_data_write(0xEF);

  lcd_cmd_write(LCD_PAGEADDRSET);
  lcd_data_write(0x00);
  lcd_data_write(0x00);
  lcd_data_write(0x01);
  lcd_data_write(0x3F);

  lcd_cmd_write(LCD_ENTRYMODE);
  lcd_data_write(0x07);

  lcd_cmd_write(LCD_DISPLAYFUNC);
  lcd_data_write(0x0A);
  lcd_data_write(0x82);
  lcd_data_write(0x27);
  lcd_data_write(0x00);

  lcd_cmd_write(LCD_SLEEPOUT);
  HAL_Delay(100);
  lcd_cmd_write(LCD_DISPLAYON);
  HAL_Delay(100);
  lcd_cmd_write(LCD_MEMORYWRITE);
}

void lcd_set_orientation(uint8_t Orientation)
{
	LCD_Orientation = Orientation;
	lcd_cmd_write(LCD_MEMCONTROL);

	switch (LCD_Orientation)
	{
		case LCD_ORIENTATION_PORTRAIT:
			lcd_data_write(LCD_MADCTL_PORTRAIT);
			lcd_width = LCD_WIDTH;
			lcd_height = LCD_HEIGHT;
			break;
		case LCD_ORIENTATION_PORTRAIT_MIRROR:
			lcd_data_write(LCD_MADCTL_PORTRAIT_MIRROR);
			lcd_width = LCD_WIDTH;
			lcd_height = LCD_HEIGHT;
			break;
		case LCD_ORIENTATION_LANDSCAPE:
			lcd_data_write(LCD_MADCTL_LANDSCAPE);
			lcd_width = LCD_HEIGHT;
			lcd_height = LCD_WIDTH;
			break;
		case LCD_ORIENTATION_LANDSCAPE_MIRROR:
			lcd_data_write(LCD_MADCTL_LANDSCAPE_MIRROR);
			lcd_width = LCD_HEIGHT;
			lcd_height = LCD_WIDTH;
			break;
		default:
			break;
	}

	lcd_cmd_write(LCD_MEMORYWRITE);
	lcd_set_window(0, 0, lcd_width - 1, lcd_height - 1);
}

void lcd_backlight_off(void)
{
	LCD_BL_OFF();
}

void lcd_backlight_on(void)
{
	LCD_BL_ON();
}

void lcd_display_off(void)
{
	lcd_cmd_write(LCD_DISPLAYOFF);
	LCD_BL_OFF();
}

void lcd_display_on(void)
{
	lcd_cmd_write(LCD_DISPLAYON);
	LCD_BL_ON();
}

uint8_t lcd_get_orientation(void)
{
  return LCD_Orientation;
}


void lcd_fill_RGB(uint16_t color, uint16_t x, uint16_t y, uint16_t width, uint16_t height)
{
  lcd_set_window(x, y, x+width - 1, y+height - 1);
  int dimensions = width * height;
  while(dimensions--)
  {
    lcd_data_write(color);
  }
}

  
  • lcd_fsmc.h
#ifndef __LCD_FSMC_H_
#define __LCD_FSMC_H_

#include "main.h"
#include <stdbool.h>

#define LCD_WIDTH		240
#define LCD_HEIGHT 		320

#define LCD_BL_ON() HAL_GPIO_WritePin(LCD_BL_GPIO_Port, LCD_BL_Pin, GPIO_PIN_RESET)
#define LCD_BL_OFF() HAL_GPIO_WritePin(LCD_BL_GPIO_Port, LCD_BL_Pin, GPIO_PIN_SET)

#define LCD_CMD_BASE        		((uint32_t)0x60000000)
#define LCD_DATA_BASE        		((uint32_t)0x60080000)

#define LCD_CMD_WRITE(command)	*(volatile uint16_t *) (LCD_CMD_BASE) = (command)
#define LCD_DATA_WRITE(data)	*(volatile uint16_t *) (LCD_DATA_BASE) = (data)
#define	LCD_REGISTER_READ()		*(volatile uint16_t *) (LCD_CMD_BASE)
#define	LCD_DATA_READ()			*(volatile uint16_t *) (LCD_DATA_BASE)

enum
{
	LCD_ORIENTATION_PORTRAIT 			= 0,
	LCD_ORIENTATION_LANDSCAPE 			= 1,
	LCD_ORIENTATION_PORTRAIT_MIRROR 	= 2,
	LCD_ORIENTATION_LANDSCAPE_MIRROR 	= 3
};

// LCD registers
#define	LCD_NOP					0x00
#define LCD_SOFTRESET			0x01
#define LCD_READID				0x04
#define LCD_READSTATUS			0x09
#define LCD_READPOWERMODE		0x0A
#define LCD_READMADCTL			0x0B
#define LCD_READPIXELFORMAT		0x0C
#define LCD_READIMAGEFORMAT		0x0D
#define LCD_READSIGNALMODE		0x0E
#define LCD_READSELFDIAGNOSTIC	0x0F
#define LCD_SLEEPIN				0x10
#define LCD_SLEEPOUT			0x11
#define LCD_PARTIALMODE			0x12
#define LCD_NORMALDISP			0x13
#define LCD_INVERTOFF			0x20
#define LCD_INVERTON			0x21
#define LCD_GAMMASET			0x26
#define LCD_DISPLAYOFF			0x28
#define LCD_DISPLAYON			0x29
#define LCD_COLADDRSET			0x2A
#define LCD_PAGEADDRSET			0x2B
#define LCD_MEMORYWRITE			0x2C
#define LCD_COLORSET			0x2D
#define LCD_MEMORYREAD			0x2E
#define LCD_PARTIALAREA			0x30
#define LCD_VERTICALSCROLING	0x33
#define LCD_TEARINGEFFECTOFF	0x34
#define LCD_TEARINGEFFECTON		0x35
#define LCD_MEMCONTROL			0x36
#define LCD_VSCROLLSTARTADDRESS	0x37
#define LCD_IDLEMODEOFF			0x38
#define LCD_IDLEMODEON			0x39
#define LCD_PIXELFORMAT			0x3A
#define LCD_WRITEMEMCONTINUE	0x3C
#define LCD_READMEMCONTINUE		0x3E
#define LCD_SETSCANLINE			0x44
#define LCD_GETSCANLINE			0x45
#define LCD_WRITEBRIGHTNESS		0x51
#define LCD_READBRIGHTNESS		0x52
#define LCD_WRITECTRL			0x53
#define LCD_READCTRL			0x54
#define LCD_WRITECABC			0x55
#define LCD_READCABC			0x56
#define LCD_WRITECABCMIN		0x5E
#define LCD_READCABCMIN			0x5F
#define LCD_RGBSIGNALCONTROL	0xB0
#define LCD_FRAMECONTROLNORMAL	0xB1
#define LCD_FRAMECONTROLIDLE	0xB2
#define LCD_FRAMECONTROLPARTIAL	0xB3
#define LCD_INVERSIONCONTROL	0xB4
#define LCD_BLANKINGPORCHCONT	0xB5
#define LCD_DISPLAYFUNC			0xB6
#define LCD_ENTRYMODE			0xB7
#define LCD_BACKLIGHTCONTROL1	0xB8
#define LCD_BACKLIGHTCONTROL2	0xB9
#define LCD_BACKLIGHTCONTROL3	0xBA
#define LCD_BACKLIGHTCONTROL4	0xBB
#define LCD_BACKLIGHTCONTROL5	0xBC
#define LCD_BACKLIGHTCONTROL7	0xBE
#define LCD_BACKLIGHTCONTROL8	0xBF
#define LCD_POWERCONTROL1		0xC0
#define LCD_POWERCONTROL2		0xC1
#define LCD_VCOMCONTROL1		0xC5
#define LCD_VCOMCONTROL2		0xC7
#define LCD_NVMEMORYWRITE		0xD0
#define LCD_NVMEMORYKEY			0xD1
#define LCD_NVMEMORYSTATUSREAD	0xD2
#define LCD_READID4				0xD3
#define LCD_READID1				0xDA
#define LCD_READID2				0xDB
#define LCD_READID3				0xDC
#define LCD_POSITIVEGAMMCORR	0xE0
#define LCD_NEGATIVEGAMMCORR	0xE1
#define LCD_DIGITALGAMMCONTROL1	0xE2
#define LCD_DIGITALGAMMCONTROL2	0xE3
#define LCD_INTERFACECONTROL	0xF6
// LCD Registers

void lcd_init(void);
void lcd_fill_RGB(uint16_t color, uint16_t x, uint16_t y, uint16_t width, uint16_t height);
void lcd_set_orientation(uint8_t Orientation);
void lcd_set_window(unsigned short x0, unsigned short y0, unsigned short x1, unsigned short y1);
void lcd_display_off(void);
void lcd_display_on(void);
void lcd_data_write(unsigned short data);
void lcd_cmd_write(unsigned char command);
void lcd_backlight_on();
void lcd_backlight_off();

uint16_t lcd_get_width();
uint16_t lcd_get_height();
uint8_t lcd_get_orientation();



#endif /* __LCD_FSMC_H_ */

  
  • lcd_lvgl.c
#include <lcd_lvgl.h>

/* Memory-to-memory DMA Handler */
extern DMA_HandleTypeDef hdma_memtomem_dma2_stream0;

extern uint8_t test_with_dma;
void tft_lvgl_draw_bitmap(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t *bitmap)
{
	uint32_t total_pixels = (x2-x1+1) * (y2-y1+1);

	lcd_set_window(x1, y1, x2, y2);

	// use memory-to-memory DMA
	HAL_DMA_Start(&hdma_memtomem_dma2_stream0, (uint32_t)bitmap, (LCD_DATA_BASE), total_pixels);
	HAL_DMA_PollForTransfer(&hdma_memtomem_dma2_stream0, HAL_DMA_FULL_TRANSFER, 1000);

	// if not use DMA translation
	//	for (int i=0; i < total_pixels; i++) {
	//		lcd_data_write(*(bitmap+i));
	//	}

}

void tft_lvgl_disp_flush(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * color_p)
{
    tft_lvgl_draw_bitmap(
            (uint16_t)(area->x1),
            (uint16_t)(area->y1),
            (uint16_t)(area->x2),
            (uint16_t)(area->y2), (uint16_t*)color_p
            );

    lv_disp_flush_ready(disp);         /* Indicate you are ready with the flushing*/
}


void lvgl_init() {
	lv_init();

	static lv_disp_draw_buf_t draw_buf;
	static lv_color_t buf1[LCD_WIDTH * LCD_HEIGHT / 10];                        /*Declare a buffer for 1/10 screen size*/
	lv_disp_draw_buf_init(&draw_buf, buf1, NULL, LCD_WIDTH * LCD_HEIGHT / 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 = tft_lvgl_disp_flush;    /*Set your driver function*/
	disp_drv.draw_buf = &draw_buf;        /*Assign the buffer to the display*/
	disp_drv.hor_res = lcd_get_width();   /*Set the horizontal resolution of the display*/
	disp_drv.ver_res = lcd_get_height();   /*Set the vertical resolution of the display*/
	lv_disp_drv_register(&disp_drv);      /*Finally register the driver*/

}

void lvgl_xpt2046_read_cb(lv_indev_drv_t * drv, lv_indev_data_t*data)
{
	static uint16_t x, y;
	if(XPT2046_TouchPressed()) {
		XPT2046_TouchGetCoordinates(&x, &y);
		data->point.x = x;
		data->point.y = y;
		data->state = LV_INDEV_STATE_PRESSED;
	} else {
		data->state = LV_INDEV_STATE_RELEASED;
	}
}

void lvgl_xpt2046_touch_init() {
	static lv_indev_drv_t indev_drv;
	lv_indev_drv_init(&indev_drv);      	/*Basic initialization*/
	indev_drv.type = LV_INDEV_TYPE_POINTER;
	indev_drv.read_cb = lvgl_xpt2046_read_cb;
	/*Register the driver in LVGL and save the created input device object*/
	lv_indev_drv_register(&indev_drv);
}


  
  • lcd_lvgl.h
#ifndef __LCD_LVGL_H
#define __LCD_LVGL_H

#include <lcd_fsmc.h>
#include <lvgl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "XPT2046_touch.h"


void lvgl_init();
void lvgl_xpt2046_touch_init();

#endif /*__LCD_LVGL_H */

  
  • XPT2046_touch.c
#include <lcd_fsmc.h>
#include <stdio.h>
#include <stdlib.h>
#include "XPT2046_touch.h"


#define READ_X 0xD0
#define READ_Y 0x90


uint16_t cRawX_min = XPT2046_MIN_RAW_X;
uint16_t cRawX_max = XPT2046_MAX_RAW_X;
uint16_t cRawY_min = XPT2046_MIN_RAW_Y;
uint16_t cRawY_max = XPT2046_MAX_RAW_Y;


static void XPT2046_TouchSelect()
{
    HAL_GPIO_WritePin(XPT2046_CS_GPIO_Port, XPT2046_CS_Pin, GPIO_PIN_RESET);
}

void XPT2046_TouchUnselect()
{
    HAL_GPIO_WritePin(XPT2046_CS_GPIO_Port, XPT2046_CS_Pin, GPIO_PIN_SET);
}

bool XPT2046_TouchPressed()
{
    return HAL_GPIO_ReadPin(XPT2046_IRQ_GPIO_Port, XPT2046_IRQ_Pin) == GPIO_PIN_RESET;
}

bool XPT2046_TouchGetCoordinates(uint16_t* x, uint16_t* y)
{
	bool ret_value=false;
	uint16_t tx,ty;
	uint32_t raw_x;
	uint32_t raw_y;
	if (XPT2046_TouchGetRawCoordinates(&raw_x, &raw_y))
	{
		if(raw_x < cRawX_min) raw_x = cRawX_min;
		if(raw_x > cRawX_max) raw_x = cRawX_max;

		if(raw_y < cRawY_min) raw_y = cRawY_min;
		if(raw_y > cRawY_max) raw_y = cRawY_max;

		tx = (raw_x - cRawX_min) * XPT2046_SCALE_X / (cRawX_max - cRawX_min);
		ty = (raw_y - cRawY_min) * XPT2046_SCALE_Y / (cRawY_max - cRawY_min);

		uint8_t lot = lcd_get_orientation();
		switch (lot)
		{
		case LCD_ORIENTATION_PORTRAIT:
			*x=tx;
			*y=ty;
			break;
		case LCD_ORIENTATION_LANDSCAPE:
			*x=ty;
			*y=LCD_WIDTH-tx;
					break;
		case LCD_ORIENTATION_PORTRAIT_MIRROR:
			*x=LCD_WIDTH-tx;
			*y=LCD_HEIGHT-ty;
					break;
		case LCD_ORIENTATION_LANDSCAPE_MIRROR:
			*x=LCD_HEIGHT-ty;
			*y=tx;
			break;
		}
		ret_value =true;
    }
	return ret_value;

}
bool XPT2046_TouchGetRawCoordinates(uint32_t* raw_x, uint32_t* raw_y)
{
    static const uint8_t cmd_read_x[] = { READ_X };
    static const uint8_t cmd_read_y[] = { READ_Y };
    static const uint8_t zeroes_tx[] = { 0x00, 0x00 };
    static const uint8_t SAMPLES=16;

    //if (!XPT2046_TouchPressed()) return false;
    //HAL_Delay(10);
    XPT2046_TouchSelect();

    uint32_t avg_x = 0;
    uint32_t avg_y = 0;
    uint8_t nsamples = 0;


    for(uint8_t i = 0; i < SAMPLES; i++)
    {
        if(!XPT2046_TouchPressed()) {
            break;
        }

        nsamples++;

        HAL_SPI_Transmit(&XPT2046_SPI_PORT, (uint8_t*)cmd_read_y, sizeof(cmd_read_y), HAL_MAX_DELAY);
        uint8_t y_raw[2];
        HAL_SPI_TransmitReceive(&XPT2046_SPI_PORT, (uint8_t*)zeroes_tx, y_raw, sizeof(y_raw), HAL_MAX_DELAY);

        HAL_SPI_Transmit(&XPT2046_SPI_PORT, (uint8_t*)cmd_read_x, sizeof(cmd_read_x), HAL_MAX_DELAY);
        uint8_t x_raw[2];
        HAL_SPI_TransmitReceive(&XPT2046_SPI_PORT, (uint8_t*)zeroes_tx, x_raw, sizeof(x_raw), HAL_MAX_DELAY);

        avg_x += (((uint16_t)x_raw[0]) << 8) | ((uint16_t)x_raw[1]);
        avg_y += (((uint16_t)y_raw[0]) << 8) | ((uint16_t)y_raw[1]);
    }

    XPT2046_TouchUnselect();

    if(nsamples < SAMPLES)
        return false;

    *raw_x = (avg_x / SAMPLES);
    *raw_y = (avg_y / SAMPLES);
    return true;

}

bool XPT2046_TouchCalibration()
{
	uint32_t x0=0,y0=0,x1=0,y1=0,x2=0,y2=0,x3=0,y3=0;
	bool correct=true;
	uint32_t width, height;
	uint8_t lot = lcd_get_orientation();
	lcd_set_orientation(LCD_ORIENTATION_PORTRAIT);
	width = lcd_get_width();
	height = lcd_get_height();
	lcd_fill_RGB(0x0000, 0, 0, width-1, height-1);



	lcd_fill_RGB(0xffff, 0, 0, 6,6);
	lcd_set_window(20,100 ,20 ,100);  // set LCD cursor to (20,100)
	while(!XPT2046_TouchPressed()) ;
	if (!XPT2046_TouchGetRawCoordinates(&x0, &y0))
	{
		lcd_set_orientation(lot);
		return false;
	}
	lcd_fill_RGB(0x0000, 0, 0, width-1, height-1);
	lcd_fill_RGB(0xffff, 0, height-7, 6, 6);

	while(XPT2046_TouchPressed());
	HAL_Delay(1);

	lcd_set_window(20, 100, 20, 100);
	while(!XPT2046_TouchPressed());
	if(!XPT2046_TouchGetRawCoordinates(&x1, &y1))
	{
		lcd_set_orientation(lot);
		return false;
	}
	lcd_fill_RGB(0x0000, 0, 0, width-1, height-1);
	lcd_fill_RGB(0xffff,width-7, height-7, 6, 6);
	while(XPT2046_TouchPressed());
	HAL_Delay(1);


	lcd_set_window(20, 100, 20, 100);
	while(!XPT2046_TouchPressed());
	if (!XPT2046_TouchGetRawCoordinates(&x2, &y2))
	{
		lcd_set_orientation(lot);
		return false;
	}
	lcd_fill_RGB(0x0000, 0, 0, width-1, height-1);
	lcd_fill_RGB(0xffff, width-7, 0, 6, 6);
	while(XPT2046_TouchPressed());
	HAL_Delay(1);

	lcd_set_window(20, 100, 20, 100);
	while(!XPT2046_TouchPressed());
	if (!XPT2046_TouchGetRawCoordinates(&x3, &y3))
	{
		lcd_set_orientation(lot);
		return false;
	}
	while(XPT2046_TouchPressed());

	if (abs(x0-x1) > XTP2046_CALI_DIFF) correct = false;
	if (abs(x2-x3) > XTP2046_CALI_DIFF) correct = false;
	if (abs(y1-y2) > XTP2046_CALI_DIFF) correct = false;
	if (abs(y0-y3) > XTP2046_CALI_DIFF) correct = false;
	if (correct) {
		cRawX_min = (x0+x1)/2;
		cRawX_max = (x2+x3)/2;
		cRawY_min = (y0+y3)/2;
		cRawY_max = (y1+y2)/2;
	}

	lcd_fill_RGB(0x0000, 0, 0, width-1, height-1);
	lcd_set_window(20, 100, 20, 100);
	lcd_set_orientation(lot);
	return correct;
}
  • XPT2046_touch.h
#ifndef XPT2046_TOUCH_H_
#define XPT2046_TOUCH_H_

#include "main.h"
#include <stdbool.h>

/*** Redefine if necessary ***/

// Warning! Use SPI bus with < 2.5 Mbit speed, better ~650 Kbit to be save.
#define XPT2046_SPI_PORT hspi2
extern SPI_HandleTypeDef XPT2046_SPI_PORT;

#define XPT2046_IRQ_Pin       T_IRQ_Pin
#define XPT2046_IRQ_GPIO_Port T_IRQ_GPIO_Port
#define XPT2046_CS_Pin        T_CS_Pin
#define XPT2046_CS_GPIO_Port  T_CS_GPIO_Port

// change depending on screen orientation
#define XPT2046_SCALE_X 240
#define XPT2046_SCALE_Y 320

#define XPT2046_MIN_RAW_X 1860
#define XPT2046_MAX_RAW_X 29650
#define XPT2046_MIN_RAW_Y 1830
#define XPT2046_MAX_RAW_Y 29350

//#define XPT2046_MIN_RAW_X 2000
//#define XPT2046_MAX_RAW_X 30000
//#define XPT2046_MIN_RAW_Y 1500
//#define XPT2046_MAX_RAW_Y 29000

#define XTP2046_CALI_DIFF	2500

// call before initializing any SPI devices
void XPT2046_TouchUnselect(void);
bool XPT2046_TouchPressed(void);
bool XPT2046_TouchGetCoordinates(uint16_t* x, uint16_t* y);
bool XPT2046_TouchGetRawCoordinates(uint32_t* raw_, uint32_t* raw_y);
bool XPT2046_TouchCalibration(void);

#endif /* XPT2046_TOUCH_H_ */

  • main.c
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "fatfs.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "XPT2046_touch.h"
#include "lcd_fsmc.h"
#include "lcd_lvgl.h"
#include "sht40.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c1;

SD_HandleTypeDef hsd;
DMA_HandleTypeDef hdma_sdio_rx;
DMA_HandleTypeDef hdma_sdio_tx;

SPI_HandleTypeDef hspi2;

TIM_HandleTypeDef htim3;

DMA_HandleTypeDef hdma_memtomem_dma2_stream0;
SRAM_HandleTypeDef hsram1;

/* USER CODE BEGIN PV */
void demo_screen_rotation();
void dma_demo();
void sd_img_dma_demo();
void temp_humi_demo();

float sht40_temp, sht40_humi;
extern lv_obj_t* temp_bar;
extern lv_obj_t* humi_meter;
extern lv_meter_indicator_t * humi_indic;
extern uint8_t test_with_dma;

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_FSMC_Init(void);
static void MX_SPI2_Init(void);
static void MX_TIM3_Init(void);
static void MX_I2C1_Init(void);
static void MX_SDIO_SD_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* tim) {

	lv_tick_inc(5);
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_FSMC_Init();
  MX_SPI2_Init();
  MX_TIM3_Init();
  MX_I2C1_Init();
  MX_SDIO_SD_Init();
  MX_FATFS_Init();
  /* USER CODE BEGIN 2 */
  f_mount(&SDFatFS, SDPath, 1);



  HAL_TIM_Base_Start_IT(&htim3);
  HAL_I2C_Init(&hi2c1);

  lcd_backlight_on();
  lcd_init();
  lcd_set_orientation(LCD_ORIENTATION_LANDSCAPE);

  //while(!XPT2046_TouchCalibration()) {HAL_Delay(100);}

  lvgl_init();
  lvgl_xpt2046_touch_init();

dma_demo();
 HAL_Delay(5000);
 lv_obj_clean(lv_scr_act());
  test_with_dma=1;
  for (int i=0; i < 2; i++) {
	  test_with_dma = (test_with_dma+1)%2;
	  sd_img_dma_demo();
	  lv_obj_clean(lv_scr_act());
  }

  //demo_screen_rotation();
  temp_humi_demo();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */

  uint32_t count=0;
  while (1)
  {
	  lv_timer_handler();
	  HAL_Delay(5);

	  if (count > 400) {
		  count = 0;
		  sht40_get_th_data(&sht40_temp, &sht40_humi);
		  lv_bar_set_value(temp_bar, (int32_t)sht40_temp, LV_ANIM_ON);

		  lv_meter_set_indicator_end_value(humi_meter, humi_indic, sht40_humi);
	  }
	  count++;

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 168;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief I2C1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_I2C1_Init(void)
{

  /* USER CODE BEGIN I2C1_Init 0 */

  /* USER CODE END I2C1_Init 0 */

  /* USER CODE BEGIN I2C1_Init 1 */

  /* USER CODE END I2C1_Init 1 */
  hi2c1.Instance = I2C1;
  hi2c1.Init.ClockSpeed = 400000;
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN I2C1_Init 2 */

  /* USER CODE END I2C1_Init 2 */

}

/**
  * @brief SDIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_SDIO_SD_Init(void)
{

  /* USER CODE BEGIN SDIO_Init 0 */

  /* USER CODE END SDIO_Init 0 */

  /* USER CODE BEGIN SDIO_Init 1 */

  /* USER CODE END SDIO_Init 1 */
  hsd.Instance = SDIO;
  hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
  hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
  hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
  hsd.Init.BusWide = SDIO_BUS_WIDE_4B;
  hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
  hsd.Init.ClockDiv = 0;
  /* USER CODE BEGIN SDIO_Init 2 */
  hsd.Init.BusWide = SDIO_BUS_WIDE_1B;
  /* USER CODE END SDIO_Init 2 */

}

/**
  * @brief SPI2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_SPI2_Init(void)
{

  /* USER CODE BEGIN SPI2_Init 0 */

  /* USER CODE END SPI2_Init 0 */

  /* USER CODE BEGIN SPI2_Init 1 */

  /* USER CODE END SPI2_Init 1 */
  /* SPI2 parameter configuration*/
  hspi2.Instance = SPI2;
  hspi2.Init.Mode = SPI_MODE_MASTER;
  hspi2.Init.Direction = SPI_DIRECTION_2LINES;
  hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi2.Init.NSS = SPI_NSS_SOFT;
  hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
  hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi2.Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(&hspi2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SPI2_Init 2 */

  /* USER CODE END SPI2_Init 2 */

}

/**
  * @brief TIM3 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM3_Init(void)
{

  /* USER CODE BEGIN TIM3_Init 0 */

  /* USER CODE END TIM3_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  /* USER CODE BEGIN TIM3_Init 1 */

  /* USER CODE END TIM3_Init 1 */
  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 42000-1;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 10-1;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM3_Init 2 */


  /* USER CODE END TIM3_Init 2 */

}

/**
  * Enable DMA controller clock
  * Configure DMA for memory to memory transfers
  *   hdma_memtomem_dma2_stream0
  */
static void MX_DMA_Init(void)
{

  /* DMA controller clock enable */
  __HAL_RCC_DMA2_CLK_ENABLE();

  /* Configure DMA request hdma_memtomem_dma2_stream0 on DMA2_Stream0 */
  hdma_memtomem_dma2_stream0.Instance = DMA2_Stream0;
  hdma_memtomem_dma2_stream0.Init.Channel = DMA_CHANNEL_0;
  hdma_memtomem_dma2_stream0.Init.Direction = DMA_MEMORY_TO_MEMORY;
  hdma_memtomem_dma2_stream0.Init.PeriphInc = DMA_PINC_ENABLE;
  hdma_memtomem_dma2_stream0.Init.MemInc = DMA_MINC_DISABLE;
  hdma_memtomem_dma2_stream0.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
  hdma_memtomem_dma2_stream0.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
  hdma_memtomem_dma2_stream0.Init.Mode = DMA_NORMAL;
  hdma_memtomem_dma2_stream0.Init.Priority = DMA_PRIORITY_LOW;
  hdma_memtomem_dma2_stream0.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
  hdma_memtomem_dma2_stream0.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
  hdma_memtomem_dma2_stream0.Init.MemBurst = DMA_MBURST_SINGLE;
  hdma_memtomem_dma2_stream0.Init.PeriphBurst = DMA_PBURST_SINGLE;
  if (HAL_DMA_Init(&hdma_memtomem_dma2_stream0) != HAL_OK)
  {
    Error_Handler( );
  }

  /* DMA interrupt init */
  /* DMA2_Stream3_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
  /* DMA2_Stream6_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream6_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn);

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOE_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LCD_BL_GPIO_Port, LCD_BL_Pin, GPIO_PIN_SET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(T_CS_GPIO_Port, T_CS_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pins : PC4 T_IRQ_Pin */
  GPIO_InitStruct.Pin = GPIO_PIN_4|T_IRQ_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pins : LCD_BL_Pin T_CS_Pin */
  GPIO_InitStruct.Pin = LCD_BL_Pin|T_CS_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}

/* FSMC initialization function */
static void MX_FSMC_Init(void)
{

  /* USER CODE BEGIN FSMC_Init 0 */

  /* USER CODE END FSMC_Init 0 */

  FSMC_NORSRAM_TimingTypeDef Timing = {0};

  /* USER CODE BEGIN FSMC_Init 1 */

  /* USER CODE END FSMC_Init 1 */

  /** Perform the SRAM1 memory initialization sequence
  */
  hsram1.Instance = FSMC_NORSRAM_DEVICE;
  hsram1.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;
  /* hsram1.Init */
  hsram1.Init.NSBank = FSMC_NORSRAM_BANK1;
  hsram1.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE;
  hsram1.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM;
  hsram1.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16;
  hsram1.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE;
  hsram1.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW;
  hsram1.Init.WrapMode = FSMC_WRAP_MODE_DISABLE;
  hsram1.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS;
  hsram1.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE;
  hsram1.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE;
  hsram1.Init.ExtendedMode = FSMC_EXTENDED_MODE_DISABLE;
  hsram1.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE;
  hsram1.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE;
  hsram1.Init.PageSize = FSMC_PAGE_SIZE_NONE;
  /* Timing */
  Timing.AddressSetupTime = 6;
  Timing.AddressHoldTime = 15;
  Timing.DataSetupTime = 4;
  Timing.BusTurnAroundDuration = 4;
  Timing.CLKDivision = 16;
  Timing.DataLatency = 17;
  Timing.AccessMode = FSMC_ACCESS_MODE_A;
  /* ExtTiming */

  if (HAL_SRAM_Init(&hsram1, &Timing, NULL) != HAL_OK)
  {
    Error_Handler( );
  }

  /* USER CODE BEGIN FSMC_Init 2 */

  /* USER CODE END FSMC_Init 2 */
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

  • demo.c
#include <lcd_fsmc.h>
#include "lvgl.h"
#include <stdio.h>
#include <stdlib.h>

static lv_obj_t * arc;
extern float sht40_temp, sht40_numi;

static void arc_value_changed_event_cb(lv_event_t * e)
{
    lv_obj_t * arc = lv_event_get_target(e);
    lv_obj_t * label = lv_event_get_user_data(e);

    lv_label_set_text_fmt(label, "%d%%", lv_arc_get_value(arc));
    lv_arc_align_obj_to_angle(arc, label, 25);

    //lv_arc_rotate_obj_to_angle(arc, label, 25);
}

void mbtn_cb(lv_event_t* e) {

	lv_arc_set_value(arc, lv_arc_get_value(arc)-1);
	lv_event_send(arc, LV_EVENT_VALUE_CHANGED, NULL);
}

void pbtn_cb(lv_event_t* e) {

	lv_arc_set_value(arc, lv_arc_get_value(arc)+1);
	lv_event_send(arc, LV_EVENT_VALUE_CHANGED, NULL);
}

void rbtn_cb(lv_event_t* e) {
	uint8_t rot = lcd_get_orientation();
	lcd_set_orientation((rot+1)%4);
	lv_disp_t* disp = lv_disp_get_default();
	disp->driver->hor_res = lcd_get_width();
	disp->driver->ver_res = lcd_get_height();

	lv_disp_set_rotation(disp, LV_DISP_ROT_NONE);

}

void demo_screen_rotation() {
	lv_obj_t * label = lv_label_create(lv_scr_act());

	arc = lv_arc_create(lv_scr_act());
	lv_obj_set_size(arc, 170, 170);
	lv_arc_set_rotation(arc, 150);
	lv_arc_set_bg_angles(arc, 0, 240);
	lv_arc_set_mode(arc, LV_ARC_MODE_SYMMETRICAL);
	lv_arc_set_value(arc, 50);
	lv_obj_align(arc,LV_ALIGN_TOP_MID, 0, 25);
	lv_obj_add_event_cb(arc, arc_value_changed_event_cb, LV_EVENT_VALUE_CHANGED, label);


	lv_event_send(arc, LV_EVENT_VALUE_CHANGED, NULL);

	lv_obj_t *pbtn = lv_btn_create(lv_scr_act());
	lv_obj_t *plabel = lv_label_create(pbtn);
	lv_label_set_text(plabel, LV_SYMBOL_PLUS);
	lv_obj_align(pbtn, LV_ALIGN_BOTTOM_MID, 30, -20);
	lv_obj_set_size(pbtn, 40, 30);
	lv_obj_add_event_cb(pbtn, pbtn_cb, LV_EVENT_CLICKED, NULL);

	lv_obj_t *mbtn = lv_btn_create(lv_scr_act());
	lv_obj_t *mlabel = lv_label_create(mbtn);
	lv_label_set_text(mlabel, LV_SYMBOL_MINUS);
	lv_obj_align(mbtn, LV_ALIGN_BOTTOM_MID, -30, -20);
	lv_obj_set_size(mbtn, 40, 30);
	lv_obj_add_event_cb(mbtn, mbtn_cb, LV_EVENT_CLICKED, NULL);

	lv_obj_t *rbtn = lv_btn_create(lv_scr_act());
	lv_obj_t *rlabel = lv_label_create(rbtn);
	lv_label_set_text(rlabel, "R");
	lv_obj_align(rbtn, LV_ALIGN_BOTTOM_RIGHT, -10, -20);
	lv_obj_set_size(rbtn, 40, 30);
	lv_obj_add_event_cb(rbtn, rbtn_cb, LV_EVENT_CLICKED, NULL);

}

extern DMA_HandleTypeDef hdma_memtomem_dma2_stream0;
void dma_demo() {
	uint16_t color[240*32];
	uint16_t tc[3] = {0xf100, 0x7e0, 0x1f};
	uint32_t t1;
	uint16_t width=lcd_get_width();
	uint16_t height=lcd_get_height();
	int  sum=0;

	lv_obj_t* label = lv_label_create(lv_scr_act());
	lv_obj_center(label);
	lv_obj_set_style_text_font(label, &lv_font_montserrat_18, 0);
	lv_label_set_text(label, "With DMA \n    vs\n without DMA");
	lv_timer_handler();
	HAL_Delay(3000);
	lv_label_set_text(label, "Start with DMA(preload):\n10 frame\n500ms delay \nbetween frames");
	lv_timer_handler();
	HAL_Delay(3000);

	for (int i = 0; i < 10; i++) {
		//t1 = HAL_GetTick();
		for (int j = 0; j < 240*32; j++) color[j] = tc[i%3];
		t1 = HAL_GetTick();
			lcd_set_window(0, 0, width-1, height-1);

			// use memory-to-memory DMA
			for (int k=0; k < 10; k++) {
				//for (int j = 0; j < 240*32; j++) color[j] = tc[i%3];
				HAL_DMA_Start(&hdma_memtomem_dma2_stream0, (uint32_t)color, (LCD_DATA_BASE), 240*32);
				HAL_DMA_PollForTransfer(&hdma_memtomem_dma2_stream0, HAL_DMA_FULL_TRANSFER, 1000);
				}
		sum += HAL_GetTick()-t1;
		HAL_Delay(500);
	}
	lv_label_set_text_fmt(label, "End with DMA:\n10 frames \nTotal Time:%d ms", sum);
	lv_timer_handler();

	HAL_Delay(5000);
	lv_label_set_text(label, "Start without DMA:\n10 frame\n500ms delay \nbetween frames");
	lv_timer_handler();
	HAL_Delay(3000);
	sum=0;
	for (int i = 0; i < 10; i++) {

		t1 = HAL_GetTick();

		lcd_fill_RGB(tc[i%3], 0, 0, width, height);

		sum += HAL_GetTick()-t1;
		HAL_Delay(500);
	}
	lv_label_set_text_fmt(label, "End without DMA:\n10 frames \nTotal Time:%d ms", sum);
	lv_timer_handler();
	HAL_Delay(5000);
}

uint8_t test_with_dma=true;
void sd_img_dma_demo() {
	uint32_t t1;
	int sum=0;
	char fn[20];
	lv_obj_t* img = lv_img_create(lv_scr_act());
	lv_obj_center(img);
	lv_obj_t* label = lv_label_create(lv_scr_act());
	lv_obj_center(label);
	lv_obj_set_style_text_font(label, &lv_font_montserrat_18, 0);
	lv_label_set_text(label, "With DMA \n       vs\n without DMA");
	lv_timer_handler();
	HAL_Delay(3000);
	if (test_with_dma)
		lv_label_set_text(label, "Start with DMA:\n10 frame\n500ms delay \nbetween frames");
	else
		lv_label_set_text(label, "Start without DMA:\n10 frame\n500ms delay \nbetween frames");
	lv_timer_handler();
	HAL_Delay(3000);
	lv_obj_add_flag(label, LV_OBJ_FLAG_HIDDEN);
	sum=0;

	for (int i =0; i < 10; i++) {
		t1 = HAL_GetTick();
		sprintf(fn, "S:img%d.bmp", i);
		lv_img_set_src(img, fn);
		lv_timer_handler();
		sum += (HAL_GetTick()-t1);
		HAL_Delay(500);
	}

	lv_obj_add_flag(img, LV_OBJ_FLAG_HIDDEN);
	lv_obj_clear_flag(label, LV_OBJ_FLAG_HIDDEN);
	if (test_with_dma)
		lv_label_set_text_fmt(label, "End with DMA:\n10 frames \nTotal Time:%d ms", sum);
	else
		lv_label_set_text_fmt(label, "End without DMA:\n10 frames \nTotal Time:%d ms", sum);
	lv_timer_handler();
	HAL_Delay(5000);


}

lv_obj_t* temp_bar;
lv_obj_t* humi_meter;
lv_meter_indicator_t * humi_indic;
static void temp_bar_event_cb(lv_event_t * e)
{
    lv_obj_draw_part_dsc_t * dsc = lv_event_get_draw_part_dsc(e);
    if(dsc->part != LV_PART_INDICATOR) return;

    lv_obj_t * obj = lv_event_get_target(e);

    lv_draw_label_dsc_t label_dsc;
    lv_draw_label_dsc_init(&label_dsc);
    label_dsc.font = LV_FONT_DEFAULT;

    char buf[8];
    lv_snprintf(buf, sizeof(buf), "%d", (int)lv_bar_get_value(obj));

    lv_point_t txt_size;
    lv_txt_get_size(&txt_size, buf, label_dsc.font, label_dsc.letter_space, label_dsc.line_space, LV_COORD_MAX,
                    label_dsc.flag);

    lv_area_t txt_area;
    /*If the indicator is long enough put the text inside on the right*/
    if(lv_area_get_height(dsc->draw_area) > txt_size.x + 20) {
        txt_area.x2 = dsc->draw_area->x2 - 5;
        txt_area.x1 = txt_area.x2 - txt_size.x + 1;
        label_dsc.color = lv_color_white();
    }
    /*If the indicator is still short put the text out of it on the right*/
    else {
        txt_area.x1 = dsc->draw_area->x2 + 5;
        txt_area.x2 = txt_area.x1 + txt_size.x - 1;
        label_dsc.color = lv_color_black();
    }

    txt_area.y1 = dsc->draw_area->y1 + (lv_area_get_width(dsc->draw_area) - txt_size.y) / 2;
    txt_area.y2 = txt_area.y1 + txt_size.y - 1;

    lv_draw_label(dsc->draw_ctx, &label_dsc, &txt_area, buf, NULL);
}
void temp_humi_demo () {

	// temperature
	static lv_style_t style_bg;
	static lv_style_t style_indic;

	lv_style_init(&style_bg);
	lv_style_set_border_color(&style_bg, lv_palette_main(LV_PALETTE_BLUE));
	lv_style_set_border_width(&style_bg, 2);
	lv_style_set_pad_all(&style_bg, 6); /*To make the indicator smaller*/
	lv_style_set_radius(&style_bg, 6);
	lv_style_set_anim_time(&style_bg, 1000);

	lv_style_init(&style_indic);
	lv_style_set_bg_opa(&style_indic, LV_OPA_COVER);
	lv_style_set_radius(&style_indic, 3);
	lv_style_set_bg_color(&style_indic, lv_palette_main(LV_PALETTE_RED));
	lv_style_set_bg_grad_color(&style_indic, lv_palette_main(LV_PALETTE_BLUE));
	lv_style_set_bg_grad_dir(&style_indic, LV_GRAD_DIR_VER);

	temp_bar = lv_bar_create(lv_scr_act());
	lv_obj_remove_style_all(temp_bar);  /*To have a clean start*/
	lv_obj_add_style(temp_bar, &style_bg, 0);
	lv_obj_add_style(temp_bar, &style_indic, LV_PART_INDICATOR);
	lv_bar_set_range(temp_bar, -10, 70);
	lv_obj_add_event_cb(temp_bar, temp_bar_event_cb, LV_EVENT_DRAW_PART_END, NULL);

	lv_obj_set_size(temp_bar, 40, 180);
	lv_obj_align(temp_bar, LV_ALIGN_TOP_LEFT,15,10);

	lv_obj_t* temp_label=lv_label_create(lv_scr_act());
	lv_obj_set_style_text_font(temp_label, &lv_font_montserrat_18, 0);
	lv_obj_set_style_text_color(temp_label, lv_palette_main(LV_PALETTE_BLUE), 0);
	lv_obj_set_size(temp_label, 30, 30);
	char tempbuff[10];
	sprintf(tempbuff, "\xC2\xB0" "C"); //°C
	lv_label_set_text(temp_label, tempbuff);
	lv_obj_align_to(temp_label, temp_bar, LV_ALIGN_OUT_BOTTOM_MID, 0, 5);

	lv_bar_set_value(temp_bar, 70, LV_ANIM_ON);


	//humidity
	humi_meter = lv_meter_create(lv_scr_act());
	lv_obj_align(humi_meter, LV_ALIGN_TOP_RIGHT, -10, 10);
	lv_obj_set_size(humi_meter, 200, 200);

	lv_obj_remove_style(humi_meter, NULL, LV_PART_INDICATOR);

	lv_meter_scale_t * scale = lv_meter_add_scale(humi_meter);
	lv_meter_set_scale_ticks(humi_meter, scale, 11, 2, 10, lv_palette_main(LV_PALETTE_GREY));
	lv_meter_set_scale_major_ticks(humi_meter, scale, 1, 2, 15, lv_color_hex3(0xeee), 5);
	lv_meter_set_scale_range(humi_meter, scale, 0, 100, 270, 135);


	humi_indic = lv_meter_add_arc(humi_meter, scale, 10, lv_palette_main(LV_PALETTE_GREEN), 0);
	lv_meter_set_indicator_end_value(humi_meter, humi_indic, 100);
	lv_obj_t* humi_label=lv_label_create(lv_scr_act());
	lv_obj_set_size(humi_label, 30, 30);
	lv_obj_set_style_text_font(humi_label, &lv_font_montserrat_18, 0);
	lv_obj_set_style_text_color(humi_label, lv_palette_main(LV_PALETTE_BLUE), 0);
	lv_label_set_text(humi_label, "%");
	lv_obj_align_to(humi_label, humi_meter, LV_ALIGN_BOTTOM_MID, 0,5);
}
  • STM32_LVGL.ioc
#MicroXplorer Configuration settings - do not modify
CAD.formats=
CAD.pinconfig=
CAD.provider=
Dma.MEMTOMEM.0.Direction=DMA_MEMORY_TO_MEMORY
Dma.MEMTOMEM.0.FIFOMode=DMA_FIFOMODE_ENABLE
Dma.MEMTOMEM.0.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL
Dma.MEMTOMEM.0.Instance=DMA2_Stream0
Dma.MEMTOMEM.0.MemBurst=DMA_MBURST_SINGLE
Dma.MEMTOMEM.0.MemDataAlignment=DMA_MDATAALIGN_HALFWORD
Dma.MEMTOMEM.0.MemInc=DMA_MINC_DISABLE
Dma.MEMTOMEM.0.Mode=DMA_NORMAL
Dma.MEMTOMEM.0.PeriphBurst=DMA_PBURST_SINGLE
Dma.MEMTOMEM.0.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD
Dma.MEMTOMEM.0.PeriphInc=DMA_PINC_ENABLE
Dma.MEMTOMEM.0.Priority=DMA_PRIORITY_LOW
Dma.MEMTOMEM.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,FIFOThreshold,MemBurst,PeriphBurst
Dma.Request0=MEMTOMEM
Dma.Request1=SDIO_RX
Dma.Request2=SDIO_TX
Dma.RequestsNb=3
Dma.SDIO_RX.1.Direction=DMA_PERIPH_TO_MEMORY
Dma.SDIO_RX.1.FIFOMode=DMA_FIFOMODE_ENABLE
Dma.SDIO_RX.1.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL
Dma.SDIO_RX.1.Instance=DMA2_Stream3
Dma.SDIO_RX.1.MemBurst=DMA_MBURST_INC4
Dma.SDIO_RX.1.MemDataAlignment=DMA_MDATAALIGN_WORD
Dma.SDIO_RX.1.MemInc=DMA_MINC_ENABLE
Dma.SDIO_RX.1.Mode=DMA_PFCTRL
Dma.SDIO_RX.1.PeriphBurst=DMA_PBURST_INC4
Dma.SDIO_RX.1.PeriphDataAlignment=DMA_PDATAALIGN_WORD
Dma.SDIO_RX.1.PeriphInc=DMA_PINC_DISABLE
Dma.SDIO_RX.1.Priority=DMA_PRIORITY_LOW
Dma.SDIO_RX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,FIFOThreshold,MemBurst,PeriphBurst
Dma.SDIO_TX.2.Direction=DMA_MEMORY_TO_PERIPH
Dma.SDIO_TX.2.FIFOMode=DMA_FIFOMODE_ENABLE
Dma.SDIO_TX.2.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL
Dma.SDIO_TX.2.Instance=DMA2_Stream6
Dma.SDIO_TX.2.MemBurst=DMA_MBURST_INC4
Dma.SDIO_TX.2.MemDataAlignment=DMA_MDATAALIGN_WORD
Dma.SDIO_TX.2.MemInc=DMA_MINC_ENABLE
Dma.SDIO_TX.2.Mode=DMA_PFCTRL
Dma.SDIO_TX.2.PeriphBurst=DMA_PBURST_INC4
Dma.SDIO_TX.2.PeriphDataAlignment=DMA_PDATAALIGN_WORD
Dma.SDIO_TX.2.PeriphInc=DMA_PINC_DISABLE
Dma.SDIO_TX.2.Priority=DMA_PRIORITY_LOW
Dma.SDIO_TX.2.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,FIFOThreshold,MemBurst,PeriphBurst
FATFS.BSP.number=1
FATFS.IPParameters=USE_DMA_CODE_SD,_MAX_SS
FATFS.USE_DMA_CODE_SD=1
FATFS._MAX_SS=4096
FATFS0.BSP.STBoard=false
FATFS0.BSP.api=Unknown
FATFS0.BSP.component=
FATFS0.BSP.condition=
FATFS0.BSP.instance=PC4
FATFS0.BSP.ip=GPIO
FATFS0.BSP.mode=Input
FATFS0.BSP.name=Detect_SDIO
FATFS0.BSP.semaphore=
FATFS0.BSP.solution=PC4
FSMC.AddressSetupTime1=6
FSMC.BusTurnAroundDuration1=4
FSMC.DataSetupTime1=4
FSMC.IPParameters=DataSetupTime1,BusTurnAroundDuration1,AddressSetupTime1
File.Version=6
I2C1.I2C_Mode=I2C_Fast
I2C1.IPParameters=I2C_Mode
KeepUserPlacement=false
Mcu.CPN=STM32F407VET6
Mcu.Family=STM32F4
Mcu.IP0=DMA
Mcu.IP1=FATFS
Mcu.IP2=FSMC
Mcu.IP3=I2C1
Mcu.IP4=NVIC
Mcu.IP5=RCC
Mcu.IP6=SDIO
Mcu.IP7=SPI2
Mcu.IP8=SYS
Mcu.IP9=TIM3
Mcu.IPNb=10
Mcu.Name=STM32F407V(E-G)Tx
Mcu.Package=LQFP100
Mcu.Pin0=PC14-OSC32_IN
Mcu.Pin1=PC15-OSC32_OUT
Mcu.Pin10=PE10
Mcu.Pin11=PE11
Mcu.Pin12=PE12
Mcu.Pin13=PE13
Mcu.Pin14=PE14
Mcu.Pin15=PE15
Mcu.Pin16=PB12
Mcu.Pin17=PB13
Mcu.Pin18=PB14
Mcu.Pin19=PB15
Mcu.Pin2=PH0-OSC_IN
Mcu.Pin20=PD8
Mcu.Pin21=PD9
Mcu.Pin22=PD10
Mcu.Pin23=PD13
Mcu.Pin24=PD14
Mcu.Pin25=PD15
Mcu.Pin26=PC8
Mcu.Pin27=PC9
Mcu.Pin28=PC10
Mcu.Pin29=PC11
Mcu.Pin3=PH1-OSC_OUT
Mcu.Pin30=PC12
Mcu.Pin31=PD0
Mcu.Pin32=PD1
Mcu.Pin33=PD2
Mcu.Pin34=PD4
Mcu.Pin35=PD5
Mcu.Pin36=PD7
Mcu.Pin37=PB6
Mcu.Pin38=PB7
Mcu.Pin39=VP_FATFS_VS_SDIO
Mcu.Pin4=PC4
Mcu.Pin40=VP_SYS_VS_Systick
Mcu.Pin41=VP_TIM3_VS_ClockSourceINT
Mcu.Pin5=PC5
Mcu.Pin6=PB1
Mcu.Pin7=PE7
Mcu.Pin8=PE8
Mcu.Pin9=PE9
Mcu.PinsNb=42
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32F407VETx
MxCube.Version=6.12.0
MxDb.Version=DB.6.0.120
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.DMA2_Stream3_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true
NVIC.DMA2_Stream6_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.ForceEnableDMAVector=true
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.SDIO_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false
NVIC.TIM3_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
PB1.GPIOParameters=PinState,GPIO_Label
PB1.GPIO_Label=LCD_BL
PB1.Locked=true
PB1.PinState=GPIO_PIN_SET
PB1.Signal=GPIO_Output
PB12.GPIOParameters=GPIO_Label
PB12.GPIO_Label=T_CS
PB12.Locked=true
PB12.Signal=GPIO_Output
PB13.Locked=true
PB13.Mode=Full_Duplex_Master
PB13.Signal=SPI2_SCK
PB14.Locked=true
PB14.Mode=Full_Duplex_Master
PB14.Signal=SPI2_MISO
PB15.Locked=true
PB15.Mode=Full_Duplex_Master
PB15.Signal=SPI2_MOSI
PB6.Mode=I2C
PB6.Signal=I2C1_SCL
PB7.Mode=I2C
PB7.Signal=I2C1_SDA
PC10.Mode=SD_4_bits_Wide_bus
PC10.Signal=SDIO_D2
PC11.Mode=SD_4_bits_Wide_bus
PC11.Signal=SDIO_D3
PC12.Mode=SD_4_bits_Wide_bus
PC12.Signal=SDIO_CK
PC14-OSC32_IN.Mode=LSE-External-Oscillator
PC14-OSC32_IN.Signal=RCC_OSC32_IN
PC15-OSC32_OUT.Mode=LSE-External-Oscillator
PC15-OSC32_OUT.Signal=RCC_OSC32_OUT
PC4.Locked=true
PC4.Signal=GPIO_Input
PC5.GPIOParameters=GPIO_Label
PC5.GPIO_Label=T_IRQ
PC5.Locked=true
PC5.Signal=GPIO_Input
PC8.Mode=SD_4_bits_Wide_bus
PC8.Signal=SDIO_D0
PC9.Mode=SD_4_bits_Wide_bus
PC9.Signal=SDIO_D1
PD0.Mode=16b-d1
PD0.Signal=FSMC_D2
PD1.Mode=16b-d1
PD1.Signal=FSMC_D3
PD10.Mode=16b-d1
PD10.Signal=FSMC_D15
PD13.Mode=A18_1
PD13.Signal=FSMC_A18
PD14.Mode=16b-d1
PD14.Signal=FSMC_D0
PD15.Mode=16b-d1
PD15.Signal=FSMC_D1
PD2.Mode=SD_4_bits_Wide_bus
PD2.Signal=SDIO_CMD
PD4.Mode=Lcd1
PD4.Signal=FSMC_NOE
PD5.Mode=Lcd1
PD5.Signal=FSMC_NWE
PD7.Mode=NorPsramChipSelect1_1
PD7.Signal=FSMC_NE1
PD8.Mode=16b-d1
PD8.Signal=FSMC_D13
PD9.Mode=16b-d1
PD9.Signal=FSMC_D14
PE10.Mode=16b-d1
PE10.Signal=FSMC_D7
PE11.Mode=16b-d1
PE11.Signal=FSMC_D8
PE12.Mode=16b-d1
PE12.Signal=FSMC_D9
PE13.Mode=16b-d1
PE13.Signal=FSMC_D10
PE14.Mode=16b-d1
PE14.Signal=FSMC_D11
PE15.Mode=16b-d1
PE15.Signal=FSMC_D12
PE7.Mode=16b-d1
PE7.Signal=FSMC_D4
PE8.Mode=16b-d1
PE8.Signal=FSMC_D5
PE9.Mode=16b-d1
PE9.Signal=FSMC_D6
PH0-OSC_IN.Mode=HSE-External-Oscillator
PH0-OSC_IN.Signal=RCC_OSC_IN
PH1-OSC_OUT.Mode=HSE-External-Oscillator
PH1-OSC_OUT.Signal=RCC_OSC_OUT
PinOutPanel.RotationAngle=0
ProjectManager.AskForMigrate=true
ProjectManager.BackupPrevious=false
ProjectManager.CompilerOptimize=6
ProjectManager.ComputerToolchain=false
ProjectManager.CoupleFile=false
ProjectManager.CustomerFirmwarePackage=
ProjectManager.DefaultFWLocation=true
ProjectManager.DeletePrevious=true
ProjectManager.DeviceId=STM32F407VETx
ProjectManager.FirmwarePackage=STM32Cube FW_F4 V1.28.0
ProjectManager.FreePins=false
ProjectManager.HalAssertFull=false
ProjectManager.HeapSize=0x200
ProjectManager.KeepUserCode=true
ProjectManager.LastFirmware=true
ProjectManager.LibraryCopy=1
ProjectManager.MainLocation=Core/Src
ProjectManager.NoMain=false
ProjectManager.PreviousToolchain=
ProjectManager.ProjectBuild=false
ProjectManager.ProjectFileName=STM32_LVGL.ioc
ProjectManager.ProjectName=STM32_LVGL
ProjectManager.ProjectStructure=
ProjectManager.RegisterCallBack=
ProjectManager.StackSize=0x400
ProjectManager.TargetToolchain=STM32CubeIDE
ProjectManager.ToolChainLocation=
ProjectManager.UAScriptAfterPath=
ProjectManager.UAScriptBeforePath=
ProjectManager.UnderRoot=true
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_FSMC_Init-FSMC-false-HAL-true,5-MX_SPI2_Init-SPI2-false-HAL-true,6-MX_TIM3_Init-TIM3-false-HAL-true,7-MX_I2C1_Init-I2C1-false-HAL-true,8-MX_SDIO_SD_Init-SDIO-false-HAL-true,9-MX_FATFS_Init-FATFS-false-HAL-false
RCC.48MHZClocksFreq_Value=48000000
RCC.AHBFreq_Value=168000000
RCC.APB1CLKDivider=RCC_HCLK_DIV4
RCC.APB1Freq_Value=42000000
RCC.APB1TimFreq_Value=84000000
RCC.APB2CLKDivider=RCC_HCLK_DIV2
RCC.APB2Freq_Value=84000000
RCC.APB2TimFreq_Value=168000000
RCC.CortexFreq_Value=168000000
RCC.EthernetFreq_Value=168000000
RCC.FCLKCortexFreq_Value=168000000
RCC.FamilyName=M
RCC.HCLKFreq_Value=168000000
RCC.HSE_VALUE=8000000
RCC.HSI_VALUE=16000000
RCC.I2SClocksFreq_Value=192000000
RCC.IPParameters=48MHZClocksFreq_Value,AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2CLKDivider,APB2Freq_Value,APB2TimFreq_Value,CortexFreq_Value,EthernetFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI_VALUE,I2SClocksFreq_Value,LSI_VALUE,MCO2PinFreq_Value,PLLCLKFreq_Value,PLLM,PLLN,PLLQ,PLLQCLKFreq_Value,RTCFreq_Value,RTCHSEDivFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,VCOI2SOutputFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VcooutputI2S
RCC.LSI_VALUE=32000
RCC.MCO2PinFreq_Value=168000000
RCC.PLLCLKFreq_Value=168000000
RCC.PLLM=8
RCC.PLLN=168
RCC.PLLQ=7
RCC.PLLQCLKFreq_Value=48000000
RCC.RTCFreq_Value=32000
RCC.RTCHSEDivFreq_Value=4000000
RCC.SYSCLKFreq_VALUE=168000000
RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
RCC.VCOI2SOutputFreq_Value=384000000
RCC.VCOInputFreq_Value=2000000
RCC.VCOOutputFreq_Value=336000000
RCC.VcooutputI2S=192000000
SPI2.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_32
SPI2.CalculateBaudRate=1.3125 MBits/s
SPI2.Direction=SPI_DIRECTION_2LINES
SPI2.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,BaudRatePrescaler
SPI2.Mode=SPI_MODE_MASTER
SPI2.VirtualType=VM_MASTER
TIM3.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE
TIM3.IPParameters=Prescaler,Period,AutoReloadPreload,TIM_MasterOutputTrigger
TIM3.Period=10-1
TIM3.Prescaler=42000-1
TIM3.TIM_MasterOutputTrigger=TIM_TRGO_RESET
VP_FATFS_VS_SDIO.Mode=SDIO
VP_FATFS_VS_SDIO.Signal=FATFS_VS_SDIO
VP_SYS_VS_Systick.Mode=SysTick
VP_SYS_VS_Systick.Signal=SYS_VS_Systick
VP_TIM3_VS_ClockSourceINT.Mode=Internal
VP_TIM3_VS_ClockSourceINT.Signal=TIM3_VS_ClockSourceINT
board=custom
isbadioc=false

沒有留言:

張貼留言