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

二、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上:
- copy lvgl中的scr資料夾與lvgl.h和lv_conf.h(由lv_conf_template.h更改檔名)檔案到專案中,並將檔案加到include paths中。
- 設定定期呼叫lv_tick_inc(x)的timer,本專案設定為5ms。
- 在main loop:定期呼叫lv_timer_handler()。
- 呼叫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
沒有留言:
張貼留言