《DMG474开发指南_V1.1》第二十章 TFT-LCD(1.3寸屏)实验

第二十章 TFT-LCD(1.3寸屏)实验


       本章我们将介绍正点原子的1.3寸TFTLCD模块,该模块采用TFT-LCD面板,可以显示16位色的真彩图片。在本章中,我们将使用开发板上的SPI接口,来点亮TFT-LCD,并实现ASCII字符和彩色显示等功能。

       本章分为如下几个小节:

       20.1 TFT-LCD简介

       20.2 硬件设计

       20.3 程序设计

       20.4 下载验证


        20.1 TFT-LCD简介

       本章我们将通过STM32G474的SPI外设来控制TFT-LCD的显示,这样我们就可以用STM32输出一些信息到显示屏上了。


       20.1.1 TFT-LCD简介

       液晶显示器,即Liquid Crystal Display,利用了液晶导电后透光性可变的特性,配合显示器光源、彩色滤光片和电压控制等工艺,最终可以在液晶阵列上显示彩色的图像。目前液晶显示技术以TN、STN、TFT三种技术为主,TFT-LCD即采用了TFT(Thin Film Transistor)技术的液晶显示器,也叫薄膜晶体管液晶显示器。

       TFT-LCD与无源TN-LCD、STN-LCD的简单矩阵不同的是,它在液晶显示屏的每一个象素上都设置有一个薄膜晶体管(TFT),可有效地克服非选通时的串扰,使显示液晶屏的静态特性与扫描线数无关,因此大大提高了图像质量。TFT式显示器具有很多优点:高响应度,高亮度,高对比度等等。TFT式屏幕的显示效果非常出色,广泛应用于手机屏幕、笔记本电脑和台式机显示器上。

       由于液晶本身不会发光,加上液晶本身的特性等原因,使得液晶屏的成像角受限,我们从屏幕的的一侧可能无法看清液晶的显示内容。液晶显示器的成像角的大小也是评估一个液晶显示器优劣的指标,目前,规格较好的液晶显示器成像角一般在120°~160°之间。

       本章我们使用的是正点原子1.3寸TFTLCD模块,它配套开发板上液晶插座,有如下特点:

       1,SPI接口,通讯简单。

       2,240×240的分辨率,显示清晰细腻。

       3,16位真彩显示。

       4,全视角。

       1.3寸TFTLCD模块的外观如图20.1.1.1所示:


图20.1.1.1 正点原子1.3寸TFTLCD外观图


       模块原理图如图20.1.1.2所示:


图20.1.1.2 正点原子TFTLCD模块原理图


       TFTLCD模块采用2*4的2.54公排针与外部连接,即图中ATK-MODOLE部分。从图20.1.1.2可以看出,正点原子TFTLCD模块采用SPI方式与外部连接。该模块与显示功能相关的信号线如表20.1.1.1所示:


表20.1.1.1 TFT-LCD接口信号线


       上述的接口线实际是对应到液晶显示控制器上的,这个芯片位于液晶屏的下方,所以我们从外观图上看不到。控制LCD显示的过程,就是按其显示驱动芯片的时序,把色彩和位置信息正确地写入对应的寄存器。


       20.1.2 液晶显示控制器

       1.3寸TFTLCD模块采用ST7789V作为LCD驱动器,LCD的显存可直接存放在ST7789V的片上RAM中,ST7789V的片上RAM有240*320*3字节,并且ST7789V会在没有外部时钟的情况下,自动将其片上RAM的数据显示至LCD上,以最小化功耗。

       在每次初始化TFTLCD模块之前,必须先通过RST引脚对TFTLCD模块进行硬件复位,硬件复位要求RST至少被拉低10微秒,拉高RST结束硬件复位后,须延时120毫秒等待复位完成后,才能够往TFTLCD模块传输数据。

       PWR引脚用于控制TFTLCD模块的LCD背光,该引脚自带下拉电阻,当PWR引脚被拉低或悬空时,TFTLCD模块的LCD背光都处于关闭状态,当PWR引脚被拉高时,TFTLCD模块的LCD背光才会点亮。

       ST7789V最高支持18位色深(262K色),但一般在TFTLCD模块上使用16位色深(65K色)的RGB565格式,这样可以在16位色深下达到最快的速度。在16位色深模式下,ST7789V采用RGB565格式传输、存储颜色数据,如下图所示:


