【正点原子STM32连载】第二十六章 TFTLCD(MCU屏)实验 摘自【正点原子】APM32F407最小系统板使用指南

1)实验平台:正点原子stm32f103战舰开发板V4
2)平台购买地址:https://detail.tmall.com/item.htm?id=609294757420
3)全套实验源码+手册+视频下载地址: http://www.openedv.com/thread-340252-1-1.html#

第二十六章 TFTLCD(MCU屏)实验

本章将介绍使用APM32F407驱动TFTLCD(MCU屏)进行显示。通过本章的学习,读者将学习到EMMC(外部存储器控制器)中SMC(静态存储控制器)的使用。
本章分为如下几个小节:
26.1硬件设计
26.2 程序设计
26.3 下载验证

26.1 硬件设计
26.1.1 例程功能

  1. TFTLCD模块显示实验信息和LCD驱动器的ID,同时不停地切换底色
  2. LED0闪烁,指示程序正在运行
    26.1.2 硬件资源
  3. LED
    LED0 - PF9
  4. 正点原子 2.8/3.5/4.3/7/10寸TFTLCD模块(仅限MCU屏,16位8080并口驱动)
    26.1.3 原理图
    本章实验使用了正点原子的TFTLCD模块(兼容正点原子2.8/3.5/4.3/7/10寸的TFTLCD模块),该模块需通过LCD转接板与板载的TFTLCD接口进行连接,该接口与板载MCU的连接原理图,如下图所示:
    在这里插入图片描述

图26.1.3.1 TFTLCD模块与MCU的连接原理图
从上图中可以看到,TFTLCD模块连接至SMC的存储块1的区域块4,并且使用了地址线A6作为TFTLCD模块命令或数据的选择信号,结合《APM32F4xxx用户手册》,便可计算出配置好SMC后,TFTLCD模块的命令访问地址被映射到0x6C00007E,TFTLCD模块的数据访问地址被映射到0x6C000080。
26.2 程序设计
26.2.1 Geehy标准库的SMC驱动
本章实验通过SMC驱动8080并口的TFTLCD模块,通过SMC可以将TFTLCD模块的命令和数据寄存器映射为两个地址,往这两个地址写入或读取数据就可直接与TFTLCD模块进行通讯,因此需要对SMC做相应的配置,具体的步骤如下:
①:配置SMC存储块1的区域块4
②:使能SMC存储块1的区域块4
在Geehy标准库中对应的驱动函数如下:
①:配置SMC存储块1的区域块
该函数用于配置SMC存储块1的区域块,其函数原型如下所示:
void SMC_ConfigNORSRAM(SMC_NORSRAMConfig_T* smcNORSRAMConfig);
该函数的形参描述,如下表所示:
形参 描述
smcNORSRAMConfig 指向SMC存储块1区域块配置结构体的指针
需自行定义,并根据SMC存储块1区域块的配置参数填充结构体中的成员变量
表26.2.1.1 函数SMC_ConfigNORSRAM()形参描述
该函数的返回值描述,如下表所示:
返回值 描述
无 无
表26.2.1.2 函数SMC_ConfigNORSRAM()返回值描述
该函数使用SMC_NORSRAMConfig_T类型的结构体变量传入SMC存储块1区域块的配置参数,该结构体的定义如下所示:

typedef enum
{
    SMC_BANK1_NORSRAM_1,						/* SMC存储块1区域块1 */
    SMC_BANK1_NORSRAM_2,						/* SMC存储块1区域块2 */
    SMC_BANK1_NORSRAM_3,						/* SMC存储块1区域块3 */
    SMC_BANK1_NORSRAM_4							/* SMC存储块1区域块4 */
} SMC_BANK1_NORSRAM_T;

typedef enum
{
    SMC_DATA_ADDRESS_MUX_DISABLE,				/* 禁止数据地址总线复用 */
    SMC_DATA_ADDRESS_MUX_ENABLE					/* 使能数据地址总线复用 */
} SMC_DATA_ADDRESS_MUX_T;

