[STM32U5]【NUCLEO-U5A5ZJ-Q测评】硬件SPI驱动LCD屏

【目的】单片机的交互信息,通常是用uart输入串口信息,作为STM32U5A5,他的运行频率为160MHz,而且接口信息丰富,可以用LCD屏来做为输出信息,这样比较直观,再也不用开串口助手来观察了。本文就驱动LCD屏来做为此款开发板试用的第一篇。
【实验的硬件】

  • NUCLEO-U5A5ZJ开发板。


 


2、3.5寸SPI串口TFT液晶显示模块LCD触摸屏ILI9488 /6 /1驱动320X480
 


【实验的开发环境】

  • 操作系统:win11。
  • 开发IDE工具:STM32CubeIDE,版本为1.13.2:


 


【开发步骤】
1、新建NUCLEO-U5A5ZJ开发板工程,这样开发板可以默认的给我们配轩好了串口、LED等常用的外设。
 


2、打开spi1,配置spi1的IO为MOSI为PA7,SCK为PA5。
 


3、配置开发板上的PF2、PD14、PD15为TFT_DC、TFT_CS、TFT_RST,如下图:
 


4、配置三个IO为上拉,输入为High,如下图所示:
 


5、设置spi为单向发送,传输数据为8bit,分频为4,工作频为40M,同时NSS为软摸拟。
 


6、配置时钟为160MHz,这样spi的时钟可以达到160M。
 


7、因为ili9488要开启大的空间进行数据传输,所以把栈堆的空间调大一些。
 


随后按alt+k生成工程。
【代码】
添加ili9488.h,添加代码如下:

复制

/*

 * ili9488.h

 *

 *  Created on: Dec 14, 2021

 *      Author: timagr615

 */



#ifndef INC_ILI9488_H_

#define INC_ILI9488_H_



#include <math.h>

#include <stdbool.h>



#include "main.h"

#include <stdlib.h>

#include <stdio.h>

#include <string.h>



#define RST_A() HAL_GPIO_WritePin(TFT_RST_GPIO_Port,TFT_RST_Pin,GPIO_PIN_RESET)

#define RST_D() HAL_GPIO_WritePin(TFT_RST_GPIO_Port,TFT_RST_Pin,GPIO_PIN_SET)

#define CS_A() HAL_GPIO_WritePin(TFT_CS_GPIO_Port,TFT_CS_Pin,GPIO_PIN_RESET)

#define CS_D() HAL_GPIO_WritePin(TFT_CS_GPIO_Port,TFT_CS_Pin,GPIO_PIN_SET)

#define DC_COMMAND() HAL_GPIO_WritePin(TFT_DC_GPIO_Port,TFT_DC_Pin,GPIO_PIN_RESET)

#define DC_DATA() HAL_GPIO_WritePin(TFT_DC_GPIO_Port,TFT_DC_Pin,GPIO_PIN_SET)



#define ILI9488_TFTWIDTH  320

#define ILI9488_TFTHEIGHT 480

#define ILI9488_PIXEL_COUNT        ILI9488_TFTWIDTH * ILI9488_TFTHEIGHT



#define ILI9488_NOP     0x00

#define ILI9488_SWRESET 0x01

#define ILI9488_RDDID   0x04

#define ILI9488_RDDST   0x09



#define ILI9488_SLPIN   0x10

#define ILI9488_SLPOUT  0x11

#define ILI9488_PTLON   0x12

#define ILI9488_NORON   0x13



#define ILI9488_RDMODE  0x0A

#define ILI9488_RDMADCTL  0x0B

#define ILI9488_RDPIXFMT  0x0C

#define ILI9488_RDIMGFMT  0x0D

#define ILI9488_RDSELFDIAG  0x0F



#define ILI9488_INVOFF  0x20

#define ILI9488_INVON   0x21

#define ILI9488_GAMMASET 0x26

#define ILI9488_DISPOFF 0x28

#define ILI9488_DISPON  0x29



#define ILI9488_CASET   0x2A

#define ILI9488_PASET   0x2B

#define ILI9488_RAMWR   0x2C

#define ILI9488_RAMRD   0x2E



#define ILI9488_PTLAR   0x30

#define ILI9488_MADCTL  0x36

#define ILI9488_PIXFMT  0x3A



#define ILI9488_FRMCTR1 0xB1

#define ILI9488_FRMCTR2 0xB2

#define ILI9488_FRMCTR3 0xB3

#define ILI9488_INVCTR  0xB4

#define ILI9488_DFUNCTR 0xB6



#define ILI9488_PWCTR1  0xC0

#define ILI9488_PWCTR2  0xC1

#define ILI9488_PWCTR3  0xC2

#define ILI9488_PWCTR4  0xC3

#define ILI9488_PWCTR5  0xC4

#define ILI9488_VMCTR1  0xC5

#define ILI9488_VMCTR2  0xC7



#define ILI9488_RDID1   0xDA

#define ILI9488_RDID2   0xDB

#define ILI9488_RDID3   0xDC

#define ILI9488_RDID4   0xDD



#define ILI9488_GMCTRP1 0xE0

#define ILI9488_GMCTRN1 0xE1

/*

#define ILI9488_PWCTR6  0xFC

*/



// Color definitions

#define ILI9488_BLACK                              0x0000      /*   0,   0,   0 */

#define ILI9488_NAVY                                0x000F      /*   0,   0, 128 */

#define ILI9488_DARKGREEN                   0x03E0      /*   0, 128,   0 */

#define ILI9488_DARKCYAN                    0x03EF      /*   0, 128, 128 */

#define ILI9488_MAROON                      0x7800      /* 128,   0,   0 */

#define ILI9488_PURPLE                      0x780F      /* 128,   0, 128 */

#define ILI9488_OLIVE                               0x7BE0      /* 128, 128,   0 */

#define ILI9488_LIGHTGREY                   0xC618      /* 192, 192, 192 */

#define ILI9488_DARKGREY                    0x7BEF      /* 128, 128, 128 */

#define ILI9488_BLUE                                0x001F      /*   0,   0, 255 */

#define ILI9488_GREEN                       0x07E0      /*   0, 255,   0 */