图20.1.2.1 16位色深模式(RGB565)传输颜色数据


       如上图所示,一个像素的颜色数据需要使用16比特来传输,这16比特数据中,高5比特用于表示红色,低5比特用于表示蓝色,中间的6比特用于表示绿色。数据的数值越大,对应表示的颜色就越深。

       ST7789V支持连续读写RAM中存放的LCD上颜色对应的数据,并且连续读写的方向(LCD的扫描方向)是可以通过命令0x36进行配置的,如下图所示:


图20.1.2.2 命令0x36


       从上图中可以看出,命令0x36可以配置6个参数,但对于配置LCD的扫描方向,仅需关心MY、MX和MV这三个参数,如下表所示:


表20.1.2.1 命令0x36配置LCD扫描方向


       这样一来,就能够大大地提高TFTLCD模块在刷屏时的效率,仅需设置一次坐标,然后连续地往TFTLCD模块传输颜色数据即可。

       在往TFTLCD模块写入颜色数据前,还需要设置地址,以确定随后写入的颜色数据对应LCD上的哪一个像素,通过命令0x2A和命令0x2B可以分别设置TFTLCD模块显示颜色数据的列地址和行地址,命令0x2A的描述,如下图所示:


图20.1.2.3 命令0x2A


       命令0x2B的描述,如下图所示:


图20.1.2.4 命令0x2B


       以默认的LCD扫描方式(从左到右,从上到下)为例,命令0x2A的参数XS和XE和命令0x2B的参数YS和YE就在LCD上确定了一个区域,在连读读写颜色数据时,ST7789V就会按照从左到右,从上到下的扫描方式读写设个区域的颜色数据。


       20.1.3 模块SPI时序简介

       模块在四线SPI通讯模式下,最少仅需四根信号线(CS、SCK、SDA、WR(DC))就能够完成与TFTLCD模块的通讯,四线SPI接口时序如下图所示:


图20.1.3.1 四线SPI接口时序图


       上图中各个时间参数,如下图所示:


图20.1.3.2 四线SPI接口时序时间参数


       从上图中可以看出,TFTLCD模块四线SPI的写周期是非常快的(T SCYCW = 66ns),而读周期就相对慢了很多(T SCYCR = 150ns)。

       注意:这里只需要知道TFTLCD模块是使用SPI接口驱动即可,还不需要深入学习SPI,关于SPI的详细介绍,将在第27章展开。


        20.2 硬件设计


       1. 例程功能

       使用开发板的LCD接口(CN3)连接正点原子1.3寸TFTLCD模块,实现TFTLCD模块的显示。把LCD模块插入底板上的TFTLCD模块接口,按下复位之后,就可以看到LCD模块不停的显示一些信息并不断切换底色。LED0闪烁用于提示程序正在运行。


       2. 硬件资源


       1)LED灯

              LED0 – PE0

       2)串口1(PB6/PB7连接在板载USB转串口芯片CH340上面)

       3)正点原子1.3寸TFTLCD模块(SPI接口)


       3. 原理图

       TFTLCD模块的电路见图20.1.1.2,而开发板的LCD接口(CN3)和正点原子TFTLCD模块直接可以对插,开发板上的LCD接口如图20.2.1所示:


图20.2.1开发板LCD接口示意图


图20.2.2 TFTLCD模块与开发板的连接原理图


       在硬件上,TFTLCD模块与开发板的IO口对应关系如下:

       LCD_PWR(背光控制)对应PD8;

       LCD_CS对应PD10;

       LCD_RST对应PD9;

       LCD_WR(SPI1_MISO)对应PB4;

       LCD_SCK(SPI1_SCK)对应PB3;

       LCD_SDA(SPI1_MOSI)对应PB5;

       这些线的连接,开发板的内部已经连接好了,我们只需要将TFTLCD模块插上去就好了。


        20.3 程序设计

       LCD显示配置步骤 

       1)使能SPI时钟和配置相关引脚的复用功能

       我们通过SPI控制LCD,所以需要使能SPI以及相关GPIO口的时钟,并设置好GPIO的复用功能。

       2)SPI参数初始化(工作模式、数据时钟极性、时钟相位等)

       这里我们需要设置SPI的相关参数,以匹配液晶驱动IC。 

       3)初始化LCD

       这些初始化函数里面的代码,都是由LCD厂家提供,一般不需要改动,也不需要深究,我们直接照抄即可。

       4)实现LCD画点&读点函数

       在初始化LCD完成以后,我们就可以控制LCD显示了,而最核心的一个函数,就是画点和读点函数,只要实现这两个函数,后续的各种LCD操作函数,都可以基于这两个函数实现。

       5)实现其他LCD操作函数

       在完成画点和读点两个最基础的LCD操作函数以后,我们就可以基于这两个函数实现各种LCD操作函数了,比如画线、画矩形、显示字符、显示字符串、显示数字等,如果不够用还可以根据自己需要来添加。详见本例程源码。

       注意:这里只需要知道TFTLCD模块是使用SPI接口驱动即可,还不需要深入学习SPI,关于SPI的详细介绍,将在第27章展开。


       20.3.1 程序流程图