typedef enum
{
    SMC_MEMORY_TYPE_SRAM,						/* SRAM */
    SMC_MEMORY_TYPE_PSRAM,						/* PSRAM */
    SMC_MEMORY_TYPE_NOR							/* NORFlash */
} SMC_MEMORY_TYPE_T;

typedef enum
{
    SMC_MEMORY_DATA_WIDTH_8BIT,					/* 8位数据宽度 */
    SMC_MEMORY_DATA_WIDTH_16BIT					/* 16位数据宽度 */
} SMC_MEMORY_DATA_WIDTH_T;

typedef enum
{
    SMC_BURST_ACCESS_MODE_DISABLE,				/* 禁用突发访问模式 */
    SMC_BURST_ACCESS_MODE_ENABLE				/* 使能突发访问模式 */
} SMC_BURST_ACCESS_MODE_T;

typedef enum
{
    SMC_ASYNCHRONOUS_WAIT_DISABLE,				/* 禁用异步等待 */
    SMC_ASYNCHRONOUS_WAIT_ENABLE				/* 使能异步等待 */
} SMC_ASYNCHRONOUS_WAIT_T;

typedef enum
{
    SMC_WAIT_SIGNAL_POLARITY_LOW,				/* 低电平有效 */
    SMC_WAIT_SIGNAL_POLARITY_HIGH				/* 高电平有效 */
} SMC_WAIT_SIGNAL_POLARITY_T;

typedef enum
{
    SMC_WRAP_MODE_DISABLE,						/* 禁止非对齐的突发访问 */
    SMC_WRAP_MODE_ENABLE						/*使能非对齐的突发访问*/
} SMC_WRAP_MODE_T;

typedef enum
{
    SMC_WAIT_SIGNAL_ACTIVE_BEFORE_WAIT_STATE,	/* 在等待前有效 */
    SMC_WAIT_SIGNAL_ACTIVE_DURING_WAIT_STATE	/* 在等在阶段有效 */
} SMC_WAIT_SIGNAL_ACTIVE_T;

typedef enum
{
    SMC_WRITE_OPERATION_DISABLE,				/* 禁止写操作 */
    SMC_WRITE_OPERATION_ENABLE					/* 使能写操作  */
} SMC_WRITE_OPERATION_T;

typedef enum
{
    SMC_WAITE_SIGNAL_DISABLE,					/* 禁止等待信号 */
    SMC_WAITE_SIGNAL_ENABLE						/* 使能等待信号 */
} SMC_WAITE_SIGNAL_T;

typedef enum
{
    SMC_EXTENDEN_MODE_DISABLE,					/* 禁止扩展模式 */
    SMC_EXTENDEN_MODE_ENABLE					/* 使能扩展模式 */
} SMC_EXTENDEN_MODE_T;

typedef enum
{
    SMC_WRITE_BURST_DISABLE,					/* 禁止突发写 */
    SMC_WRITE_BURST_ENABLE						/* 使能突发写 */
} SMC_WRITE_BURST_T;

typedef struct
{
    uint8_t addressSetupTime;					/* 地址建立时间 */
    uint8_t addressHodeTime;					/* 地址保持时间 */
    uint8_t dataSetupTime;						/* 数据建立时间 */
    uint8_t busTurnaroundTime;					/* 总线恢复时间 */
    uint8_t clockDivision;						/* 时钟分频系数 */
    uint8_t dataLatency;						/* 数据保持时间 */
    SMC_ACCESS_MODE_T accessMode;				/* 访问模式 */
} SMC_NORSRAMTimingConfig_T;

typedef enum
{
    SMC_ACCESS_MODE_A,							/* 访问模式A */
    SMC_ACCESS_MODE_B,							/* 访问模式B */
    SMC_ACCESS_MODE_C,							/* 访问模式C */
    SMC_ACCESS_MODE_D							/* 访问模式D */
} SMC_ACCESS_MODE_T;