#define ILI9488_CYAN                                0x07FF      /*   0, 255, 255 */

#define ILI9488_RED                                 0xF800      /* 255,   0,   0 */

#define ILI9488_MAGENTA                     0xF81F      /* 255,   0, 255 */

#define ILI9488_YELLOW                      0xFFE0      /* 255, 255,   0 */

#define ILI9488_WHITE                               0xFFFF      /* 255, 255, 255 */

#define ILI9488_ORANGE                      0xFD20      /* 255, 165,   0 */

#define ILI9488_GREENYELLOW         0xAFE5      /* 173, 255,  47 */

#define ILI9488_PINK                                0xF81F



#define        TFT9341_BLACK   0x0000

#define        TFT9341_BLUE    0x001F

#define        TFT9341_RED     0xF800

#define        TFT9341_GREEN   0x07E0

#define TFT9341_CYAN    0x07FF

#define TFT9341_MAGENTA 0xF81F

#define TFT9341_YELLOW  0xFFE0

#define TFT9341_WHITE   0xFFFF

#define MADCTL_MY  0x80

#define MADCTL_MX  0x40

#define MADCTL_MV  0x20

#define MADCTL_ML  0x10

#define MADCTL_RGB 0x00

#define MADCTL_BGR 0x08

#define MADCTL_MH  0x04





#define swap(a, b) { int16_t t = a; a = b; b = t; }

#define pgm_read_byte(addr) (*(const unsigned char *)(addr))

#define min(a,b) (((a)<(b))?(a):(b))



//***** Functions prototypes *****//

//1. Write Command to LCD

void ILI9341_SendCommand(uint8_t com);

//2. Write data to LCD

void ILI9341_SendData(uint8_t data);

//2.2 Write multiple/DMA

void ILI9488_SendData_Multi(uint8_t *buff, size_t buff_size);



//void ILI9488_Init(SPI_HandleTypeDef *spiLcdHandle, GPIO_TypeDef *csPORT, uint16_t csPIN, GPIO_TypeDef *dcPORT, uint16_t dcPIN, GPIO_TypeDef *resetPORT, uint16_t resetPIN);

void ILI9488_Init();

void setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);

void setScrollArea(uint16_t topFixedArea, uint16_t bottomFixedArea);

void scroll(uint16_t pixels);

void pushColor(uint16_t color);

void pushColors(uint16_t *data, uint8_t len, uint8_t first);

void drawImage(const uint8_t* img, uint16_t x, uint16_t y, uint16_t w, uint16_t h);

void fillScreen(uint16_t color);



void drawPixel(int16_t x, int16_t y, uint16_t color);

void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);

void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);

void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1,uint16_t color);

void writeLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1,uint16_t color);

void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);





void setRotation(uint8_t r);

void invertDisplay(uint8_t  i);

uint16_t color565(uint8_t r, uint8_t g, uint8_t b);

void drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size);

void ILI9488_printText(char text[], int16_t x, int16_t y, uint16_t color, uint16_t bg, uint8_t size);



void write16BitColor(uint16_t color);



void testLines(uint8_t color);







#endif /* INC_ILI9488_H_ */



2、添加ili9488.c代码如下:

复制

/*

 * ili9488.c

 *

 *  Created on: Nov 12, 2023

 *      Author: liujianhua

 */



#include "ili9488.h"

#include "FONT.H"

extern SPI_HandleTypeDef hspi1;

extern UART_HandleTypeDef huart1;



static uint8_t rotationNum=1;

static bool _cp437    = false;

static SPI_HandleTypeDef lcdSPIhandle;

//Chip Select pin

static GPIO_TypeDef  *tftCS_GPIO;

static uint16_t tftCS_PIN;

//Data Command pin

static GPIO_TypeDef  *tftDC_GPIO;

static uint16_t tftDC_PIN;

//Reset pin

static GPIO_TypeDef  *tftRESET_GPIO;

static uint16_t tftRESET_PIN;

//uint8_t frm_buf[65536] = {0};

uint16_t width;

uint16_t height;



static //Text simple font array (You can your own font)