图20.3.1.1 TFTLCD(1.3寸屏)实验程序流程图


       20.3.2 程序解析

       1. LCD驱动代码

       这里我们只讲解核心代码,详细的源码请大家参考A盘资料对应源码。液晶(LCD)驱动源码包括3个文件:lcd.c、lcd.h和font.h。注意:本章重点讲解LCD显示相关代码,暂不分析SPI相关驱动文件,后者将在第27章展开介绍。

       lcd.c和lcd.h文件是驱动函数和引脚接口宏定义以及函数声明等,font.h头文件存放了4种字体大小不一样的ASCII字符集(12*12、16*16、24*24和32*32)。

       下面我们还是先介绍lcd.h文件,首先是LCD的引脚定义:

/* LCD引脚定义 */
#define LCD_PWR_GPIO_PORT            GPIOD
#define LCD_PWR_GPIO_PIN             GPIO_PIN_8
#define LCD_PWR_GPIO_CLK_ENABLE()  do{ __HAL_RCC_GPIOD_CLK_ENABLE(); }while(0)
 
#define LCD_RST_GPIO_PORT            GPIOD
#define LCD_RST_GPIO_PIN             GPIO_PIN_9
#define LCD_RST_GPIO_CLK_ENABLE()  do{ __HAL_RCC_GPIOD_CLK_ENABLE(); }while(0)
 
#define LCD_WR_GPIO_PORT             GPIOB
#define LCD_WR_GPIO_PIN              GPIO_PIN_4
#define LCD_WR_GPIO_CLK_ENABLE()   do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0)
 
#define LCD_CS_GPIO_PORT            GPIOD
#define LCD_CS_GPIO_PIN             GPIO_PIN_10
#define LCD_CS_GPIO_CLK_ENABLE()  do{ __HAL_RCC_GPIOD_CLK_ENABLE(); }while(0)
 
#define LCD_PWR(x)                   do{ x ? \
                                        (HAL_GPIO_WritePin(LCD_PWR_GPIO_PORT,
LCD_PWR_GPIO_PIN, GPIO_PIN_SET)):       \
                                        (HAL_GPIO_WritePin(LCD_PWR_GPIO_PORT,
LCD_PWR_GPIO_PIN, GPIO_PIN_RESET));     \
                                         }while(0)
 
#define LCD_RST(x)                   do{ x ? \
                                        (HAL_GPIO_WritePin(LCD_RST_GPIO_PORT,
LCD_RST_GPIO_PIN, GPIO_PIN_SET)):       \
                                        (HAL_GPIO_WritePin(LCD_RST_GPIO_PORT,
LCD_RST_GPIO_PIN, GPIO_PIN_RESET));     \
                                         }while(0)
 
#define LCD_WR(x)                    do{ x ? \
                                        (HAL_GPIO_WritePin(LCD_WR_GPIO_PORT,
LCD_WR_GPIO_PIN, GPIO_PIN_SET)):         \
                                        (HAL_GPIO_WritePin(LCD_WR_GPIO_PORT,
LCD_WR_GPIO_PIN,GPIO_PIN_RESET));        \
                                         }while(0)
 
#define LCD_CS(x)                    do{ x ? \
                                        (HAL_GPIO_WritePin(LCD_CS_GPIO_PORT,
LCD_CS_GPIO_PIN, GPIO_PIN_SET)):         \
                                        (HAL_GPIO_WritePin(LCD_CS_GPIO_PORT,
LCD_CS_GPIO_PIN, GPIO_PIN_RESET));       \
                                         }while(0)

       第一部分的宏定义是LCD PWR/RST/WR/CS引脚定义。

       下面介绍我们在lcd.h里面定义的一些尺寸和颜色信息:

extern uint16_t    g_point_color;        /* 默认画笔颜色 */
extern uint16_t    g_back_color;         /* 默认背景颜色 */
 
/* LCD的宽和高定义 */
#define LCD_WIDTH   240
#define LCD_HEIGHT   240
 