typedef struct
{
    SMC_BANK1_NORSRAM_T			bank;					/* SMC存储块1区域块 */
    SMC_DATA_ADDRESS_MUX_T		dataAddressMux;			/* 数据地址总线复用 */
    SMC_MEMORY_TYPE_T			memoryType;				/* 存储器类型 */
    SMC_MEMORY_DATA_WIDTH_T		memoryDataWidth;		/* 数据宽度 */
    SMC_BURST_ACCESS_MODE_T		burstAcceesMode;		/* 突发访问模式 */
    SMC_ASYNCHRONOUS_WAIT_T		asynchronousWait;		/* 异步等待 */
    SMC_WAIT_SIGNAL_POLARITY_T	waitSignalPolarity;		/* 等待信号极性    */
    SMC_WRAP_MODE_T				wrapMode;				/* 非对齐的突发访问 */
    SMC_WAIT_SIGNAL_ACTIVE_T	waitSignalActive;		/* 等待时序 */
    SMC_WRITE_OPERATION_T		writeOperation;			/* 写操作 */
    SMC_WAITE_SIGNAL_T			waiteSignal;			/* 等待信号 */
    SMC_EXTENDEN_MODE_T			extendedMode;			/* 扩展模式 */
    SMC_WRITE_BURST_T			writeBurst;				/* 突发写 */
    SMC_NORSRAMTimingConfig_T	*readWriteTimingStruct;	/* 读写时序 */
    SMC_NORSRAMTimingConfig_T	*writeTimingStruct;		/* 写时序 */
} SMC_NORSRAMConfig_T;
该函数的使用示例,如下所示:
#include "apm32f4xx.h"
#include "apm32f4xx_smc.h"

void example_fun(void)
{
    SMC_NORSRAMConfig_T smc_norsram_init_struct;
    SMC_NORSRAMTimingConfig_T smc_read_timing_struct;
    SMC_NORSRAMTimingConfig_T smc_write_timing_struct;
    
    /* 配置SMC读时序 */
    smc_read_timing_struct.addressSetupTime		= 0x0F;
    smc_read_timing_struct.addressHodeTime		= 0x00;
    smc_read_timing_struct.dataSetupTime		= 0x3C;
    smc_read_timing_struct.busTurnaroundTime	= 0;
    smc_read_timing_struct.clockDivision		= 0;
    smc_read_timing_struct.dataLatency			= 0;
    smc_read_timing_struct.accessMode			= SMC_ACCESS_MODE_A;
    
    /* 配置SMC写时序 */
    smc_write_timing_struct.addressSetupTime	= 0x09;
    smc_write_timing_struct.addressHodeTime		= 0x00;
    smc_write_timing_struct.dataSetupTime		= 0x09;
    smc_write_timing_struct.busTurnaroundTime	= 0;
    smc_write_timing_struct.clockDivision		= 0;
    smc_write_timing_struct.dataLatency			= 0;
    smc_write_timing_struct.accessMode			= SMC_ACCESS_MODE_A;
    
    /* 配置SMC存储块1区域块1 */
    smc_norsram_init_struct.bank				= SMC_BANK1_NORSRAM_1;
    smc_norsram_init_struct.dataAddressMux		= SMC_DATA_ADDRESS_MUX_DISABLE;
    smc_norsram_init_struct.memoryType			= SMC_MEMORY_TYPE_SRAM;
    smc_norsram_init_struct.memoryDataWidth		= SMC_MEMORY_DATA_WIDTH_16BIT;
    smc_norsram_init_struct.burstAcceesMode		= SMC_BURST_ACCESS_MODE_DISABLE;
    smc_norsram_init_struct.asynchronousWait	= SMC_ASYNCHRONOUS_WAIT_DISABLE;
    smc_norsram_init_struct.waitSignalPolarity	= SMC_WAIT_SIGNAL_POLARITY_LOW;
    smc_norsram_init_struct.wrapMode			= SMC_WRAP_MODE_DISABLE;
    smc_norsram_init_struct.waitSignalActive	=
    										SMC_WAIT_SIGNAL_ACTIVE_BEFORE_WAIT_STATE;
    smc_norsram_init_struct.writeOperation		= SMC_WRITE_OPERATION_ENABLE;
    smc_norsram_init_struct.waiteSignal			= SMC_WAITE_SIGNAL_DISABLE;
    smc_norsram_init_struct.extendedMode		= SMC_EXTENDEN_MODE_ENABLE;
    smc_norsram_init_struct.writeBurst			= SMC_WRITE_BURST_DISABLE;
    smc_norsram_init_struct.readWriteTimingStruct	= &smc_read_timing_struct;
    smc_norsram_init_struct.writeTimingStruct	= &smc_write_timing_struct;
    SMC_ConfigNORSRAM(&smc_norsram_init_struct);
}