const unsigned char font1[] = {

        0x00, 0x00, 0x00, 0x00, 0x00,

        0x3E, 0x5B, 0x4F, 0x5B, 0x3E,

        0x3E, 0x6B, 0x4F, 0x6B, 0x3E,

        0x1C, 0x3E, 0x7C, 0x3E, 0x1C,

        0x18, 0x3C, 0x7E, 0x3C, 0x18,

        0x1C, 0x57, 0x7D, 0x57, 0x1C,

        0x1C, 0x5E, 0x7F, 0x5E, 0x1C,

        0x00, 0x18, 0x3C, 0x18, 0x00,

        0xFF, 0xE7, 0xC3, 0xE7, 0xFF,

        0x00, 0x18, 0x24, 0x18, 0x00,

        0xFF, 0xE7, 0xDB, 0xE7, 0xFF,

        0x30, 0x48, 0x3A, 0x06, 0x0E,

        0x26, 0x29, 0x79, 0x29, 0x26,

        0x40, 0x7F, 0x05, 0x05, 0x07,

        0x40, 0x7F, 0x05, 0x25, 0x3F,

        0x5A, 0x3C, 0xE7, 0x3C, 0x5A,

        0x7F, 0x3E, 0x1C, 0x1C, 0x08,

        0x08, 0x1C, 0x1C, 0x3E, 0x7F,

        0x14, 0x22, 0x7F, 0x22, 0x14,

        0x5F, 0x5F, 0x00, 0x5F, 0x5F,

        0x06, 0x09, 0x7F, 0x01, 0x7F,

        0x00, 0x66, 0x89, 0x95, 0x6A,

        0x60, 0x60, 0x60, 0x60, 0x60,

        0x94, 0xA2, 0xFF, 0xA2, 0x94,

        0x08, 0x04, 0x7E, 0x04, 0x08,

        0x10, 0x20, 0x7E, 0x20, 0x10,

        0x08, 0x08, 0x2A, 0x1C, 0x08,

        0x08, 0x1C, 0x2A, 0x08, 0x08,

        0x1E, 0x10, 0x10, 0x10, 0x10,

        0x0C, 0x1E, 0x0C, 0x1E, 0x0C,

        0x30, 0x38, 0x3E, 0x38, 0x30,

        0x06, 0x0E, 0x3E, 0x0E, 0x06,

        0x00, 0x00, 0x00, 0x00, 0x00,

        0x00, 0x00, 0x5F, 0x00, 0x00,

        0x00, 0x07, 0x00, 0x07, 0x00,

        0x14, 0x7F, 0x14, 0x7F, 0x14,

        0x24, 0x2A, 0x7F, 0x2A, 0x12,

        0x23, 0x13, 0x08, 0x64, 0x62,

        0x36, 0x49, 0x56, 0x20, 0x50,

        0x00, 0x08, 0x07, 0x03, 0x00,

        0x00, 0x1C, 0x22, 0x41, 0x00,

        0x00, 0x41, 0x22, 0x1C, 0x00,

        0x2A, 0x1C, 0x7F, 0x1C, 0x2A,

        0x08, 0x08, 0x3E, 0x08, 0x08,

        0x00, 0x80, 0x70, 0x30, 0x00,

        0x08, 0x08, 0x08, 0x08, 0x08,

        0x00, 0x00, 0x60, 0x60, 0x00,

        0x20, 0x10, 0x08, 0x04, 0x02,

        0x3E, 0x51, 0x49, 0x45, 0x3E,

        0x00, 0x42, 0x7F, 0x40, 0x00,

        0x72, 0x49, 0x49, 0x49, 0x46,

        0x21, 0x41, 0x49, 0x4D, 0x33,

        0x18, 0x14, 0x12, 0x7F, 0x10,

        0x27, 0x45, 0x45, 0x45, 0x39,

        0x3C, 0x4A, 0x49, 0x49, 0x31,

        0x41, 0x21, 0x11, 0x09, 0x07,

        0x36, 0x49, 0x49, 0x49, 0x36,

        0x46, 0x49, 0x49, 0x29, 0x1E,

        0x00, 0x00, 0x14, 0x00, 0x00,

        0x00, 0x40, 0x34, 0x00, 0x00,

        0x00, 0x08, 0x14, 0x22, 0x41,

        0x14, 0x14, 0x14, 0x14, 0x14,

        0x00, 0x41, 0x22, 0x14, 0x08,

        0x02, 0x01, 0x59, 0x09, 0x06,

        0x3E, 0x41, 0x5D, 0x59, 0x4E,

        0x7C, 0x12, 0x11, 0x12, 0x7C,

        0x7F, 0x49, 0x49, 0x49, 0x36,

        0x3E, 0x41, 0x41, 0x41, 0x22,

        0x7F, 0x41, 0x41, 0x41, 0x3E,

        0x7F, 0x49, 0x49, 0x49, 0x41,

        0x7F, 0x09, 0x09, 0x09, 0x01,

        0x3E, 0x41, 0x41, 0x51, 0x73,

        0x7F, 0x08, 0x08, 0x08, 0x7F,

        0x00, 0x41, 0x7F, 0x41, 0x00,

        0x20, 0x40, 0x41, 0x3F, 0x01,

        0x7F, 0x08, 0x14, 0x22, 0x41,

        0x7F, 0x40, 0x40, 0x40, 0x40,

        0x7F, 0x02, 0x1C, 0x02, 0x7F,

        0x7F, 0x04, 0x08, 0x10, 0x7F,

        0x3E, 0x41, 0x41, 0x41, 0x3E,

        0x7F, 0x09, 0x09, 0x09, 0x06,

        0x3E, 0x41, 0x51, 0x21, 0x5E,

        0x7F, 0x09, 0x19, 0x29, 0x46,

        0x26, 0x49, 0x49, 0x49, 0x32,

        0x03, 0x01, 0x7F, 0x01, 0x03,

        0x3F, 0x40, 0x40, 0x40, 0x3F,

        0x1F, 0x20, 0x40, 0x20, 0x1F,

        0x3F, 0x40, 0x38, 0x40, 0x3F,

        0x63, 0x14, 0x08, 0x14, 0x63,

        0x03, 0x04, 0x78, 0x04, 0x03,

        0x61, 0x59, 0x49, 0x4D, 0x43,

        0x00, 0x7F, 0x41, 0x41, 0x41,

        0x02, 0x04, 0x08, 0x10, 0x20,

        0x00, 0x41, 0x41, 0x41, 0x7F,

        0x04, 0x02, 0x01, 0x02, 0x04,

        0x40, 0x40, 0x40, 0x40, 0x40,

        0x00, 0x03, 0x07, 0x08, 0x00,

        0x20, 0x54, 0x54, 0x78, 0x40,

        0x7F, 0x28, 0x44, 0x44, 0x38,

        0x38, 0x44, 0x44, 0x44, 0x28,

        0x38, 0x44, 0x44, 0x28, 0x7F,

        0x38, 0x54, 0x54, 0x54, 0x18,

        0x00, 0x08, 0x7E, 0x09, 0x02,

        0x18, 0xA4, 0xA4, 0x9C, 0x78,

        0x7F, 0x08, 0x04, 0x04, 0x78,

        0x00, 0x44, 0x7D, 0x40, 0x00,

        0x20, 0x40, 0x40, 0x3D, 0x00,

        0x7F, 0x10, 0x28, 0x44, 0x00,

        0x00, 0x41, 0x7F, 0x40, 0x00,

        0x7C, 0x04, 0x78, 0x04, 0x78,

        0x7C, 0x08, 0x04, 0x04, 0x78,

        0x38, 0x44, 0x44, 0x44, 0x38,

        0xFC, 0x18, 0x24, 0x24, 0x18,

        0x18, 0x24, 0x24, 0x18, 0xFC,

        0x7C, 0x08, 0x04, 0x04, 0x08,

        0x48, 0x54, 0x54, 0x54, 0x24,

        0x04, 0x04, 0x3F, 0x44, 0x24,

        0x3C, 0x40, 0x40, 0x20, 0x7C,

        0x1C, 0x20, 0x40, 0x20, 0x1C,

        0x3C, 0x40, 0x30, 0x40, 0x3C,

        0x44, 0x28, 0x10, 0x28, 0x44,

        0x4C, 0x90, 0x90, 0x90, 0x7C,

        0x44, 0x64, 0x54, 0x4C, 0x44,

        0x00, 0x08, 0x36, 0x41, 0x00,

        0x00, 0x00, 0x77, 0x00, 0x00,

        0x00, 0x41, 0x36, 0x08, 0x00,

        0x02, 0x01, 0x02, 0x04, 0x02,

        0x3C, 0x26, 0x23, 0x26, 0x3C,

        0x1E, 0xA1, 0xA1, 0x61, 0x12,

        0x3A, 0x40, 0x40, 0x20, 0x7A,

        0x38, 0x54, 0x54, 0x55, 0x59,

        0x21, 0x55, 0x55, 0x79, 0x41,

        0x22, 0x54, 0x54, 0x78, 0x42,

        0x21, 0x55, 0x54, 0x78, 0x40,

        0x20, 0x54, 0x55, 0x79, 0x40,

        0x0C, 0x1E, 0x52, 0x72, 0x12,

        0x39, 0x55, 0x55, 0x55, 0x59,

        0x39, 0x54, 0x54, 0x54, 0x59,

        0x39, 0x55, 0x54, 0x54, 0x58,

        0x00, 0x00, 0x45, 0x7C, 0x41,

        0x00, 0x02, 0x45, 0x7D, 0x42,

        0x00, 0x01, 0x45, 0x7C, 0x40,

        0x7D, 0x12, 0x11, 0x12, 0x7D,

        0xF0, 0x28, 0x25, 0x28, 0xF0,

        0x7C, 0x54, 0x55, 0x45, 0x00,

        0x20, 0x54, 0x54, 0x7C, 0x54,

        0x7C, 0x0A, 0x09, 0x7F, 0x49,

        0x32, 0x49, 0x49, 0x49, 0x32,

        0x3A, 0x44, 0x44, 0x44, 0x3A,

        0x32, 0x4A, 0x48, 0x48, 0x30,

        0x3A, 0x41, 0x41, 0x21, 0x7A,

        0x3A, 0x42, 0x40, 0x20, 0x78,

        0x00, 0x9D, 0xA0, 0xA0, 0x7D,

        0x3D, 0x42, 0x42, 0x42, 0x3D,

        0x3D, 0x40, 0x40, 0x40, 0x3D,

        0x3C, 0x24, 0xFF, 0x24, 0x24,

        0x48, 0x7E, 0x49, 0x43, 0x66,

        0x2B, 0x2F, 0xFC, 0x2F, 0x2B,

        0xFF, 0x09, 0x29, 0xF6, 0x20,

        0xC0, 0x88, 0x7E, 0x09, 0x03,

        0x20, 0x54, 0x54, 0x79, 0x41,

        0x00, 0x00, 0x44, 0x7D, 0x41,

        0x30, 0x48, 0x48, 0x4A, 0x32,

        0x38, 0x40, 0x40, 0x22, 0x7A,

        0x00, 0x7A, 0x0A, 0x0A, 0x72,

        0x7D, 0x0D, 0x19, 0x31, 0x7D,

        0x26, 0x29, 0x29, 0x2F, 0x28,

        0x26, 0x29, 0x29, 0x29, 0x26,

        0x30, 0x48, 0x4D, 0x40, 0x20,

        0x38, 0x08, 0x08, 0x08, 0x08,

        0x08, 0x08, 0x08, 0x08, 0x38,

        0x2F, 0x10, 0xC8, 0xAC, 0xBA,

        0x2F, 0x10, 0x28, 0x34, 0xFA,

        0x00, 0x00, 0x7B, 0x00, 0x00,

        0x08, 0x14, 0x2A, 0x14, 0x22,

        0x22, 0x14, 0x2A, 0x14, 0x08,

        0x55, 0x00, 0x55, 0x00, 0x55,

        0xAA, 0x55, 0xAA, 0x55, 0xAA,

        0xFF, 0x55, 0xFF, 0x55, 0xFF,

        0x00, 0x00, 0x00, 0xFF, 0x00,

        0x10, 0x10, 0x10, 0xFF, 0x00,

        0x14, 0x14, 0x14, 0xFF, 0x00,

        0x10, 0x10, 0xFF, 0x00, 0xFF,

        0x10, 0x10, 0xF0, 0x10, 0xF0,

        0x14, 0x14, 0x14, 0xFC, 0x00,

        0x14, 0x14, 0xF7, 0x00, 0xFF,

        0x00, 0x00, 0xFF, 0x00, 0xFF,

        0x14, 0x14, 0xF4, 0x04, 0xFC,

        0x14, 0x14, 0x17, 0x10, 0x1F,

        0x10, 0x10, 0x1F, 0x10, 0x1F,

        0x14, 0x14, 0x14, 0x1F, 0x00,

        0x10, 0x10, 0x10, 0xF0, 0x00,

        0x00, 0x00, 0x00, 0x1F, 0x10,

        0x10, 0x10, 0x10, 0x1F, 0x10,

        0x10, 0x10, 0x10, 0xF0, 0x10,

        0x00, 0x00, 0x00, 0xFF, 0x10,

        0x10, 0x10, 0x10, 0x10, 0x10,

        0x10, 0x10, 0x10, 0xFF, 0x10,

        0x00, 0x00, 0x00, 0xFF, 0x14,

        0x00, 0x00, 0xFF, 0x00, 0xFF,

        0x00, 0x00, 0x1F, 0x10, 0x17,

        0x00, 0x00, 0xFC, 0x04, 0xF4,

        0x14, 0x14, 0x17, 0x10, 0x17,

        0x14, 0x14, 0xF4, 0x04, 0xF4,

        0x00, 0x00, 0xFF, 0x00, 0xF7,

        0x14, 0x14, 0x14, 0x14, 0x14,

        0x14, 0x14, 0xF7, 0x00, 0xF7,

        0x14, 0x14, 0x14, 0x17, 0x14,

        0x10, 0x10, 0x1F, 0x10, 0x1F,

        0x14, 0x14, 0x14, 0xF4, 0x14,

        0x10, 0x10, 0xF0, 0x10, 0xF0,

        0x00, 0x00, 0x1F, 0x10, 0x1F,

        0x00, 0x00, 0x00, 0x1F, 0x14,

        0x00, 0x00, 0x00, 0xFC, 0x14,

        0x00, 0x00, 0xF0, 0x10, 0xF0,

        0x10, 0x10, 0xFF, 0x10, 0xFF,

        0x14, 0x14, 0x14, 0xFF, 0x14,

        0x10, 0x10, 0x10, 0x1F, 0x00,

        0x00, 0x00, 0x00, 0xF0, 0x10,

        0xFF, 0xFF, 0xFF, 0xFF, 0xFF,

        0xF0, 0xF0, 0xF0, 0xF0, 0xF0,

        0xFF, 0xFF, 0xFF, 0x00, 0x00,

        0x00, 0x00, 0x00, 0xFF, 0xFF,

        0x0F, 0x0F, 0x0F, 0x0F, 0x0F,

        0x38, 0x44, 0x44, 0x38, 0x44,

        0xFC, 0x4A, 0x4A, 0x4A, 0x34,

        0x7E, 0x02, 0x02, 0x06, 0x06,

        0x02, 0x7E, 0x02, 0x7E, 0x02,

        0x63, 0x55, 0x49, 0x41, 0x63,

        0x38, 0x44, 0x44, 0x3C, 0x04,

        0x40, 0x7E, 0x20, 0x1E, 0x20,

        0x06, 0x02, 0x7E, 0x02, 0x02,

        0x99, 0xA5, 0xE7, 0xA5, 0x99,

        0x1C, 0x2A, 0x49, 0x2A, 0x1C,

        0x4C, 0x72, 0x01, 0x72, 0x4C,

        0x30, 0x4A, 0x4D, 0x4D, 0x30,

        0x30, 0x48, 0x78, 0x48, 0x30,

        0xBC, 0x62, 0x5A, 0x46, 0x3D,

        0x3E, 0x49, 0x49, 0x49, 0x00,

        0x7E, 0x01, 0x01, 0x01, 0x7E,

        0x2A, 0x2A, 0x2A, 0x2A, 0x2A,

        0x44, 0x44, 0x5F, 0x44, 0x44,

        0x40, 0x51, 0x4A, 0x44, 0x40,

        0x40, 0x44, 0x4A, 0x51, 0x40,

        0x00, 0x00, 0xFF, 0x01, 0x03,

        0xE0, 0x80, 0xFF, 0x00, 0x00,

        0x08, 0x08, 0x6B, 0x6B, 0x08,

        0x36, 0x12, 0x36, 0x24, 0x36,

        0x06, 0x0F, 0x09, 0x0F, 0x06,

        0x00, 0x00, 0x18, 0x18, 0x00,

        0x00, 0x00, 0x10, 0x10, 0x00,

        0x30, 0x40, 0xFF, 0x01, 0x01,

        0x00, 0x1F, 0x01, 0x01, 0x1E,

        0x00, 0x19, 0x1D, 0x17, 0x12,

        0x00, 0x3C, 0x3C, 0x3C, 0x3C,

        0x00, 0x00, 0x00, 0x00, 0x00

};