/* 常用画笔颜色 */
#define WHITE    0xFFFF /* 白色 */
#define BLACK    0x0000 /* 黑色 */
#define RED     0xF800 /* 红色 */
#define BLUE    0x001F /* 蓝色 */ 
#define YELLOW    0xFFE0 /* 黄色 = GREEN + RED */
#define GBLUE    0X07FF /* 青色 = GREEN + BLUE */  
#define MAGENTA    0xF81F /* 品红色/紫红色 = BLUE + RED */
#define GREEN    0x07E0 /* 绿色 */
#define CYAN    0x7FFF /* 青蓝色 */
 
/* 非常用颜色 */
#define BROWN    0XBC40 /* 棕色 */
#define BRRED    0XFC07 /* 棕红色 */
#define GRAY    0X8430 /* 灰色 */
#define DARKBLUE   0X01CF /* 深蓝色 */
#define LIGHTBLUE   0X7D7C /* 浅蓝色 */
#define GRAYBLUE   0X5458 /* 灰蓝色 */
/* 以上三色为PANEL的颜色  */
#define LIGHTGREEN   0X841F /* 浅绿色 */
#define LGRAY    0XC618 /* 浅灰色(PANNEL),窗体背景色 */
 
#define LGRAYBLUE   0XA651 /* 浅灰蓝色(中间层颜色) */
#define LBBLUE    0X2B12 /* 浅棕蓝色(选择条目的反色) */

       上述宏定义用于保存一些LCD重要参数信息,比如LCD的长宽、常用颜色和非常用颜色等。

       下面开始对lcd.c文件介绍,先看LCD初始化函数,其定义如下:

/**
 * @brief       LCD控制接口初始化
 * @param       无
 * @retval      无
 */
static void lcd_gpio_init(void)
{
    GPIO_InitTypeDef gpio_init_struct = {0};
    
    LCD_PWR_GPIO_CLK_ENABLE();
    LCD_RST_GPIO_CLK_ENABLE();
    LCD_WR_GPIO_CLK_ENABLE();
    LCD_CS_GPIO_CLK_ENABLE();
    
    gpio_init_struct.Pin = LCD_PWR_GPIO_PIN;    /* LCD_PWR引脚 */
    gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;   /* 推挽输出 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;   /* 高速 */
    gpio_init_struct.Pull = GPIO_PULLUP;     /* 上拉 */
    HAL_GPIO_Init(LCD_PWR_GPIO_PORT, &gpio_init_struct); /* 初始化LCD_PWR */
    
    gpio_init_struct.Pin = LCD_RST_GPIO_PIN;    /* LCD_RST引脚 */
    gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;   /* 推挽输出 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;   /* 高速 */
    gpio_init_struct.Pull = GPIO_PULLUP;     /* 上拉 */
    HAL_GPIO_Init(LCD_RST_GPIO_PORT, &gpio_init_struct); /* 初始化LCD_RST */
    
    gpio_init_struct.Pin = LCD_WR_GPIO_PIN;     /* LCD_WR引脚 */
    gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;   /* 推挽输出 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;   /* 高速 */
    gpio_init_struct.Pull = GPIO_PULLUP;     /* 上拉 */
    HAL_GPIO_Init(LCD_WR_GPIO_PORT, &gpio_init_struct);  /* 初始化LCD_WR */
    
    gpio_init_struct.Pin = LCD_CS_GPIO_PIN;     /* LCD_CS引脚 */
    gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;   /* 推挽输出 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;   /* 高速 */
    gpio_init_struct.Pull = GPIO_PULLUP;     /* 上拉 */
    HAL_GPIO_Init(LCD_CS_GPIO_PORT, &gpio_init_struct);  /* 初始化LCD_CS */
    
    LCD_CS(0);            /* 使能片选 */
    LCD_PWR(0);
    LCD_RST(0);
    delay_ms(120);
    LCD_RST(1);
 
    spi1_init();            /* 初始化SPI1接口 */
}

       该函数先对LCD相关IO进行初始化,然后使能片选信号,点亮背光,最后复位LCD和初始化SPI接口。

       下面是7个简单,但是很重要的函数:

/**
 * @brief       LCD底层SPI发送数据函数
 * @param       data    数据的起始地址
 * @param       size    发送数据大小
 * @retval      无
 */