②:使能SMC存储块1的区域块
该函数用于使能SMC存储块1的区域块,其函数原型如下所示:
void SMC_EnableNORSRAM(SMC_BANK1_NORSRAM_T bank);
该函数的形参描述,如下表所示:
形参 描述
bank SMC存储块1的区域块
例如:SMC_BANK1_NORSRAM_1、SMC_BANK1_NORSRAM_2等(在apm32f4xx_smc.h文件中有定义)
表26.2.1.3 函数SMC_EnableNORSRAM()形参描述
该函数的返回值描述,如下表所示:
返回值 描述
无 无
表26.2.1.4 函数SMC_EnableNORSRAM()返回值描述
该函数的使用示例,图下所示:

#include "apm32f4xx.h"
#include "apm32f4xx_smc.h"

void example_fun(void)
{
    /* 使能SMC存储块1区域块1 */
    SMC_EnableNORSRAM(SMC_BANK1_NORSRAM_1);
}

26.2.2 TFTLCD驱动
本章实验的TFTLCD驱动主要负责向应用层提供TFTLCD的初始化和各种TFTLCD显示的操作函数。本章实验中,TFTLCD的驱动代码包括lcd.c、lcd_ex.c、lcd.h和字体文件lcdfont.h四个文件。
由于TFTLCD模块需要使用到大量的GPIO引脚,因此对于GPIO的相关定义,请读者自行查看lcd.c和lcd.h这两个文件。
TFTLCD驱动中,TFTLCD的初始化函数,如下所示:

/**
 * @brief	初始化LCD
 * @param	无
 */
 * @retval无