//***** Functions prototypes *****//





//1. Write Command to LCD

void ILI9488_SendCommand(uint8_t com)

{

        //*(__IO uint8_t *)(0x60000000) = com;

        uint8_t tmpCmd = com;



        DC_COMMAND();



        CS_A();

        //Write byte using SPI

        HAL_SPI_Transmit(&hspi1, &tmpCmd, 1, 1);



        CS_D();



}



//2. Write data to LCD

void ILI9488_SendData(uint8_t data)

{

        uint8_t tmpCmd = data;

        DC_DATA();

        CS_A();

        HAL_SPI_Transmit(&hspi1, &tmpCmd, 1, 1);

        CS_D();



}

//2.2 Write multiple/DMA

void ILI9488_SendData_Multi(uint8_t *buff, size_t buff_size){

        DC_DATA();

        CS_A();

        while (buff_size > 0){

                uint16_t chunk_size = buff_size > 32768 ? 32768 : buff_size;

                HAL_SPI_Transmit(&hspi1, buff, chunk_size, HAL_MAX_DELAY);

                buff += chunk_size;

                buff_size -= chunk_size;

        }

        CS_D();

}





void ILI9488_Init()

{



        CS_D();

        RST_A();

        HAL_Delay(10);

        RST_D();

         width=ILI9488_TFTWIDTH;

         height=ILI9488_TFTHEIGHT;

         //CS_A();

         ILI9488_SendCommand(0xE0);

         ILI9488_SendData(0x00);

         ILI9488_SendData(0x03);

         ILI9488_SendData(0x09);

         ILI9488_SendData(0x08);

         ILI9488_SendData(0x16);

         ILI9488_SendData(0x0A);

         ILI9488_SendData(0x3F);

         ILI9488_SendData(0x78);

         ILI9488_SendData(0x4C);

         ILI9488_SendData(0x09);

         ILI9488_SendData(0x0A);

         ILI9488_SendData(0x08);

         ILI9488_SendData(0x16);

         ILI9488_SendData(0x1A);

         ILI9488_SendData(0x0F);



                 ILI9488_SendCommand(0XE1);

                 ILI9488_SendData(0x00);

                 ILI9488_SendData(0x16);

                 ILI9488_SendData(0x19);

                 ILI9488_SendData(0x03);

                 ILI9488_SendData(0x0F);

                 ILI9488_SendData(0x05);

                 ILI9488_SendData(0x32);

                 ILI9488_SendData(0x45);

                 ILI9488_SendData(0x46);

                 ILI9488_SendData(0x04);

                 ILI9488_SendData(0x0E);

                 ILI9488_SendData(0x0D);

                 ILI9488_SendData(0x35);

                 ILI9488_SendData(0x37);

                 ILI9488_SendData(0x0F);



                 ILI9488_SendCommand(0XC0);      //Power Control 1

                 ILI9488_SendData(0x17);    //Vreg1out

                 ILI9488_SendData(0x15);    //Verg2out



                 ILI9488_SendCommand(0xC1);      //Power Control 2

                 ILI9488_SendData(0x41);    //VGH,VGL



                 ILI9488_SendCommand(0xC5);      //Power Control 3

                 ILI9488_SendData(0x00);

                 ILI9488_SendData(0x12);    //Vcom

                 ILI9488_SendData(0x80);



                 ILI9488_SendCommand(0x36);      //Memory Access

                 ILI9488_SendData(0x48);



                 ILI9488_SendCommand(0x3A);      // Interface Pixel Format

                 ILI9488_SendData(0x66);           //18 bit



                 ILI9488_SendCommand(0XB0);      // Interface Mode Control

                 ILI9488_SendData(0x80);                              //SDO NOT USE



                 ILI9488_SendCommand(0xB1);      //Frame rate

                 ILI9488_SendData(0xA0);    //60Hz



                 ILI9488_SendCommand(0xB4);      //Display Inversion Control

                 ILI9488_SendData(0x02);    //2-dot



                 ILI9488_SendCommand(0XB6); //Display Function Control  RGB/MCU Interface Control



                 ILI9488_SendData(0x02);    //MCU

                 ILI9488_SendData(0x02);    //Source,Gate scan dieection



                 ILI9488_SendCommand(0XE9);      // Set Image Functio

                 ILI9488_SendData(0x00);    // Disable 24 bit data



                 ILI9488_SendCommand(0xF7);      // Adjust Control

                 ILI9488_SendData(0xA9);

                 ILI9488_SendData(0x51);

                 ILI9488_SendData(0x2C);

                 ILI9488_SendData(0x82);    // D7 stream, loose



                 ILI9488_SendCommand(ILI9488_SLPOUT);    //Exit Sleep



                 HAL_Delay(120);



                 ILI9488_SendCommand(ILI9488_DISPON);    //Display on



}



void setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)

{

        /*ILI9488_SendCommand(ILI9488_CASET); // Column addr set

        ILI9488_SendData(x0 >> 8);

        ILI9488_SendData(x0 & 0xFF);     // XSTART

        ILI9488_SendData(x1 >> 8);

        ILI9488_SendData(x1 & 0xFF);     // XEND

        ILI9488_SendCommand(ILI9488_PASET); // Row addr set

        ILI9488_SendData(y0 >> 8);

        ILI9488_SendData(y0 & 0xff);     // YSTART

        ILI9488_SendData(y1 >> 8);

        ILI9488_SendData(y1 & 0xff);     // YEND

        ILI9488_SendCommand(ILI9488_RAMWR); // write to RAM*/

        ILI9488_SendCommand(ILI9488_CASET); // Column addr set

                {

                uint8_t data[] = {(x0 >> 8) & 0xFF, x0 & 0xFF, (x1 >> 8) & 0xFF, x1 & 0xFF};

                ILI9488_SendData_Multi(data, sizeof(data));

                }

                ILI9488_SendCommand(ILI9488_PASET);

                {

                uint8_t data[] = {(y0 >> 8) & 0xFF, y0 & 0xFF, (y1 >> 8) & 0xFF, y1 & 0xFF};

                ILI9488_SendData_Multi(data, sizeof(data));

                }

                ILI9488_SendCommand(ILI9488_RAMWR); // write to RAM*/

}