static void lcd_spi_send(uint8_t *data, uint32_t size)
{
    uint32_t i;
    uint32_t delta;
    LCD_CS(0);     /* 使能片选 */
    delta = size / 0xFFFF;
    
    for (i = 0; i <= delta; i ++)
    {
        if( i == delta )   /* 发送最后一帧数据 */
        {
            spi1_write_data(&data[i * 0xFFFF], size % 0xFFFF);
        }
        Else      /* 超长数据一次发送0xFFFF字节数据 */
        {
            spi1_write_data(&data[i * 0xFFFF], 0xFFFF);
        }
    }
    LCD_CS(1);     /* 取消片选 */
}
 
/**
 * @brief       写命令到LCD
 * @param       cmd 需要发送的命令
 * @retval      无
 */
static void lcd_write_cmd(uint8_t cmd)
{
    LCD_WR(0);
    lcd_spi_send(&cmd, 1);
}
 
/**
 * @brief       写数据到LCD
 * @param       cmd 需要发送的数据
 * @retval      无
 */
static void lcd_write_data(uint8_t data)
{
    LCD_WR(1);
    lcd_spi_send(&data, 1);
}
 
/**
 * @brief       写半个字的数据到LCD
 * @param       cmd 需要发送的数据
 * @retval      无
 */
void lcd_write_halfword(const uint16_t da)
{
    uint8_t data[2] = {0};
 
    data[0] = da >> 8;
    data[1] = da;
 
    LCD_WR(1);
    lcd_spi_send(data, 2);
}
 
/**
 * @brief       设置数据写入LCD缓存区域
 * @param       x1,y1 起点坐标
 * @param       x2,y2 终点坐标
 * @retval      无
 */