void lcd_init(void)
{
    GPIO_Config_T gpio_init_struct;
    SMC_NORSRAMConfig_T smc_norsram_init_struct;
    SMC_NORSRAMTimingConfig_T smc_read_timing_struct;
    SMC_NORSRAMTimingConfig_T smc_write_timing_struct;
    
    /* 使能时钟 */
    RCM->AHB3CLKEN_B.EMMCEN = ENABLE;	/* 使能EMMC时钟 */
    LCD_BL_GPIO_CLK_ENABLE();			/* 使能LCD_BL引脚端口时钟 */
    
    /* 省略SMC相关GPIO引脚的初始化代码 */
    
    /* 配置LCD_BL引脚 */
    gpio_init_struct.pin	= LCD_BL_GPIO_PIN;			/* LCD_BL引脚 */
    gpio_init_struct.mode	= GPIO_MODE_OUT;			/* 通用输出模式 */
    gpio_init_struct.speed	= GPIO_SPEED_100MHz;		/* 高速 */
    gpio_init_struct.otype	= GPIO_OTYPE_PP;			/* 推挽输出 */
    gpio_init_struct.pupd	= GPIO_PUPD_UP;				/* 上拉 */
    GPIO_Config(LCD_BL_GPIO_PORT, &gpio_init_struct);	/* 配置LCD_BL引脚 */
    
    /* 配置SMC读时序 */
    smc_read_timing_struct.addressSetupTime		= 0x0F;	/* 地址建立时间 */
    smc_read_timing_struct.addressHodeTime		= 0x00;	/* 地址保持时间 */
    smc_read_timing_struct.dataSetupTime		= 0x3C;	/* 数据建立时间 */
    smc_read_timing_struct.accessMode			= SMC_ACCESS_MODE_A;/* 访问模式 */
    
    /* 配置SMC写时序 */
    smc_write_timing_struct.addressSetupTime	= 0x09;	/* 地址建立时间 */
    smc_write_timing_struct.addressHodeTime		= 0x00;	/* 地址保持时间 */
    smc_write_timing_struct.dataSetupTime		= 0x09;	/* 数据建立时间 */
    smc_write_timing_struct.accessMode			= SMC_ACCESS_MODE_A;/* 访问模式 */
    
    /* 配置SMC */
    smc_norsram_init_struct.bank				= SMC_BANK1_NORSRAM_4;
    smc_norsram_init_struct.dataAddressMux		= SMC_DATA_ADDRESS_MUX_DISABLE;
    smc_norsram_init_struct.memoryType			= SMC_MEMORY_TYPE_SRAM;
    smc_norsram_init_struct.memoryDataWidth		= SMC_MEMORY_DATA_WIDTH_16BIT;
    smc_norsram_init_struct.burstAcceesMode		= SMC_BURST_ACCESS_MODE_DISABLE;
    smc_norsram_init_struct.asynchronousWait	= SMC_ASYNCHRONOUS_WAIT_DISABLE;
    smc_norsram_init_struct.waitSignalPolarity	= SMC_WAIT_SIGNAL_POLARITY_LOW;
    smc_norsram_init_struct.wrapMode			= SMC_WRAP_MODE_DISABLE;
    smc_norsram_init_struct.waitSignalActive	=
    										SMC_WAIT_SIGNAL_ACTIVE_BEFORE_WAIT_STATE;
    smc_norsram_init_struct.writeOperation		= SMC_WRITE_OPERATION_ENABLE;
    smc_norsram_init_struct.waiteSignal			= SMC_WAITE_SIGNAL_DISABLE;
    smc_norsram_init_struct.extendedMode		= SMC_EXTENDEN_MODE_ENABLE;
    smc_norsram_init_struct.writeBurst			= SMC_WRITE_BURST_DISABLE;
    smc_norsram_init_struct.readWriteTimingStruct	= &smc_read_timing_struct;
    smc_norsram_init_struct.writeTimingStruct		= &smc_write_timing_struct;
    SMC_ConfigNORSRAM(&smc_norsram_init_struct);	/* 配置SMC */
    SMC_EnableNORSRAM(SMC_BANK1_NORSRAM_4);			/* 使能存储块1区域块4 */
    delay_ms(50);
    
    /* 尝试读取ILI9341的ID */
    lcd_wr_regno(0xD3);
    lcddev.id = lcd_rd_data();						/* 无效数据 */
    lcddev.id = lcd_rd_data();						/* 读取到0x00 */
    lcddev.id = lcd_rd_data() << 8;					/* 读取到0x93 */
    lcddev.id |= lcd_rd_data();						/* 读取到0x41 */
    if (lcddev.id != 0x9341)						/* 尝试读取ST7789的ID */
    {
    		lcd_wr_regno(0x04);
    		lcddev.id = lcd_rd_data();					/* 无效数据 */
    		lcddev.id = lcd_rd_data();					/* 读取到0x85 */
    		lcddev.id = lcd_rd_data() << 8;				/* 读取到0x85 */
    		lcddev.id |= lcd_rd_data();					/* 读取到0x52 */
    		if (lcddev.id == 0x8552)					/* 将ST7789的ID记为0x7789 */
    		{
    			lcddev.id = 0x7789;
    		}
    		if (lcddev.id != 0x7789)					/* 尝试读取NT35310的ID */
    		{
    			lcd_wr_regno(0xD4);
    			lcddev.id = lcd_rd_data();				/* 无效数据 */
    			lcddev.id = lcd_rd_data();				/* 读取到0x01 */
    			lcddev.id = lcd_rd_data() << 8;			/* 读取到0x53 */
    			lcddev.id |= lcd_rd_data();				/* 读取到0x10 */
    			if (lcddev.id != 0x5310)				/* 尝试读取NT35510的ID */
    			{
    				/* 发送密钥(厂家提供) */
    				lcd_write_reg(0xF000, 0x0055);
    				lcd_write_reg(0xF001, 0x00AA);
    				lcd_write_reg(0xF002, 0x0052);
    				lcd_write_reg(0xF003, 0x0008);
    				lcd_write_reg(0xF004, 0x0001);
    				
    				lcd_wr_regno(0xC500);
    				lcddev.id = lcd_rd_data() << 8;		/* 读取到0x80 */
    				lcd_wr_regno(0xC501);
    				lcddev.id |= lcd_rd_data();			/* 读取到0x00 */
    				delay_ms(5);	/* 因为此NT5510的指令恰好为SSD1963的软件复位指令 */
    				if (lcddev.id != 0x5510)			/* 尝试读取SSD1963的ID */
    				{
    					lcd_wr_regno(0xA1);
    					lcddev.id = lcd_rd_data();
    					lcddev.id = lcd_rd_data() << 8;	/* 读取到0x57 */
    					lcddev.id |= lcd_rd_data();		/* 读取到0x61 */
    					if (lcddev.id == 0x5761)		/* 将SSD1963的ID记为0x1963 */
    					{
    						lcddev.id = 0x1963;
    					}
    				}
    			}
    		}
    }
    
    if (lcddev.id == 0x7789)
    {
    		lcd_ex_st7789_reginit();	/* 执行ST7789初始化 */
    }
    else if (lcddev.id == 0x9341)
    {
    		lcd_ex_ili9341_reginit();	/* 执行ILI9341初始化 */
    }
    else if (lcddev.id == 0x5310)
    {
    		lcd_ex_nt35310_reginit();	/* 执行NT35310初始化 */
    }
    else if (lcddev.id == 0x5510)
    {
    		lcd_ex_nt35510_reginit();	/* 执行NT35510初始化 */
    }
    else if (lcddev.id == 0x1963)
    {
    		lcd_ex_ssd1963_reginit();	/* 执行SSD1963初始化 */
    		lcd_ssd_backlight_set(100);	/* 背光设置为最亮 */
    }
    
    /* 初始化完成后,提速 */
    if (	(lcddev.id == 0x9341) ||				/* 9341/1963/7789 */
    		(lcddev.id == 0x1963) ||
    		(lcddev.id == 0x7789))
    {
    		SMC_Bank1E->WRTTIM4_B.ADDRSETCFG = 3;
    		SMC_Bank1E->WRTTIM4_B.DATASETCFG = 3;
    }
    else if (	(lcddev.id == 0x5310) ||		/* 5310/5510 */
    				(lcddev.id == 0x5510))
    {
    		SMC_Bank1E->WRTTIM4_B.ADDRSETCFG = 2;
    		SMC_Bank1E->WRTTIM4_B.DATASETCFG = 2;
    }
    
    lcd_display_dir(0);	/* 默认设置为竖屏 */
    LCD_BL(1);			/* 点亮背光 */
    lcd_clear(WHITE);	/* 清屏 */
}