void setScrollArea(uint16_t topFixedArea, uint16_t bottomFixedArea)

{

        ILI9488_SendCommand(0x33); // Vertical scroll definition

        ILI9488_SendData(topFixedArea >> 8);

        ILI9488_SendData(topFixedArea);

        ILI9488_SendData((height - topFixedArea - bottomFixedArea) >> 8);

        ILI9488_SendData(height - topFixedArea - bottomFixedArea);

        ILI9488_SendData(bottomFixedArea >> 8);

        ILI9488_SendData(bottomFixedArea);

}



void scroll(uint16_t pixels)

{

        ILI9488_SendCommand(0x37); // Vertical scrolling start address

        ILI9488_SendData(pixels >> 8);

        ILI9488_SendData(pixels);

}

void pushColor(uint16_t color)

{

        HAL_GPIO_WritePin(tftDC_GPIO, tftDC_PIN, GPIO_PIN_SET);

        HAL_GPIO_WritePin(tftCS_GPIO, tftCS_PIN, GPIO_PIN_RESET);

        write16BitColor(color);

        HAL_GPIO_WritePin(tftCS_GPIO, tftCS_PIN, GPIO_PIN_SET);



}



void pushColors(uint16_t *data, uint8_t len, uint8_t first)

{

        uint16_t color;

        uint8_t buff[len * 3 + 1];

        uint16_t count = 0;

        uint8_t lencount = len;

        HAL_GPIO_WritePin(tftCS_GPIO, tftCS_PIN, GPIO_PIN_RESET);



        if (first == 1) {

                HAL_GPIO_WritePin(tftDC_GPIO, tftDC_PIN, GPIO_PIN_SET);

        }

        while (lencount--)

        {

                color = *data++;

                buff[count] = (((color & 0xF800) >> 11) * 255) / 31;

                count++;

                buff[count] = (((color & 0x07E0) >> 5) * 255) / 63;

                count++;

                buff[count] = ((color & 0x001F) * 255) / 31;

                count++;

        }

        HAL_SPI_Transmit(&lcdSPIhandle, buff, len * 3, 100);

        HAL_GPIO_WritePin(tftCS_GPIO, tftCS_PIN, GPIO_PIN_SET);

}



void drawImage(const uint8_t* img, uint16_t x, uint16_t y, uint16_t w, uint16_t h)