void lcd_address_set(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
{
    lcd_write_cmd(0x2a);
    lcd_write_data(x1 >> 8);
    lcd_write_data(x1);
    lcd_write_data(x2 >> 8);
    lcd_write_data(x2);
 
    lcd_write_cmd(0x2b);
    lcd_write_data(y1 >> 8);
    lcd_write_data(y1);
    lcd_write_data(y2 >> 8);
    lcd_write_data(y2);
 
    lcd_write_cmd(0x2C);
}
 
/**
 * @brief       打开LCD显示
 * @param       无
 * @retval      无
 */
void lcd_display_on(void)
{
    LCD_PWR(1);
}
 
/**
 * @brief       关闭LCD显示
 * @param       无
 * @retval      无
 */
void lcd_display_off(void)
{
    LCD_PWR(0);
}

       因为SPI控制了WR信号,所以这7个函数实现起来都非常简单,我们就不多说,这些函数实现功能见函数前面的备注,通过这几个简单函数的组合,我们就可以对LCD进行各种操作了。

       下面要介绍的函数是画点函数,其定义如下:

/**
 * @brief       画点函数
 * @param       x,y 画点坐标
 * @retval      无
 */
void lcd_draw_point(uint16_t x, uint16_t y,uint16_t color)
{
    lcd_address_set(x, y, x, y);
    lcd_write_halfword(color);
}

       该函数实现比较简单,我们先设置数据写入的缓存区域,然后往该区域中写入颜色数据。lcd_draw_point函数虽然简单,但是至关重要,其他几乎所有上层函数,都是通过调用这个函数实现的。

       第九个要介绍的是字符显示函数lcd_show_char,可以以叠加方式显示,或者以非叠加方式显示。叠加方式显示多用于在显示的图片上再显示字符,非叠加方式一般用于普通的显示。该函数实现代码如下:

/**
 * @brief       显示一个字符
 * @param       x,y     显示起始坐标
 * @param       chr     需要显示的字符
 * @param       size    字体大小(支持16/24/32号字体)
 * @param       mode    叠加方式(1); 非叠加方式(0);
 * @retval      无
 */
void lcd_show_char(uint16_t x, uint16_t y, char chr, uint8_t size,
 uint8_t mode ,uint16_t color)
{
    uint8_t temp = 0,t1 = 0, t = 0;
    uint8_t *pfont = 0;
    uint8_t csize = 0;   /* 得到字体一个字符对应点阵集所占的字节数 */
    uint16_t colortemp = 0;
    uint8_t sta = 0;
 
/* 得到偏移后的值(ASCII字库是从空格开始取模,所以-' '就是对应字符的字库)*/
    chr = chr - ' '; 
 
    if ((x > (LCD_WIDTH - size / 2)) || (y > (LCD_HEIGHT - size)))
    {
        return;
    }
 
/* (x,y,x+8-1,y+16-1) */
    lcd_address_set(x, y, x + size / 2 - 1, y + size - 1); 
 
    switch (size)
    {
        case 12:
            pfont = (uint8_t *)asc2_1206[chr]; /* 调用1206字体 */
            break;
 
        case 16:
            pfont = (uint8_t *)asc2_1608[chr]; /* 调用1608字体 */
            break;
 
        case 24:
            pfont = (uint8_t *)asc2_2412[chr]; /* 调用2412字体 */
            break;
 
        case 32:
            pfont = (uint8_t *)asc2_3216[chr]; /* 调用3216字体 */
            break;
 
        default:
            return ;
    }
    
    if (size != 24)
    {
        csize = (size / 8 + ((size % 8) ? 1 : 0)) * (size / 2);
        
        for (t = 0; t < csize; t++)
        {
            temp = pfont[t];      /* 获取字符的点阵数据 */
            if(size == 12)
            {
                for(t1 = 0; t1 < 6; t1++)
                {
                    if(temp & 0x80)
                    {
                         colortemp = color;
                    }                       
                    else if (mode == 0) 
                    {
                        colortemp = g_back_color;
                    }
                    lcd_write_halfword(colortemp);
                    temp <<= 1;
                }
            }else if(size == 16 || size == 32)
            {
                for (t1 = 0; t1 < 8; t1++)
                {
                        if (temp & 0x80)
                        {
                            colortemp = color;
                        }
                        else if (mode == 0)  /* 无效点,不显示 */
                        {
                            colortemp = g_back_color;
                        }
 
                        lcd_write_halfword(colortemp);
                        temp <<= 1;
                }
            }
        }
    }
    else
    {
        csize = (size * 16) / 8;
        
        for (t = 0; t < csize; t++)
        {
            temp = asc2_2412[chr][t];
 
            if (t % 2 == 0)
            {
                sta = 8;
            }
            else
            {
                sta = 4;
            }
 
            for (t1 = 0; t1 < sta; t1++)
            {
                if(temp & 0x80)
                {
                    colortemp = color;
                }
                else if (mode == 0)    /* 无效点,不显示 */
                {
                    colortemp = g_back_color;
                }
 
                lcd_write_halfword(colortemp);
                temp <<= 1;
            }
        }
    }
}

       在lcd_show_char函数里面,我们用到了四个字符集点阵数据数组asc2_1206、asc2_1608、asc2_2412和asc2_3216。

       lcd.c的函数比较多,其他的函数请大家自行查看源码,都有详细的注释。

       2. main.c代码

       在main.c文件代码如下: 

int main(void)
{
    uint8_t x = 0;
 
    HAL_Init();                                  /* 初始化HAL库 */
    sys_stm32_clock_init(85, 2, 2, 4, 8);        /* 设置时钟,170Mhz */
    delay_init(170);                                 /* 延时初始化 */
    usart_init(115200);                             /* 串口初始化为115200 */
    led_init();                                       /* 初始化LED */
    lcd_init();                                      /* 初始化LCD */
g_point_color = RED;
 
    while (1)
    {
       switch (x)
       {
        case 0: lcd_clear(WHITE); break;
        case 1: lcd_clear(BLACK);break;
        case 2: lcd_clear(BLUE);break;
        case 3: lcd_clear(RED);break;
        case 4: lcd_clear(MAGENTA);break;
        case 5: lcd_clear(GREEN);break;
        case 6: lcd_clear(CYAN); break;
        case 7: lcd_clear(YELLOW); break;
        case 8: lcd_clear(BRRED); break;
        case 9: lcd_clear(GRAY); break;
        case 10: lcd_clear(LGRAY); break;
        case 11: lcd_clear(BROWN); break;
       }
        lcd_show_string(10, 40, 240, 32, 32, "STM32", RED);
        lcd_show_string(10, 80, 240, 24, 24, "TFTLCD TEST", RED);
        lcd_show_string(10, 110, 240, 16, 16, "ATOM@ALIENTEK", RED);
        x++;
        if (x == 12)
        {
            x = 0;
        }
        LED0_TOGGLE();  /* LED0闪烁 */
        delay_ms(1000);
   }
}

       main函数功能主要是显示一些固定的字符串,字体大小包括32*16、24*12和16*8三种,然后不停的切换背景颜色,每1s切换一次。而LED0也会不停的闪烁,指示程序已经在运行了。


        20.4 下载验证

       下载代码后,LED0不停的闪烁,提示程序已经在运行了。同时可以看到TFTLCD模块的显示背景色不停切换,如图20.4.1所示:


图20.4.1 TFTLCD显示效果图


请使用浏览器的分享功能分享到微信等