从上的代码中可以看出,本章实验的TFTLCD驱动是兼容了正点原子的多款TFTLCD模块的,因此在初始化完SMC后,会与TFTLCD进行通讯,确定TFTLCD的型号,然后根据型号针对性地对TFTLCD模块进行配置。
TFTLCD驱动中与TFTLCD模块通讯的函数,如下所示:

/**
 * @brief	LCD写数据
 * @param	data: 要写入的数据
 * @retval	无
 */
void lcd_wr_data(volatile uint16_t data)
{
    data = data;
    LCD->LCD_RAM = data;
}

/**
 * @brief	LCD写寄存器编号或地址
 * @param	regno: 寄存器编号或地址
 * @retval	无
 */
void lcd_wr_regno(volatile uint16_t regno)
{
    regno = regno;
    LCD->LCD_REG = regno;
}

/**
 * @brief	LCD写寄存器
 * @param	regno: 寄存器编号
 * @param	data : 要写入的数据
 * @retval	无
 */
void lcd_write_reg(uint16_t regno, uint16_t data)
{
    LCD->LCD_REG = regno;
    LCD->LCD_RAM = data;
}

/**
 * @brief	LCD读数据
 * @param	无
 * @retval	读取到的数据
 */
static uint16_t lcd_rd_data(void)
{
    volatile uint16_t ram;
    
    ram = LCD->LCD_RAM;
    
    return ram;
}