{



        if ((x >= width) || (y >= height))

                return;

        if ((x + w - 1) >= width)

                w = width - x;

        if ((y + h - 1) >= height)

                h = height - y;

        setAddrWindow(x, y, x + w - 1, y + h - 1);

        DC_DATA();

        CS_A();

        //HAL_GPIO_WritePin(tftDC_GPIO, tftDC_PIN, GPIO_PIN_SET);

        //HAL_GPIO_WritePin(tftCS_GPIO, tftCS_PIN, GPIO_PIN_RESET);



        uint8_t linebuff[w * 3 + 1];

        uint32_t count = 0;

        for (uint16_t i = 0; i < h; i++) {

                uint16_t pixcount = 0;

                for (uint16_t o = 0; o < w; o++) {

                        uint8_t b1 = img[count];

                        count++;

                        uint8_t b2 = img[count];

                        count++;

                        uint16_t color = b1 << 8 | b2;

                        linebuff[pixcount] = (((color & 0xF800) >> 11) * 255)

                                        / 31;

                        pixcount++;

                        linebuff[pixcount] = (((color & 0x07E0) >> 5) * 255)

                                        / 63;

                        pixcount++;

                        linebuff[pixcount] = ((color & 0x001F) * 255) / 31;

                        pixcount++;

                }

                HAL_SPI_Transmit(&lcdSPIhandle, linebuff, w * 3, 100);



        }

        CS_D();

        //HAL_GPIO_WritePin(tftCS_GPIO, tftCS_PIN, GPIO_PIN_SET);

}





void drawPixel(int16_t x, int16_t y, uint16_t color)

{

        if ((x < 0) || (x >= width) || (y < 0) || (y >= height))

                return;



        setAddrWindow(x, y, x + 1, y + 1);

        DC_DATA();

        CS_A();



        write16BitColor(color);

        CS_D();



}



void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color)

{



        if ((x >= width) || (y >= height))

                return;



        if ((y + h - 1) >= height)

                h = height - y;



        setAddrWindow(x, y, x, y + h - 1);

        DC_DATA();

        CS_A();

        //HAL_GPIO_WritePin(tftDC_GPIO, tftDC_PIN, GPIO_PIN_SET);

        //HAL_GPIO_WritePin(tftCS_GPIO, tftCS_PIN, GPIO_PIN_RESET);



        while (h--) {

                write16BitColor(color);

        }

        CS_D();

        //HAL_GPIO_WritePin(tftCS_GPIO, tftCS_PIN, GPIO_PIN_SET);



}



void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color)

{



        if ((x >= width) || (y >= height))

                return;

        if ((x + w - 1) >= width)

                w = width - x;

        setAddrWindow(x, y, x + w - 1, y);

        DC_DATA();

        CS_A();

        //HAL_GPIO_WritePin(tftDC_GPIO, tftDC_PIN, GPIO_PIN_SET);

        //HAL_GPIO_WritePin(tftCS_GPIO, tftCS_PIN, GPIO_PIN_RESET);

        while (w--)

        {

                write16BitColor(color);

        }

        CS_D();

        //HAL_GPIO_WritePin(tftCS_GPIO, tftCS_PIN, GPIO_PIN_SET);

}



void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color)

{

         if (x0 == x1) {

            if (y0 > y1)

              swap(y0, y1);

            drawFastVLine(x0, y0, y1 - y0 + 1, color);

          } else if (y0 == y1) {

            if (x0 > x1)

              swap(x0, x1);

            drawFastHLine(x0, y0, x1 - x0 + 1, color);

          } else {



            writeLine(x0, y0, x1, y1, color);



          }



}



void writeLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color) {



  int16_t steep = abs(y1 - y0) > abs(x1 - x0);

  if (steep) {

    swap(x0, y0);

    swap(x1, y1);

  }



  if (x0 > x1) {

          swap(x0, x1);

          swap(y0, y1);

  }



  int16_t dx, dy;

  dx = x1 - x0;

  dy = abs(y1 - y0);



  int16_t err = dx / 2;

  int16_t ystep;



  if (y0 < y1) {

    ystep = 1;

  } else {

    ystep = -1;

  }



  for (; x0 <= x1; x0++) {

    if (steep) {

      drawPixel(y0, x0, color);

    } else {

      drawPixel(x0, y0, color);

    }

    err -= dy;

    if (err < 0) {

      y0 += ystep;

      err += dx;

    }

  }

}

//6. Fill the entire screen with a background color



void fillScreen(uint16_t color)

{

        fillRect(0, 0,  width, height, color);

}



void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)

{



        uint32_t i, n, cnt, buf_size;

        if ((x >= width) || (y >= height))

                return;

        if ((x + w - 1) >= width)

                w = width - x;

        if ((y + h - 1) >= height)

                h = height - y;

        setAddrWindow(x, y, x + w - 1, y + h - 1);

        uint8_t r = (color & 0xF800) >> 11;

        uint8_t g = (color & 0x07E0) >> 5;

        uint8_t b = color & 0x001F;



        r = (r * 255) / 31;

        g = (g * 255) / 63;

        b = (b * 255) / 31;



        n = w*h*3;

        if (n <= 65535){

                cnt = 1;

                buf_size = n;

        }

        else {

                cnt = n/3;

                buf_size = 3;

                uint8_t min_cnt = n/65535+1;

                for (i=min_cnt; i < n/3; i++){

                        if(n%i == 0){

                                cnt = i;

                                buf_size = n/i;

                                break;

                        }

                }

        }

        uint8_t frm_buf[buf_size];

        for (i=0; i < buf_size/3; i++)

        {

                frm_buf[i*3] = r;

                frm_buf[i*3+1] = g;

                frm_buf[i*3+2] = b;

        }

        DC_DATA();

        CS_A();

                while(cnt>0)

                {

                        HAL_SPI_Transmit(&hspi1, frm_buf, buf_size, HAL_MAX_DELAY);



                        cnt -= 1;

                }

                CS_D();



}





void setRotation(uint8_t r)

{



        ILI9488_SendCommand(ILI9488_MADCTL);

        uint8_t rotation = r % 4; // can't be higher than 3

        switch (rotation) {

        case 0:

                ILI9488_SendData(MADCTL_MX | MADCTL_BGR);

                width = ILI9488_TFTWIDTH;

                height = ILI9488_TFTHEIGHT;

                break;

        case 1:

                ILI9488_SendData(MADCTL_MV | MADCTL_BGR);

                width = ILI9488_TFTHEIGHT;

                height = ILI9488_TFTWIDTH;

                break;

        case 2:

                ILI9488_SendData(MADCTL_MY | MADCTL_BGR);

                width = ILI9488_TFTWIDTH;

                height = ILI9488_TFTHEIGHT;

                break;

        case 3:

                ILI9488_SendData(MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_BGR);

                width = ILI9488_TFTHEIGHT;

                height = ILI9488_TFTWIDTH;

                break;

        }



}



void invertDisplay(uint8_t i)

{



        ILI9488_SendCommand(i ? ILI9488_INVON : ILI9488_INVOFF);



}

uint16_t color565(uint8_t r, uint8_t g, uint8_t b)

{

        return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);

}



//11. Text printing functions

void drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size)

{

        uint8_t font_size;

        font_size = size;

        if(rotationNum == 1 || rotationNum ==3)

        {

                if((x >= ILI9488_TFTWIDTH)            || // Clip right

     (y >= ILI9488_TFTHEIGHT)           || // Clip bottom

     ((x + 6 * font_size - 1) < 0) || // Clip left

     ((y + 8 * font_size - 1) < 0))   // Clip top

    return;

        }

        else

        {

                if((y >= ILI9488_TFTWIDTH)            || // Clip right

     (x >= ILI9488_TFTHEIGHT)           || // Clip bottom

     ((y + 6 * font_size - 1) < 0) || // Clip left

     ((x + 8 * font_size - 1) < 0))   // Clip top

    return;

        }





  if(!_cp437 && (c >= 176)) c++; // Handle 'classic' charset behavior



  for (int8_t i=0; i<6; i++ ) {

    uint8_t line;

    if (i == 5)

      line = 0x0;

    else

      line = pgm_read_byte(font1+(c*5)+i);

    for (int8_t j = 0; j<8; j++) {

      if (line & 0x1) {

        if (font_size == 1) // default size

                drawPixel(x+i, y+j, color);

        else {  // big size

                fillRect(x+(i*font_size), y+(j*font_size), font_size, font_size, color);

        }

      } else if (bg != color) {

        if (font_size == 1) // default size

                drawPixel(x+i, y+j, bg);

        else {  // big size

                fillRect(x+(i*font_size), y+(j*font_size), font_size, font_size, bg);

        }

      }

      line >>= 1;

    }

  }

}

void ILI9488_printText(char text[], int16_t x, int16_t y, uint16_t color, uint16_t bg, uint8_t size)

{

        int16_t offset;

        offset = size*6;



        for(uint16_t i=0; i<40 && text[i]!=NULL; i++)

        {

                drawChar(x+(offset*i), y, text[i],color,bg,size);

        }

}

void testLines(uint8_t color)

{



        unsigned long start, t;

        int x1, y1, x2, y2, w = width, h = height;

        fillScreen(ILI9488_BLACK);



        x1 = y1 = 0;

        y2 = h - 1;



        for (x2 = 0; x2 < w; x2 += 6)

                drawLine(x1, y1, x2, y2, color);

        x2 = w - 1;

        for (y2 = 0; y2 < h; y2 += 6)

                drawLine(x1, y1, x2, y2, color);

        fillScreen(ILI9488_BLACK);



        x1 = w - 1;

        y1 = 0;

        y2 = h - 1;



        for (x2 = 0; x2 < w; x2 += 6)

                drawLine(x1, y1, x2, y2, color);

        x2 = 0;

        for (y2 = 0; y2 < h; y2 += 6)

                drawLine(x1, y1, x2, y2, color);



        fillScreen(ILI9488_BLACK);



        x1 = 0;

        y1 = h - 1;

        y2 = 0;



        for (x2 = 0; x2 < w; x2 += 6)

                drawLine(x1, y1, x2, y2, color);

        x2 = w - 1;

        for (y2 = 0; y2 < h; y2 += 6)

                drawLine(x1, y1, x2, y2, color);



        fillScreen(ILI9488_BLACK);



        x1 = w - 1;

        y1 = h - 1;

        y2 = 0;



        for (x2 = 0; x2 < w; x2 += 6)

                drawLine(x1, y1, x2, y2, color);

        x2 = 0;

        for (y2 = 0; y2 < h; y2 += 6)

                drawLine(x1, y1, x2, y2, color);

}



void write16BitColor(uint16_t color)

{



          uint8_t r = (color & 0xF800) >> 11;

          uint8_t g = (color & 0x07E0) >> 5;

          uint8_t b = color & 0x001F;



          r = (r * 255) / 31;

          g = (g * 255) / 63;

          b = (b * 255) / 31;

          uint8_t data[3] = {r, g, b};

          ILI9488_SendData_Multi(data, 3);

          //HAL_SPI_Transmit(&hspi1, (uint8_t *)&r, 1, 10);

          //HAL_SPI_Transmit(&hspi1, (uint8_t *)&g, 1, 10);

          //HAL_SPI_Transmit(&hspi1, (uint8_t *)&b, 1, 10);



}








3、添加测试函数如下:

复制

  /* USER CODE BEGIN 2 */

  ILI9488_Init();





    HAL_Delay(1000);

    setRotation(0);

    char badmpu[] = "HELLO 21IC";

          fillScreen(ILI9488_BLACK);

    fillScreen(ILI9488_WHITE);

          ILI9488_printText(badmpu,10,10,ILI9488_BLACK,ILI9488_WHITE,1);

          ILI9488_printText(badmpu,10,20,ILI9488_BLUE,ILI9488_WHITE,2);

          ILI9488_printText(badmpu,10,50,ILI9488_GREEN,ILI9488_WHITE,3);

          ILI9488_printText(badmpu,10,50,ILI9488_RED,ILI9488_WHITE,4);

          testLines(ILI9488_BLUE);

  /* USER CODE END 2 */


【实验效果】
 


【总结】
1.stm32u5系列拥有高频率、大内存,运行速超级快.
2. stm32拥有超级好用的stm32CubeIDE,配置、只要运行在hal库下面的驱动,可以实现少量代码的修改后,轻松移植到不同的芯片上的工程中。
3. 在实现LCD的驱动后,我们运行ADC、PWM、UART等信息,可以实时的显示到LCD屏上,实现交互信息的方便查看等。
---------------------
作者:lulugl
链接:https://bbs.21ic.com/icview-3340004-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值