从上面的代码中可以看出,与TFTLCD的通讯都是通过LCD这一结构体对象来完成的,对于LCD结构体的相关定义,如下所示:

typedef struct
{
    volatile uint16_t LCD_REG;
    volatile uint16_t LCD_RAM;
} LCD_TypeDef;

#define LCD_SMC_NEX	4
#define LCD_SMC_AX	6
#define LCD_BASE	\
    (uint32_t)((0x60000000+(0x4000000*(LCD_SMC_NEX-1)))|(((1<<LCD_SMC_AX)*2)-2))
#define LCD			((LCD_TypeDef *)LCD_BASE)

从LCD结构体的相关定义中可以看出,与TFTLCD模块的通讯地址是与TFTLCD连接的SMC存储块1的区域块和TFTLCD模块命令、数据选择信号所连接的SMC地址线是有关的。通过上面宏定义的计算,可以算出LCD_BASE宏定义的值为0x6C00007E,因此访问LCD->LCD_REG就是访问0x6C00007E这一地址,访问LCD->LCD_RAM就是访问0x6C000080这一地址,这两个地址也就是通过SMC映射的TFTLCD命令和数据寄存器的访问地址。
通过上面介绍的驱动函数就能够与TFTLCD模块进行通讯了,而在TFTLCD模块的显示屏上显示出特定的图案或字符或设置TFTLCD模块的显示方向等等的操作都是能够通过TFTLCD模块规定的特定命令来完成的,想深究的读者可以产看正点原子TFTLCD模块的用户手册或查看实际使用的TFTLCD模块的相关文档。
26.2.3 实验应用代码
本章实验的应用代码,如下所示:

int main(void)
{
    uint8_t x = 0;
    uint8_t lcd_id[13];
    
    NVIC_ConfigPriorityGroup(NVIC_PRIORITY_GROUP_3);	/* 设置中断优先级分组为组3 */
    sys_apm32_clock_init(336, 8, 2, 7);					/* 配置系统时钟 */
    delay_init(168);										/* 初始化延时功能 */
    usart_init(115200);									/* 初始化串口 */
    led_init();											/* 初始化LED */
    lcd_init();											/* 初始化LCD */
    
    sprintf((char *)lcd_id, "LCD ID: %04X", lcddev.id);
    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, "APM32", RED);
    		lcd_show_string(10, 80, 240, 24, 24, "TFTLCD TEST", RED);
    		lcd_show_string(10, 110, 240, 16, 16, "ATOM@ALIENTEK", RED);
    		lcd_show_string(10, 130, 240, 16, 16, (char *)lcd_id, RED);
    		
    		x++;
    		if (x == 12)
    		{
    			x = 0;
    		}
    		
    		LED0_TOGGLE();
    		delay_ms(1000);
    }
}

从上面的代码中可以看出,在初始化完LCD后,便在LCD上显示一些本实验的相关信息,随后便每间隔1000毫秒就更换一次LCD屏幕显示的背景色。
26.3 下载验证
在完成编译和烧录操作后,先将开发板断电,随后将TFTLCD模块通过LCD转接板与开发板进行连接,最后再给开发板供电(在插拔开发板上的接插件和模块时,要求必须断电操作,否则容易烧毁硬件)。程序运行后,可以看到LCD上显示了本实验的相关信息,同时LCD显示的背景色被间隔1000毫秒就切换一次。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值