文章目录
- 【FSMC】LCD液晶显示实验系列文章
- 前言
- 一、硬件设计
- 二、软件设计
-
- 1.编程要点
- 2.代码分析
-
- bsp_ili9806g_lcd.h
- bsp_ili9806g_lcd.c(部分)
- bsp_ili9806g_lcd.h(全部)
- 基本液晶显示例程的 main 函数
- 液晶坐标方向演示的 main 函数
【FSMC】LCD液晶显示实验系列文章
【FSMC】LCD液晶显示实验(1)
【FSMC】LCD液晶显示实验(2)
【FSMC】LCD液晶显示实验(3)
前言
前面两篇文章已经把显示屏的分类和液晶屏的基本控制原理讲到了,接下来我们学习的内容主要就是LCD液晶显示实验,从底层的驱动函数深挖,毕竟自从将智能赛和电赛项目放到简历上后,面试官经常问我:你的屏幕驱动你能给我讲讲吗?为了能够不止步于调库,接下来跟随我的文章一起,我们从底层驱动函数好好了解一下这个熟悉又陌生的兄弟!!!
本小节讲解如何使用 FSMC 外设控制实验板配套的 4.5 寸 ILI9806G 液晶屏,见图液晶屏实物图 , 该液晶屏的分辨率为 854×480,支持 RGB565 格式。学习本小节内容时,请打开配套的“FSMC—液晶显示英文”工程配合阅读。
一、硬件设计
液晶屏背面的 PCB 电路对应图屏幕 PCB 底板原理图 、图屏幕 PCB 底板的触摸部分原理图 、图 液晶屏接口 中的原理图。
前面我们已经了解到主板FPC引出线与液晶屏幕进行相连,这些线里面有CS(片选),RS(高电平代表数据,低电平代表命令),D0–15等线;还有LED_k可以控制背光的强度,低电平时打开背光;主板上还有FPC线与触摸版上的GT5688相连,这个芯片能够将触摸信号进行采集和简化把信号传输给主板。
它可以把这些信号通过IIC或者SPI进行传输给主板,我们这里使用的是IIC进行传输触摸信号,后面章节会专门讲解。
图液晶屏接口 表示的是 PCB 底板引出的排针线序,屏幕整体通过这些引出的排针与开发板或其 它控制器连接。
图开发板与屏幕的连接的信号说明 是野火 F407 开发板上的液晶排母接口原理图,它说明了配 套的 4.5 寸屏幕接入到开发板上时的信号连接关系。图中的FSMC_NE3连接的是LCD_CS,FSMC_A0连接的是LCD_RS,可以选择STM32是以什么地址和液晶屏进行通讯。
二、软件设计
新建“bsp_ili9806g_lcd.c”及“bsp_ili9806g_lcd.h”文件
1.编程要点
1.初始化目标引脚和端口时钟; 2.使能FSMC的时钟; 3.配置FSMC的模式位NOR Flash模式用来模拟8080接口时序; 4.建立机制可以实现FSMC与LCD之间的数据传输; 5.初始化LCD屏幕; 6.编写像素函数,可以实现单个像素的控制显示; 7.根据单个像素进行组合绘制不同图形。
2.代码分析
bsp_ili9806g_lcd.h
1.FSMC 参数定义:命令/数据操作地址,片选选中的BANK 2.通讯的相关引脚 3.液晶显示相关参数定义:扫描方向,模式,起点等定义 4.常用颜色等定义 5.函数声明
#ifndef __BSP_ILI9806G_LCD_H
#define __BSP_ILI9806G_LCD_H
#include "stm32f4xx.h"
#include "./font/fonts.h"
/***************************************************************************************
2^26 =0X0400 0000 = 64MB,每个 BANK 有4*64MB = 256MB
64MB:FSMC_Bank1_NORSRAM1:0X6000 0000 ~ 0X63FF FFFF
64MB:FSMC_Bank1_NORSRAM2:0X6400 0000 ~ 0X67FF FFFF
64MB:FSMC_Bank1_NORSRAM3:0X6800 0000 ~ 0X6BFF FFFF
64MB:FSMC_Bank1_NORSRAM4:0X6C00 0000 ~ 0X6FFF FFFF
选择BANK1-BORSRAM3 连接 TFT,地址范围为0X6800 0000 ~ 0X6BFF FFFF
FSMC_A0 接LCD的DC(寄存器/数据选择)脚
寄存器基地址 = 0X6C00 0000
RAM基地址 = 0X6D00 0000 = 0X6C00 0000+2^0*2 = 0X6800 0000 + 0X2 = 0X6800 0002
当选择不同的地址线时,地址要重新计算
****************************************************************************************/
/******************************* ILI9806G 显示屏的 FSMC 参数定义 ***************************/
//FSMC_Bank1_NORSRAM用于LCD命令操作的地址
#define FSMC_Addr_ILI9806G_CMD ( ( uint32_t ) 0x68000000 )
//FSMC_Bank1_NORSRAM用于LCD数据操作的地址
#define FSMC_Addr_ILI9806G_DATA ( ( uint32_t ) 0x68000002 )
//由片选引脚决定的NOR/SRAM块
#define FSMC_Bank1_NORSRAMx FSMC_Bank1_NORSRAM3
/******************************* ILI9806G 显示屏8080通讯引脚定义 ***************************/
/******控制信号线******/
#define FSMC_AF GPIO_AF_FSMC
//片选,选择NOR/SRAM块
#define ILI9806G_CS_CLK RCC_AHB1Periph_GPIOG
#define ILI9806G_CS_PORT GPIOG
#define ILI9806G_CS_PIN GPIO_Pin_10
#define ILI9806G_CS_PinSource GPIO_PinSource10
//DC引脚,使用FSMC的地址信号控制,本引脚决定了访问LCD时使用的地址
//PF0为FSMC_A0
#define ILI9806G_DC_CLK RCC_AHB1Periph_GPIOF
#define ILI9806G_DC_PORT GPIOF
#define ILI9806G_DC_PIN GPIO_Pin_0
#define ILI9806G_DC_PinSource GPIO_PinSource0
//写使能
#define ILI9806G_WR_CLK RCC_AHB1Periph_GPIOD
#define ILI9806G_WR_PORT GPIOD
#define ILI9806G_WR_PIN GPIO_Pin_5
#define ILI9806G_WR_PinSource GPIO_PinSource5
//读使能
#define ILI9806G_RD_CLK RCC_AHB1Periph_GPIOD
#define ILI9806G_RD_PORT GPIOD
#define ILI9806G_RD_PIN GPIO_Pin_4
#define ILI9806G_RD_PinSource GPIO_PinSource4
//复位引脚
#define ILI9806G_RST_CLK RCC_AHB1Periph_GPIOF
#define ILI9806G_RST_PORT GPIOF
#define ILI9806G_RST_PIN GPIO_Pin_11
//背光引脚
#define ILI9806G_BK_CLK RCC_AHB1Periph_GPIOF
#define ILI9806G_BK_PORT GPIOF
#define ILI9806G_BK_PIN GPIO_Pin_9
/********数据信号线***************/
#define ILI9806G_D0_CLK RCC_AHB1Periph_GPIOD
#define ILI9806G_D0_PORT GPIOD
#define ILI9806G_D0_PIN GPIO_Pin_14
#define ILI9806G_D0_PinSource GPIO_PinSource14
#define ILI9806G_D1_CLK RCC_AHB1Periph_GPIOD
#define ILI9806G_D1_PORT GPIOD
#define ILI9806G_D1_PIN GPIO_Pin_15
#define ILI9806G_D1_PinSource GPIO_PinSource15
#define ILI9806G_D2_CLK RCC_AHB1Periph_GPIOD
#define ILI9806G_D2_PORT GPIOD
#define ILI9806G_D2_PIN GPIO_Pin_0
#define ILI9806G_D2_PinSource GPIO_PinSource0
#define ILI9806G_D3_CLK RCC_AHB1Periph_GPIOD
#define ILI9806G_D3_PORT GPIOD
#define ILI9806G_D3_PIN GPIO_Pin_1
#define ILI9806G_D3_PinSource GPIO_PinSource1
#define ILI9806G_D4_CLK RCC_AHB1Periph_GPIOE
#define ILI9806G_D4_PORT GPIOE
#define ILI9806G_D4_PIN GPIO_Pin_7
#define ILI9806G_D4_PinSource GPIO_PinSource7
#define ILI9806G_D5_CLK RCC_AHB1Periph_GPIOE
#define ILI9806G_D5_PORT GPIOE
#define ILI9806G_D5_PIN GPIO_Pin_8
#define ILI9806G_D5_PinSource GPIO_PinSource8
#define ILI9806G_D6_CLK RCC_AHB1Periph_GPIOE
#define ILI9806G_D6_PORT GPIOE
#define ILI9806G_D6_PIN GPIO_Pin_9
#define ILI9806G_D6_PinSource GPIO_PinSource9
#define ILI9806G_D7_CLK RCC_AHB1Periph_GPIOE
#define ILI9806G_D7_PORT GPIOE
#define ILI9806G_D7_PIN GPIO_Pin_10
#define ILI9806G_D7_PinSource GPIO_PinSource10
#define ILI9806G_D8_CLK RCC_AHB1Periph_GPIOE
#define ILI9806G_D8_PORT GPIOE
#define ILI9806G_D8_PIN GPIO_Pin_11
#define ILI9806G_D8_PinSource GPIO_PinSource11
#define ILI9806G_D9_CLK RCC_AHB1Periph_GPIOE
#define ILI9806G_D9_PORT GPIOE
#define ILI9806G_D9_PIN GPIO_Pin_12
#define ILI9806G_D9_PinSource GPIO_PinSource12
#define ILI9806G_D10_CLK RCC_AHB1Periph_GPIOE
#define ILI9806G_D10_PORT GPIOE
#define ILI9806G_D10_PIN GPIO_Pin_13
#define ILI9806G_D10_PinSource GPIO_PinSource13
#define ILI9806G_D11_CLK RCC_AHB1Periph_GPIOE
#define ILI9806G_D11_PORT GPIOE
#define ILI9806G_D11_PIN GPIO_Pin_14
#define ILI9806G_D11_PinSource GPIO_PinSource14
#define ILI9806G_D12_CLK RCC_AHB1Periph_GPIOE
#define ILI9806G_D12_PORT GPIOE
#define ILI9806G_D12_PIN GPIO_Pin_15
#define ILI9806G_D12_PinSource GPIO_PinSource15
#define ILI9806G_D13_CLK RCC_AHB1Periph_GPIOD
#define ILI9806G_D13_PORT GPIOD
#define ILI9806G_D13_PIN GPIO_Pin_8
#define ILI9806G_D13_PinSource GPIO_PinSource8
#define ILI9806G_D14_CLK RCC_AHB1Periph_GPIOD
#define ILI9806G_D14_PORT GPIOD
#define ILI9806G_D14_PIN GPIO_Pin_9
#define ILI9806G_D14_PinSource GPIO_PinSource9
#define ILI9806G_D15_CLK RCC_AHB1Periph_GPIOD
#define ILI9806G_D15_PORT GPIOD
#define ILI9806G_D15_PIN GPIO_Pin_10
#define ILI9806G_D15_PinSource GPIO_PinSource10
/*************************************** 调试预用 ******************************************/
#define DEBUG_DELAY() Delay(0x5000)
/***************************** ILI934 显示区域的起始坐标和总行列数 ***************************/
#define ILI9806G_DispWindow_X_Star 0 //起始点的X坐标
#define ILI9806G_DispWindow_Y_Star 0 //起始点的Y坐标
#define ILI9806G_LESS_PIXEL 480//液晶屏较短方向的像素宽度
#define ILI9806G_MORE_PIXEL 800//液晶屏较长方向的像素宽度
//根据液晶扫描方向而变化的XY像素宽度
//调用ILI9806G_GramScan函数设置方向时会自动更改
extern uint16_t LCD_X_LENGTH,LCD_Y_LENGTH;
//液晶屏扫描模式
//参数可选值为0-7
extern uint8_t LCD_SCAN_MODE;
/******************************* 定义 ILI934 显示屏常用颜色 ********************************/
#define BACKGROUND BLACK //默认背景颜色
#define WHITE 0xFFFF //白色
#define BLACK 0x0000 //黑色
#define GREY 0xF7DE //灰色
#define BLUE 0x001F //蓝色
#define BLUE2 0x051F //浅蓝色
#define RED 0xF800 //红色
#define MAGENTA 0xF81F //红紫色,洋红色
#define GREEN 0x07E0 //绿色
#define CYAN 0x7FFF //蓝绿色,青色
#define YELLOW 0xFFE0 //黄色
#define BRED 0xF81F
#define GRED 0xFFE0
#define GBLUE 0x07FF
/******************************* 定义 ILI934 常用命令 ********************************/
#define CMD_SetCoordinateX 0x2A //设置X坐标
#define CMD_SetCoordinateY 0x2B //设置Y坐标
#define CMD_SetPixel 0x2C //填充像素
/********************************** 声明 ILI934 函数 ***************************************/
void ILI9806G_Init ( void );
void ILI9806G_Rst ( void );
void ILI9806G_BackLed_Control ( FunctionalState enumState );
void ILI9806G_GramScan ( uint8_t ucOtion );
void ILI9806G_OpenWindow ( uint16_t usX, uint16_t usY, uint16_t usWidth, uint16_t usHeight );
void ILI9806G_Clear ( uint16_t usX, uint16_t usY, uint16_t usWidth, uint16_t usHeight );
void ILI9806G_SetPointPixel ( uint16_t usX, uint16_t usY );
uint16_t ILI9806G_GetPointPixel ( uint16_t usX , uint16_t usY );
void ILI9806G_DrawLine ( uint16_t usX1, uint16_t usY1, uint16_t usX2, uint16_t usY2 );
void ILI9806G_DrawRectangle ( uint16_t usX_Start, uint16_t usY_Start, uint16_t usWidth, uint16_t usHeight,uint8_t ucFilled );
void ILI9806G_DrawCircle ( uint16_t usX_Center, uint16_t usY_Center, uint16_t usRadius, uint8_t ucFilled );
void ILI9806G_DispChar_EN ( uint16_t usX, uint16_t usY, const char cChar );
void ILI9806G_DispStringLine_EN ( uint16_t line, char * pStr );
void ILI9806G_DispString_EN ( uint16_t usX, uint16_t usY, char * pStr );
void ILI9806G_DispString_EN_YDir ( uint16_t usX,uint16_t usY , char * pStr );
void ILI9806G_DispChar_CH ( uint16_t usX, uint16_t usY, uint16_t usChar );
void ILI9806G_DispString_CH ( uint16_t usX, uint16_t usY, char * pStr );
void ILI9806G_DispString_EN_CH (uint16_t usX, uint16_t usY, char * pStr );
void ILI9806G_DispStringLine_EN_CH ( uint16_t line, char * pStr );
void ILI9806G_DispString_EN_YDir ( uint16_t usX,uint16_t usY , char * pStr );
void ILI9806G_DispString_EN_CH_YDir ( uint16_t usX,uint16_t usY , char * pStr );
void LCD_SetFont(sFONT *fonts);
sFONT *LCD_GetFont(void);
void ILI9806G_ClearLine(uint16_t Line);
void LCD_SetBackColor(uint16_t Color);
void LCD_SetTextColor(uint16_t Color);
void LCD_SetColors(uint16_t TextColor, uint16_t BackColor);
void LCD_GetColors(uint16_t *TextColor, uint16_t *BackColor);
#define LCD_ClearLine ILI9806G_ClearLine
void ILI9806G_DisplayStringEx(uint16_t x, //字符显示位置x
uint16_t y, //字符显示位置y
uint16_t Font_width,//要显示的字体宽度,英文字符在此基础上/2。注意为偶数
uint16_t Font_Height,//要显示的字体高度,注意为偶数
uint8_t *ptr,//显示的字符内容
uint16_t DrawModel); //是否反色显示
void ILI9806G_DisplayStringEx_YDir(uint16_t x, //字符显示位置x
uint16_t y, //字符显示位置y
uint16_t Font_width,//要显示的字体宽度,英文字符在此基础上/2。注意为偶数
uint16_t Font_Height,//要显示的字体高度,注意为偶数
uint8_t *ptr,//显示的字符内容
uint16_t DrawModel); //是否反色显示
#endif /* __BSP_ILI9806G_ILI9806G_H */
bsp_ili9806g_lcd.c(部分)
初始化ILI9806G的IO引脚
/**
* @brief 初始化ILI9806G的IO引脚
* @param 无
* @retval 无
*/
static void ILI9806G_GPIO_Config ( void )
{
GPIO_InitTypeDef GPIO_InitStructure;
/* 使能FSMC对应相应管脚时钟*/
RCC_AHB1PeriphClockCmd (
/*控制信号*/
ILI9806G_CS_CLK|ILI9806G_DC_CLK|ILI9806G_WR_CLK|
ILI9806G_RD_CLK|ILI9806G_BK_CLK|ILI9806G_RST_CLK|
/*数据信号*/
ILI9806G_D0_CLK|ILI9806G_D1_CLK|ILI9806G_D2_CLK |
ILI9806G_D3_CLK | ILI9806G_D4_CLK|ILI9806G_D5_CLK|
ILI9806G_D6_CLK | ILI9806G_D7_CLK|ILI9806G_D8_CLK|
ILI9806G_D9_CLK | ILI9806G_D10_CLK|ILI9806G_D11_CLK|
ILI9806G_D12_CLK | ILI9806G_D13_CLK|ILI9806G_D14_CLK|
ILI9806G_D15_CLK, ENABLE );
/* 配置FSMC相对应的数据线,FSMC-D0~D15 */
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_Pin = ILI9806G_D0_PIN;
GPIO_Init(ILI9806G_D0_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D0_PORT,ILI9806G_D0_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D1_PIN;
GPIO_Init(ILI9806G_D1_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D1_PORT,ILI9806G_D1_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D2_PIN;
GPIO_Init(ILI9806G_D2_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D2_PORT,ILI9806G_D2_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D3_PIN;
GPIO_Init(ILI9806G_D3_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D3_PORT,ILI9806G_D3_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D4_PIN;
GPIO_Init(ILI9806G_D4_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D4_PORT,ILI9806G_D4_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D5_PIN;
GPIO_Init(ILI9806G_D5_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D5_PORT,ILI9806G_D5_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D6_PIN;
GPIO_Init(ILI9806G_D6_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D6_PORT,ILI9806G_D6_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D7_PIN;
GPIO_Init(ILI9806G_D7_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D7_PORT,ILI9806G_D7_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D8_PIN;
GPIO_Init(ILI9806G_D8_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D8_PORT,ILI9806G_D8_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D9_PIN;
GPIO_Init(ILI9806G_D9_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D9_PORT,ILI9806G_D9_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D10_PIN;
GPIO_Init(ILI9806G_D10_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D10_PORT,ILI9806G_D10_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D11_PIN;
GPIO_Init(ILI9806G_D11_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D11_PORT,ILI9806G_D11_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D12_PIN;
GPIO_Init(ILI9806G_D12_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D12_PORT,ILI9806G_D12_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D13_PIN;
GPIO_Init(ILI9806G_D13_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D13_PORT,ILI9806G_D13_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D14_PIN;
GPIO_Init(ILI9806G_D14_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D14_PORT,ILI9806G_D14_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D15_PIN;
GPIO_Init(ILI9806G_D15_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D15_PORT,ILI9806G_D15_PinSource,FSMC_AF);
/* 配置FSMC相对应的控制线
* FSMC_NOE :LCD-RD
* FSMC_NWE :LCD-WR
* FSMC_NE1 :LCD-CS
* FSMC_A0 :LCD-DC
*/
GPIO_InitStructure.GPIO_Pin = ILI9806G_RD_PIN;
GPIO_Init(ILI9806G_RD_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_RD_PORT,ILI9806G_RD_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_WR_PIN;
GPIO_Init(ILI9806G_WR_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_WR_PORT,ILI9806G_WR_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_CS_PIN;
GPIO_Init(ILI9806G_CS_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_CS_PORT,ILI9806G_CS_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_DC_PIN;
GPIO_Init(ILI9806G_DC_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_DC_PORT,ILI9806G_DC_PinSource,FSMC_AF);
/* 配置LCD复位RST控制管脚*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = ILI9806G_RST_PIN;
GPIO_Init ( ILI9806G_RST_PORT, & GPIO_InitStructure );
/* 配置LCD背光控制管脚BK*/
GPIO_InitStructure.GPIO_Pin = ILI9806G_BK_PIN;
GPIO_Init ( ILI9806G_BK_PORT, & GPIO_InitStructure );
}
LCD FSMC 模式配置: 把 FSMC 配置成异步 NOR FLASH 使用的模式 B,使用该方式模拟 8080 时序控制液晶屏 过程: 1.初始化FSMC时钟 2.时序结构体赋值 3.配置FSMC初始化结构体赋值
/**
* @brief LCD FSMC 模式配置
* @param 无
* @retval 无
*/
static void ILI9806G_FSMC_Config ( void )
{
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
FSMC_NORSRAMTimingInitTypeDef readWriteTiming;
/* 使能FSMC时钟*/
RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC,ENABLE);
//地址建立时间(ADDSET)为1个HCLK 5/168M=30ns
readWriteTiming.FSMC_AddressSetupTime = 0x04; //地址建立时间
//数据保持时间(DATAST)+ 1个HCLK = 12/168M=72ns
readWriteTiming.FSMC_DataSetupTime = 0x0b; //数据建立时间
//选择控制的模式
//模式B,异步NOR FLASH模式,与ILI9806G的8080时序匹配
readWriteTiming.FSMC_AccessMode = FSMC_AccessMode_B;
/*以下配置与模式B无关*/
//地址保持时间(ADDHLD)模式A未用到
readWriteTiming.FSMC_AddressHoldTime = 0x00; //地址保持时间
//设置总线转换周期,仅用于复用模式的NOR操作
readWriteTiming.FSMC_BusTurnAroundDuration = 0x00;
//设置时钟分频,仅用于同步类型的存储器
readWriteTiming.FSMC_CLKDivision = 0x00;
//数据保持时间,仅用于同步型的NOR
readWriteTiming.FSMC_DataLatency = 0x00;
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAMx;
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &readWriteTiming;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &readWriteTiming;
FSMC_NORSRAMInit ( & FSMC_NORSRAMInitStructure );
/* 使能 FSMC_Bank1_NORSRAM3 */
FSMC_NORSRAMCmd ( FSMC_Bank1_NORSRAMx, ENABLE );
}
向ILI9806G写入命令/数据,读取数据
/**
* @brief 向ILI9806G写入命令
* @param usCmd :要写入的命令(表寄存器地址)
* @retval 无
*/
static void ILI9806G_Write_Cmd ( uint16_t usCmd )
{
* ( __IO uint16_t * ) ( FSMC_Addr_ILI9806G_CMD ) = usCmd;
}
/**
* @brief 向ILI9806G写入数据
* @param usData :要写入的数据
* @retval 无
*/
static void ILI9806G_Write_Data ( uint16_t usData )
{
* ( __IO uint16_t * ) ( FSMC_Addr_ILI9806G_DATA ) = usData;
}
/**
* @brief 从ILI9806G读取数据
* @param 无
* @retval 读取到的数据
*/
static uint16_t ILI9806G_Read_Data ( void )
{
return ( * ( __IO uint16_t * ) ( FSMC_Addr_ILI9806G_DATA ) );
}
向液晶屏写入初始化配置: 本质上它们都是使用 ILI9806G_Write_Cmd 发送代码, 然后使用 ILI9806G_Write_Data 函数发送命令对应的参数对液晶屏进行配置。 关于命令及参数可以查询《ILI9806G 数据手册》获知
/**
* @brief 初始化ILI9806G寄存器
* @param 无
* @retval 无
*/
/**
* @brief 初始化ILI9806G寄存器
* @param 无
* @retval 无
*/
static void ILI9806G_REG_Config ( void )
{
//************* Start Initial Sequence **********//
ILI9806G_Write_Cmd(0xFF); // EXTC Command Set enable register
ILI9806G_Write_Data(0xFF);
ILI9806G_Write_Data(0x98);
ILI9806G_Write_Data(0x06);
ILI9806G_Write_Cmd(0xBA); // SPI Interface Setting
ILI9806G_Write_Data(0x60);
ILI9806G_Write_Cmd(0xBC); // GIP 1
ILI9806G_Write_Data(0x01);
ILI9806G_Write_Data(0x0E);
ILI9806G_Write_Data(0x61);
ILI9806G_Write_Data(0xFB);
ILI9806G_Write_Data(0x10);
ILI9806G_Write_Data(0x10);
ILI9806G_Write_Data(0x0B);
ILI9806G_Write_Data(0x0F);
ILI9806G_Write_Data(0x2E);
ILI9806G_Write_Data(0x73);
ILI9806G_Write_Data(0xFF);
ILI9806G_Write_Data(0xFF);
ILI9806G_Write_Data(0x0E);
ILI9806G_Write_Data(0x0E);
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Data(0x03);
ILI9806G_Write_Data(0x66);
ILI9806G_Write_Data(0x63);
ILI9806G_Write_Data(0x01);
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Cmd(0xBD); // GIP 2
ILI9806G_Write_Data(0x01);
ILI9806G_Write_Data(0x23);
ILI9806G_Write_Data(0x45);
ILI9806G_Write_Data(0x67);
ILI9806G_Write_Data(0x01);
ILI9806G_Write_Data(0x23);
ILI9806G_Write_Data(0x45);
ILI9806G_Write_Data(0x67);
ILI9806G_Write_Cmd(0xBE); // GIP 3
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Data(0x21);
ILI9806G_Write_Data(0xAB);
ILI9806G_Write_Data(0x60);
ILI9806G_Write_Data(0x22);
ILI9806G_Write_Data(0x22);
ILI9806G_Write_Data(0x22);
ILI9806G_Write_Data(0x22);
ILI9806G_Write_Data(0x22);
ILI9806G_Write_Cmd(0xC7); // Vcom
ILI9806G_Write_Data(0x6F);
ILI9806G_Write_Cmd(0xED); // EN_volt_reg
ILI9806G_Write_Data(0x7F);
ILI9806G_Write_Data(0x0F);
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Cmd(0xC0); // Power Control 1
ILI9806G_Write_Data(0x37);
ILI9806G_Write_Data(0x0B);
ILI9806G_Write_Data(0x0A);
ILI9806G_Write_Cmd(0xFC); // LVGL
ILI9806G_Write_Data(0x0A);
ILI9806G_Write_Cmd(0xDF); // Engineering Setting
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Data(0x20);
ILI9806G_Write_Cmd(0xF3); // DVDD Voltage Setting
ILI9806G_Write_Data(0x74);
ILI9806G_Write_Cmd(0xB4); // Display Inversion Control
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Cmd(0xF7); // 480×800
ILI9806G_Write_Data(0x8A);
ILI9806G_Write_Cmd(0xB1); // Frame Rate
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Data(0x12);
ILI9806G_Write_Data(0x13);
ILI9806G_Write_Cmd(0xF2); //Panel Timing Control
ILI9806G_Write_Data(0x80);
ILI9806G_Write_Data(0x5B);
ILI9806G_Write_Data(0x40);
ILI9806G_Write_Data(0x28);
ILI9806G_Write_Cmd(0xC1); // Power Control 2
ILI9806G_Write_Data(0x17);
ILI9806G_Write_Data(0x7D);
ILI9806G_Write_Data(0x7A);
ILI9806G_Write_Data(0x20);
ILI9806G_Write_Cmd(0xE0);
ILI9806G_Write_Data(0x00); //P1
ILI9806G_Write_Data(0x11); //P2
ILI9806G_Write_Data(0x1C); //P3
ILI9806G_Write_Data(0x0E); //P4
ILI9806G_Write_Data(0x0F); //P5
ILI9806G_Write_Data(0x0C); //P6
ILI9806G_Write_Data(0xC7); //P7
ILI9806G_Write_Data(0x06); //P8
ILI9806G_Write_Data(0x06); //P9
ILI9806G_Write_Data(0x0A); //P10
ILI9806G_Write_Data(0x10); //P11
ILI9806G_Write_Data(0x12); //P12
ILI9806G_Write_Data(0x0A); //P13
ILI9806G_Write_Data(0x10); //P14
ILI9806G_Write_Data(0x02); //P15
ILI9806G_Write_Data(0x00); //P16
ILI9806G_Write_Cmd(0xE1);
ILI9806G_Write_Data(0x00); //P1
ILI9806G_Write_Data(0x12); //P2
ILI9806G_Write_Data(0x18); //P3
ILI9806G_Write_Data(0x0C); //P4
ILI9806G_Write_Data(0x0F); //P5
ILI9806G_Write_Data(0x0A); //P6
ILI9806G_Write_Data(0x77); //P7
ILI9806G_Write_Data(0x06); //P8
ILI9806G_Write_Data(0x07); //P9
ILI9806G_Write_Data(0x0A); //P10
ILI9806G_Write_Data(0x0E); //P11
ILI9806G_Write_Data(0x0B); //P12
ILI9806G_Write_Data(0x10); //P13
ILI9806G_Write_Data(0x1D); //P14
ILI9806G_Write_Data(0x17); //P15
ILI9806G_Write_Data(0x00); //P16
ILI9806G_Write_Cmd(0x35); //Tearing Effect ON
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Cmd(0x3A);
ILI9806G_Write_Data(0x55);
ILI9806G_Write_Cmd(0x11); //Exit Sleep
DEBUG_DELAY ();
ILI9806G_Write_Cmd(0x29); // Display On
}
设置液晶显示窗口
/**
* @brief 在ILI9806G显示器上开辟一个窗口
* @param usX :在特定扫描方向下窗口的起点X坐标
* @param usY :在特定扫描方向下窗口的起点Y坐标
* @param usWidth :窗口的宽度
* @param usHeight :窗口的高度
* @retval 无
*/
void ILI9806G_OpenWindow ( uint16_t usX, uint16_t usY, uint16_t usWidth, uint16_t usHeight )
{
ILI9806G_Write_Cmd ( CMD_SetCoordinateX ); /* 设置X坐标 */
ILI9806G_Write_Data ( usX >> 8 ); /* 先高8位,然后低8位 */
ILI9806G_Write_Data ( usX & 0xff ); /* 设置起始点和结束点*/
ILI9806G_Write_Data ( ( usX + usWidth – 1 ) >> 8 );
ILI9806G_Write_Data ( ( usX + usWidth – 1 ) & 0xff );
ILI9806G_Write_Cmd ( CMD_SetCoordinateY ); /* 设置Y坐标*/
ILI9806G_Write_Data ( usY >> 8 );
ILI9806G_Write_Data ( usY & 0xff );
ILI9806G_Write_Data ( ( usY + usHeight – 1 ) >> 8 );
ILI9806G_Write_Data ( ( usY + usHeight – 1) & 0xff );
}
如图表示的是设置起始坐标和终止坐标的X值, 其中第一次和第二次的数据可以拼接成起点的X, 第三次和第四次的数据可以拼接成终点的X
这个代表的是Y值,同理。
在ILI9806G显示器上以某一颜色填充像素点, 使用函数ILI9806G_OpenWindow 开辟好窗口 输入参数多少个像素点,第二个参数是颜色。 实现效果就是把这个开辟的窗口依次用这个颜色进行填充多少个像素点
/**
* @brief 在ILI9806G显示器上以某一颜色填充像素点
* @param ulAmout_Point :要填充颜色的像素点的总数目
* @param usColor :颜色
* @retval 无
*/
static __inline void ILI9806G_FillColor ( uint32_t ulAmout_Point, uint16_t usColor )
{
uint32_t i = 0;
/* memory write */
ILI9806G_Write_Cmd ( CMD_SetPixel );
for ( i = 0; i < ulAmout_Point; i ++ )
ILI9806G_Write_Data ( usColor );
}
N就是要填充颜色的像素点的总数目,usColor 是颜色。
这些颜色值会按顺序填充到前面使用 ILI9806G_OpenWindow 函数设置的显示窗口中,例如,若 设置了一个 usX=10, usY=30, usWidth=50, usHeight=20 的窗口,然后再连续填充 50*20 个颜色值为 0XFFFF 的像素数据,即可在 (10,30) 的起始坐标处显示一个宽 50 像素高 20 像素的白色矩 形
绘制单个像素点: 划定一个像素的窗口 在这个窗口里面进行填充颜色,从而达到对该像素的填充
/**
* @brief 设定ILI9806G的光标坐标
* @param usX :在特定扫描方向下光标的X坐标
* @param usY :在特定扫描方向下光标的Y坐标
* @retval 无
*/
static void ILI9806G_SetCursor ( uint16_t usX, uint16_t usY )
{
ILI9806G_OpenWindow ( usX, usY, 1, 1 );
}
/**
* @brief 对ILI9806G显示器的某一点以某种颜色进行填充
* @param usX :在特定扫描方向下该点的X坐标
* @param usY :在特定扫描方向下该点的Y坐标
* @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
* @retval 无
*/
void ILI9806G_SetPointPixel ( uint16_t usX, uint16_t usY )
{
if ( ( usX < LCD_X_LENGTH ) && ( usY < LCD_Y_LENGTH ) )
{
ILI9806G_SetCursor ( usX, usY );
ILI9806G_FillColor ( 1, CurrentTextColor );
}
}
绘制矩形
/**
* @brief 在 ILI9806G 显示器上画一个矩形
* @param usX_Start :在特定扫描方向下矩形的起始点X坐标
* @param usY_Start :在特定扫描方向下矩形的起始点Y坐标
* @param usWidth:矩形的宽度(单位:像素)
* @param usHeight:矩形的高度(单位:像素)
* @param ucFilled :选择是否填充该矩形
* 该参数为以下值之一:
* @arg 0 :空心矩形
* @arg 1 :实心矩形
* @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
* @retval 无
*/
void ILI9806G_DrawRectangle ( uint16_t usX_Start, uint16_t usY_Start, uint16_t usWidth, uint16_t usHeight, uint8_t ucFilled )
{
if ( ucFilled )
{
ILI9806G_OpenWindow ( usX_Start, usY_Start, usWidth, usHeight );
ILI9806G_FillColor ( usWidth * usHeight ,CurrentTextColor);
}
else
{
ILI9806G_DrawLine ( usX_Start, usY_Start, usX_Start + usWidth – 1, usY_Start );
ILI9806G_DrawLine ( usX_Start, usY_Start + usHeight – 1, usX_Start + usWidth – 1, usY_Start + usHeight – 1 );
ILI9806G_DrawLine ( usX_Start, usY_Start, usX_Start, usY_Start + usHeight – 1 );
ILI9806G_DrawLine ( usX_Start + usWidth – 1, usY_Start, usX_Start + usWidth – 1, usY_Start + usHeight – 1 );
}
}
设置液晶的扫描方向
/**
* @brief 设置ILI9806G的GRAM的扫描方向
* @param ucOption :选择GRAM的扫描方向
* @arg 0-7 :参数可选值为0-7这八个方向
*
*!!!其中0、3、5、6 模式适合从左至右显示文字,
*不推荐使用其它模式显示文字其它模式显示文字会有镜像效果
*
*其中0、2、4、6 模式的X方向像素为480,Y方向像素为854
*其中1、3、5、7 模式下X方向像素为854,Y方向像素为480
*
*其中 6 模式为大部分液晶例程的默认显示方向
*其中 3 模式为摄像头例程使用的方向
*其中 0 模式为BMP图片显示例程使用的方向
*
* @retval 无
* @note 坐标图例:A表示向上,V表示向下,<表示向左,>表示向右
X表示X轴,Y表示Y轴
————————————————————
模式0:.模式1:.模式2:.模式3:
A.A.A.A
|.|.|.|
Y.X.Y.X
0.1.2.3
<— X0 o.<—-Y1o.o 2X—> .o 3Y—>
————————————————————
模式4:.模式5:.模式6:.模式7:
<— X4 o.<— Y5 o.o 6X—> .o 7Y—>
4.5.6.7
Y.X.Y.X
|.|.|.|
V.V.V.V
———————————————————
LCD屏示例
|—————–|
|野火Logo|
||
||
||
||
||
||
||
||
|—————–|
屏幕正面(宽480,高854)
*******************************************************/
void ILI9806G_GramScan ( uint8_t ucOption )
{
//参数检查,只可输入0-7
if(ucOption >7 )
return;
//根据模式更新LCD_SCAN_MODE的值,主要用于触摸屏选择计算参数
LCD_SCAN_MODE = ucOption;
//根据模式更新XY方向的像素宽度
if(ucOption%2 == 0)
{
//0 2 4 6模式下X方向像素宽度为480,Y方向为854
LCD_X_LENGTH = ILI9806G_LESS_PIXEL;
LCD_Y_LENGTH =ILI9806G_MORE_PIXEL;
}
else
{
//1 3 5 7模式下X方向像素宽度为854,Y方向为480
LCD_X_LENGTH = ILI9806G_MORE_PIXEL;
LCD_Y_LENGTH =ILI9806G_LESS_PIXEL;
}
//0x36命令参数的高3位可用于设置GRAM扫描方向
ILI9806G_Write_Cmd ( 0x36 );
ILI9806G_Write_Data (0x00 | (ucOption<<5));//根据ucOption的值设置LCD参数,共0-7种模式
ILI9806G_Write_Cmd ( CMD_SetCoordinateX );
ILI9806G_Write_Data ( 0x00 );/* x 起始坐标高8位 */
ILI9806G_Write_Data ( 0x00 );/* x 起始坐标低8位 */
ILI9806G_Write_Data ( ((LCD_X_LENGTH–1)>>8)&0xFF ); /* x 结束坐标高8位 */
ILI9806G_Write_Data ( (LCD_X_LENGTH–1)&0xFF );/* x 结束坐标低8位 */
ILI9806G_Write_Cmd ( CMD_SetCoordinateY );
ILI9806G_Write_Data ( 0x00 );/* y 起始坐标高8位 */
ILI9806G_Write_Data ( 0x00 );/* y 起始坐标低8位 */
ILI9806G_Write_Data ( ((LCD_Y_LENGTH–1)>>8)&0xFF );/* y 结束坐标高8位 */
ILI9806G_Write_Data ( (LCD_Y_LENGTH–1)&0xFF );/* y 结束坐标低8位 */
/* write gram start */
ILI9806G_Write_Cmd ( CMD_SetPixel );
}
注意代码中0X36代表的是命令格式,ucOption<<5 本质是配置 MY/MX/MV 三位(bit7-bit5),这三位的组合对应 8 种扫描方向(比如:0 = 竖屏正向,1 = 横屏正向,2 = 竖屏反向等); 
液晶屏全局初始化: 初始化 GPIO、 FSMC 外设,复位液晶屏,然后向 ILI9806 写入配置参数,调用ILI9806G_GramScan 函数设置默认的液晶扫描方向,并且写入基本的液晶屏配置,最后开启液晶屏的背光。在需要使用液晶屏的时候,直接调用本函数即可完成初始化。
/**
* @brief ILI9806G初始化函数,如果要用到lcd,一定要调用这个函数
* @param 无
* @retval 无
*/
void ILI9806G_Init ( void )
{
ILI9806G_GPIO_Config ();
ILI9806G_FSMC_Config ();
ILI9806G_Rst ();
ILI9806G_REG_Config ();
//设置默认扫描方向,其中 6 模式为大部分液晶例程的默认显示方向
ILI9806G_GramScan(LCD_SCAN_MODE);
ILI9806G_Clear(0,0,LCD_X_LENGTH,LCD_Y_LENGTH);/* 清屏,显示全黑 */
ILI9806G_BackLed_Control ( ENABLE ); //点亮LCD背光灯
}
bsp_ili9806g_lcd.h(全部)
#include "./lcd/bsp_ili9806g_lcd.h"
#include "./font/fonts.h"
//根据液晶扫描方向而变化的XY像素宽度
//调用ILI9806G_GramScan函数设置方向时会自动更改
uint16_t LCD_X_LENGTH = ILI9806G_MORE_PIXEL;
uint16_t LCD_Y_LENGTH = ILI9806G_LESS_PIXEL;
//液晶屏扫描模式,本变量主要用于方便选择触摸屏的计算参数
//参数可选值为0-7
//调用ILI9806G_GramScan函数设置方向时会自动更改
//LCD刚初始化完成时会使用本默认值
uint8_t LCD_SCAN_MODE =6;
static sFONT *LCD_Currentfonts = &Font16x32; //英文字体
static uint16_t CurrentTextColor = WHITE;//前景色
static uint16_t CurrentBackColor = BLACK;//背景色
//缓存读取回来的字模数据
static uint8_t ucBuffer [ WIDTH_CH_CHAR*HEIGHT_CH_CHAR/8 ];
static void ILI9806G_Write_Cmd ( uint16_t usCmd );
static void ILI9806G_Write_Data ( uint16_t usData );
static uint16_t ILI9806G_Read_Data ( void );
static void ILI9806G_Delay ( __IO uint32_t nCount );
static void ILI9806G_GPIO_Config ( void );
static void ILI9806G_FSMC_Config ( void );
static void ILI9806G_REG_Config ( void );
static void ILI9806G_SetCursor ( uint16_t usX, uint16_t usY );
static __inline void ILI9806G_FillColor ( uint32_t ulAmout_Point, uint16_t usColor );
static uint16_t ILI9806G_Read_PixelData ( void );
/**
* @brief 简单延时函数
* @param nCount :延时计数值
* @retval 无
*/
static void Delay ( __IO uint32_t nCount )
{
for ( ; nCount != 0; nCount — );
}
/**
* @brief 向ILI9806G写入命令
* @param usCmd :要写入的命令(表寄存器地址)
* @retval 无
*/
static void ILI9806G_Write_Cmd ( uint16_t usCmd )
{
* ( __IO uint16_t * ) ( FSMC_Addr_ILI9806G_CMD ) = usCmd;
}
/**
* @brief 向ILI9806G写入数据
* @param usData :要写入的数据
* @retval 无
*/
static void ILI9806G_Write_Data ( uint16_t usData )
{
* ( __IO uint16_t * ) ( FSMC_Addr_ILI9806G_DATA ) = usData;
}
/**
* @brief 从ILI9806G读取数据
* @param 无
* @retval 读取到的数据
*/
static uint16_t ILI9806G_Read_Data ( void )
{
return ( * ( __IO uint16_t * ) ( FSMC_Addr_ILI9806G_DATA ) );
}
/**
* @brief 用于 ILI9806G 简单延时函数
* @param nCount :延时计数值
* @retval 无
*/
static void ILI9806G_Delay ( __IO uint32_t nCount )
{
for ( ; nCount != 0; nCount — );
}
/**
* @brief 初始化ILI9806G的IO引脚
* @param 无
* @retval 无
*/
static void ILI9806G_GPIO_Config ( void )
{
GPIO_InitTypeDef GPIO_InitStructure;
/* 使能FSMC对应相应管脚时钟*/
RCC_AHB1PeriphClockCmd (
/*控制信号*/
ILI9806G_CS_CLK|ILI9806G_DC_CLK|ILI9806G_WR_CLK|
ILI9806G_RD_CLK|ILI9806G_BK_CLK|ILI9806G_RST_CLK|
/*数据信号*/
ILI9806G_D0_CLK|ILI9806G_D1_CLK|ILI9806G_D2_CLK |
ILI9806G_D3_CLK | ILI9806G_D4_CLK|ILI9806G_D5_CLK|
ILI9806G_D6_CLK | ILI9806G_D7_CLK|ILI9806G_D8_CLK|
ILI9806G_D9_CLK | ILI9806G_D10_CLK|ILI9806G_D11_CLK|
ILI9806G_D12_CLK | ILI9806G_D13_CLK|ILI9806G_D14_CLK|
ILI9806G_D15_CLK, ENABLE );
/* 配置FSMC相对应的数据线,FSMC-D0~D15 */
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_Pin = ILI9806G_D0_PIN;
GPIO_Init(ILI9806G_D0_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D0_PORT,ILI9806G_D0_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D1_PIN;
GPIO_Init(ILI9806G_D1_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D1_PORT,ILI9806G_D1_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D2_PIN;
GPIO_Init(ILI9806G_D2_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D2_PORT,ILI9806G_D2_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D3_PIN;
GPIO_Init(ILI9806G_D3_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D3_PORT,ILI9806G_D3_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D4_PIN;
GPIO_Init(ILI9806G_D4_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D4_PORT,ILI9806G_D4_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D5_PIN;
GPIO_Init(ILI9806G_D5_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D5_PORT,ILI9806G_D5_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D6_PIN;
GPIO_Init(ILI9806G_D6_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D6_PORT,ILI9806G_D6_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D7_PIN;
GPIO_Init(ILI9806G_D7_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D7_PORT,ILI9806G_D7_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D8_PIN;
GPIO_Init(ILI9806G_D8_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D8_PORT,ILI9806G_D8_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D9_PIN;
GPIO_Init(ILI9806G_D9_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D9_PORT,ILI9806G_D9_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D10_PIN;
GPIO_Init(ILI9806G_D10_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D10_PORT,ILI9806G_D10_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D11_PIN;
GPIO_Init(ILI9806G_D11_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D11_PORT,ILI9806G_D11_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D12_PIN;
GPIO_Init(ILI9806G_D12_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D12_PORT,ILI9806G_D12_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D13_PIN;
GPIO_Init(ILI9806G_D13_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D13_PORT,ILI9806G_D13_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D14_PIN;
GPIO_Init(ILI9806G_D14_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D14_PORT,ILI9806G_D14_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_D15_PIN;
GPIO_Init(ILI9806G_D15_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_D15_PORT,ILI9806G_D15_PinSource,FSMC_AF);
/* 配置FSMC相对应的控制线
* FSMC_NOE :LCD-RD
* FSMC_NWE :LCD-WR
* FSMC_NE1 :LCD-CS
* FSMC_A0 :LCD-DC
*/
GPIO_InitStructure.GPIO_Pin = ILI9806G_RD_PIN;
GPIO_Init(ILI9806G_RD_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_RD_PORT,ILI9806G_RD_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_WR_PIN;
GPIO_Init(ILI9806G_WR_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_WR_PORT,ILI9806G_WR_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_CS_PIN;
GPIO_Init(ILI9806G_CS_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_CS_PORT,ILI9806G_CS_PinSource,FSMC_AF);
GPIO_InitStructure.GPIO_Pin = ILI9806G_DC_PIN;
GPIO_Init(ILI9806G_DC_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(ILI9806G_DC_PORT,ILI9806G_DC_PinSource,FSMC_AF);
/* 配置LCD复位RST控制管脚*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = ILI9806G_RST_PIN;
GPIO_Init ( ILI9806G_RST_PORT, & GPIO_InitStructure );
/* 配置LCD背光控制管脚BK*/
GPIO_InitStructure.GPIO_Pin = ILI9806G_BK_PIN;
GPIO_Init ( ILI9806G_BK_PORT, & GPIO_InitStructure );
}
/**
* @brief LCD FSMC 模式配置
* @param 无
* @retval 无
*/
static void ILI9806G_FSMC_Config ( void )
{
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
FSMC_NORSRAMTimingInitTypeDef readWriteTiming;
/* 使能FSMC时钟*/
RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC,ENABLE);
//地址建立时间(ADDSET)为1个HCLK 5/168M=30ns
readWriteTiming.FSMC_AddressSetupTime = 0x04; //地址建立时间
//数据保持时间(DATAST)+ 1个HCLK = 12/168M=72ns
readWriteTiming.FSMC_DataSetupTime = 0x0b; //数据建立时间
//选择控制的模式
//模式B,异步NOR FLASH模式,与ILI9806G的8080时序匹配
readWriteTiming.FSMC_AccessMode = FSMC_AccessMode_B;
/*以下配置与模式B无关*/
//地址保持时间(ADDHLD)模式A未用到
readWriteTiming.FSMC_AddressHoldTime = 0x00; //地址保持时间
//设置总线转换周期,仅用于复用模式的NOR操作
readWriteTiming.FSMC_BusTurnAroundDuration = 0x00;
//设置时钟分频,仅用于同步类型的存储器
readWriteTiming.FSMC_CLKDivision = 0x00;
//数据保持时间,仅用于同步型的NOR
readWriteTiming.FSMC_DataLatency = 0x00;
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAMx;
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &readWriteTiming;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &readWriteTiming;
FSMC_NORSRAMInit ( & FSMC_NORSRAMInitStructure );
/* 使能 FSMC_Bank1_NORSRAM3 */
FSMC_NORSRAMCmd ( FSMC_Bank1_NORSRAMx, ENABLE );
}
/**
* @brief 初始化ILI9806G寄存器
* @param 无
* @retval 无
*/
/**
* @brief 初始化ILI9806G寄存器
* @param 无
* @retval 无
*/
static void ILI9806G_REG_Config ( void )
{
//************* Start Initial Sequence **********//
ILI9806G_Write_Cmd(0xFF); // EXTC Command Set enable register
ILI9806G_Write_Data(0xFF);
ILI9806G_Write_Data(0x98);
ILI9806G_Write_Data(0x06);
ILI9806G_Write_Cmd(0xBA); // SPI Interface Setting
ILI9806G_Write_Data(0x60);
ILI9806G_Write_Cmd(0xBC); // GIP 1
ILI9806G_Write_Data(0x01);
ILI9806G_Write_Data(0x0E);
ILI9806G_Write_Data(0x61);
ILI9806G_Write_Data(0xFB);
ILI9806G_Write_Data(0x10);
ILI9806G_Write_Data(0x10);
ILI9806G_Write_Data(0x0B);
ILI9806G_Write_Data(0x0F);
ILI9806G_Write_Data(0x2E);
ILI9806G_Write_Data(0x73);
ILI9806G_Write_Data(0xFF);
ILI9806G_Write_Data(0xFF);
ILI9806G_Write_Data(0x0E);
ILI9806G_Write_Data(0x0E);
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Data(0x03);
ILI9806G_Write_Data(0x66);
ILI9806G_Write_Data(0x63);
ILI9806G_Write_Data(0x01);
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Cmd(0xBD); // GIP 2
ILI9806G_Write_Data(0x01);
ILI9806G_Write_Data(0x23);
ILI9806G_Write_Data(0x45);
ILI9806G_Write_Data(0x67);
ILI9806G_Write_Data(0x01);
ILI9806G_Write_Data(0x23);
ILI9806G_Write_Data(0x45);
ILI9806G_Write_Data(0x67);
ILI9806G_Write_Cmd(0xBE); // GIP 3
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Data(0x21);
ILI9806G_Write_Data(0xAB);
ILI9806G_Write_Data(0x60);
ILI9806G_Write_Data(0x22);
ILI9806G_Write_Data(0x22);
ILI9806G_Write_Data(0x22);
ILI9806G_Write_Data(0x22);
ILI9806G_Write_Data(0x22);
ILI9806G_Write_Cmd(0xC7); // Vcom
ILI9806G_Write_Data(0x6F);
ILI9806G_Write_Cmd(0xED); // EN_volt_reg
ILI9806G_Write_Data(0x7F);
ILI9806G_Write_Data(0x0F);
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Cmd(0xC0); // Power Control 1
ILI9806G_Write_Data(0x37);
ILI9806G_Write_Data(0x0B);
ILI9806G_Write_Data(0x0A);
ILI9806G_Write_Cmd(0xFC); // LVGL
ILI9806G_Write_Data(0x0A);
ILI9806G_Write_Cmd(0xDF); // Engineering Setting
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Data(0x20);
ILI9806G_Write_Cmd(0xF3); // DVDD Voltage Setting
ILI9806G_Write_Data(0x74);
ILI9806G_Write_Cmd(0xB4); // Display Inversion Control
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Cmd(0xF7); // 480×800
ILI9806G_Write_Data(0x8A);
ILI9806G_Write_Cmd(0xB1); // Frame Rate
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Data(0x12);
ILI9806G_Write_Data(0x13);
ILI9806G_Write_Cmd(0xF2); //Panel Timing Control
ILI9806G_Write_Data(0x80);
ILI9806G_Write_Data(0x5B);
ILI9806G_Write_Data(0x40);
ILI9806G_Write_Data(0x28);
ILI9806G_Write_Cmd(0xC1); // Power Control 2
ILI9806G_Write_Data(0x17);
ILI9806G_Write_Data(0x7D);
ILI9806G_Write_Data(0x7A);
ILI9806G_Write_Data(0x20);
ILI9806G_Write_Cmd(0xE0);
ILI9806G_Write_Data(0x00); //P1
ILI9806G_Write_Data(0x11); //P2
ILI9806G_Write_Data(0x1C); //P3
ILI9806G_Write_Data(0x0E); //P4
ILI9806G_Write_Data(0x0F); //P5
ILI9806G_Write_Data(0x0C); //P6
ILI9806G_Write_Data(0xC7); //P7
ILI9806G_Write_Data(0x06); //P8
ILI9806G_Write_Data(0x06); //P9
ILI9806G_Write_Data(0x0A); //P10
ILI9806G_Write_Data(0x10); //P11
ILI9806G_Write_Data(0x12); //P12
ILI9806G_Write_Data(0x0A); //P13
ILI9806G_Write_Data(0x10); //P14
ILI9806G_Write_Data(0x02); //P15
ILI9806G_Write_Data(0x00); //P16
ILI9806G_Write_Cmd(0xE1);
ILI9806G_Write_Data(0x00); //P1
ILI9806G_Write_Data(0x12); //P2
ILI9806G_Write_Data(0x18); //P3
ILI9806G_Write_Data(0x0C); //P4
ILI9806G_Write_Data(0x0F); //P5
ILI9806G_Write_Data(0x0A); //P6
ILI9806G_Write_Data(0x77); //P7
ILI9806G_Write_Data(0x06); //P8
ILI9806G_Write_Data(0x07); //P9
ILI9806G_Write_Data(0x0A); //P10
ILI9806G_Write_Data(0x0E); //P11
ILI9806G_Write_Data(0x0B); //P12
ILI9806G_Write_Data(0x10); //P13
ILI9806G_Write_Data(0x1D); //P14
ILI9806G_Write_Data(0x17); //P15
ILI9806G_Write_Data(0x00); //P16
ILI9806G_Write_Cmd(0x35); //Tearing Effect ON
ILI9806G_Write_Data(0x00);
ILI9806G_Write_Cmd(0x3A);
ILI9806G_Write_Data(0x55);
ILI9806G_Write_Cmd(0x11); //Exit Sleep
DEBUG_DELAY ();
ILI9806G_Write_Cmd(0x29); // Display On
}
/**
* @brief ILI9806G初始化函数,如果要用到lcd,一定要调用这个函数
* @param 无
* @retval 无
*/
void ILI9806G_Init ( void )
{
ILI9806G_GPIO_Config ();
ILI9806G_FSMC_Config ();
ILI9806G_Rst ();
ILI9806G_REG_Config ();
//设置默认扫描方向,其中 6 模式为大部分液晶例程的默认显示方向
ILI9806G_GramScan(LCD_SCAN_MODE);
ILI9806G_Clear(0,0,LCD_X_LENGTH,LCD_Y_LENGTH);/* 清屏,显示全黑 */
ILI9806G_BackLed_Control ( ENABLE ); //点亮LCD背光灯
}
/**
* @brief ILI9806G背光LED控制
* @param enumState :决定是否使能背光LED
* 该参数为以下值之一:
* @arg ENABLE :使能背光LED
* @arg DISABLE :禁用背光LED
* @retval 无
*/
void ILI9806G_BackLed_Control ( FunctionalState enumState )
{
if ( enumState )
GPIO_SetBits( ILI9806G_BK_PORT, ILI9806G_BK_PIN );
else
GPIO_ResetBits( ILI9806G_BK_PORT, ILI9806G_BK_PIN );
}
/**
* @brief ILI9806G 软件复位
* @param 无
* @retval 无
*/
void ILI9806G_Rst ( void )
{
GPIO_ResetBits ( ILI9806G_RST_PORT, ILI9806G_RST_PIN ); //低电平复位
ILI9806G_Delay ( 30000 );
GPIO_SetBits ( ILI9806G_RST_PORT, ILI9806G_RST_PIN );
ILI9806G_Delay ( 30000 );
}
/**
* @brief 设置ILI9806G的GRAM的扫描方向
* @param ucOption :选择GRAM的扫描方向
* @arg 0-7 :参数可选值为0-7这八个方向
*
*!!!其中0、3、5、6 模式适合从左至右显示文字,
*不推荐使用其它模式显示文字其它模式显示文字会有镜像效果
*
*其中0、2、4、6 模式的X方向像素为480,Y方向像素为854
*其中1、3、5、7 模式下X方向像素为854,Y方向像素为480
*
*其中 6 模式为大部分液晶例程的默认显示方向
*其中 3 模式为摄像头例程使用的方向
*其中 0 模式为BMP图片显示例程使用的方向
*
* @retval 无
* @note 坐标图例:A表示向上,V表示向下,<表示向左,>表示向右
X表示X轴,Y表示Y轴
————————————————————
模式0:.模式1:.模式2:.模式3:
A.A.A.A
|.|.|.|
Y.X.Y.X
0.1.2.3
<— X0 o.<—-Y1o.o 2X—> .o 3Y—>
————————————————————
模式4:.模式5:.模式6:.模式7:
<— X4 o.<— Y5 o.o 6X—> .o 7Y—>
4.5.6.7
Y.X.Y.X
|.|.|.|
V.V.V.V
———————————————————
LCD屏示例
|—————–|
|野火Logo|
||
||
||
||
||
||
||
||
|—————–|
屏幕正面(宽480,高854)
*******************************************************/
void ILI9806G_GramScan ( uint8_t ucOption )
{
//参数检查,只可输入0-7
if(ucOption >7 )
return;
//根据模式更新LCD_SCAN_MODE的值,主要用于触摸屏选择计算参数
LCD_SCAN_MODE = ucOption;
//根据模式更新XY方向的像素宽度
if(ucOption%2 == 0)
{
//0 2 4 6模式下X方向像素宽度为480,Y方向为854
LCD_X_LENGTH = ILI9806G_LESS_PIXEL;
LCD_Y_LENGTH =ILI9806G_MORE_PIXEL;
}
else
{
//1 3 5 7模式下X方向像素宽度为854,Y方向为480
LCD_X_LENGTH = ILI9806G_MORE_PIXEL;
LCD_Y_LENGTH =ILI9806G_LESS_PIXEL;
}
//0x36命令参数的高3位可用于设置GRAM扫描方向
ILI9806G_Write_Cmd ( 0x36 );
ILI9806G_Write_Data (0x00 | (ucOption<<5));//根据ucOption的值设置LCD参数,共0-7种模式
ILI9806G_Write_Cmd ( CMD_SetCoordinateX );
ILI9806G_Write_Data ( 0x00 );/* x 起始坐标高8位 */
ILI9806G_Write_Data ( 0x00 );/* x 起始坐标低8位 */
ILI9806G_Write_Data ( ((LCD_X_LENGTH–1)>>8)&0xFF ); /* x 结束坐标高8位 */
ILI9806G_Write_Data ( (LCD_X_LENGTH–1)&0xFF );/* x 结束坐标低8位 */
ILI9806G_Write_Cmd ( CMD_SetCoordinateY );
ILI9806G_Write_Data ( 0x00 );/* y 起始坐标高8位 */
ILI9806G_Write_Data ( 0x00 );/* y 起始坐标低8位 */
ILI9806G_Write_Data ( ((LCD_Y_LENGTH–1)>>8)&0xFF );/* y 结束坐标高8位 */
ILI9806G_Write_Data ( (LCD_Y_LENGTH–1)&0xFF );/* y 结束坐标低8位 */
/* write gram start */
ILI9806G_Write_Cmd ( CMD_SetPixel );
}
/**
* @brief 在ILI9806G显示器上开辟一个窗口
* @param usX :在特定扫描方向下窗口的起点X坐标
* @param usY :在特定扫描方向下窗口的起点Y坐标
* @param usWidth :窗口的宽度
* @param usHeight :窗口的高度
* @retval 无
*/
void ILI9806G_OpenWindow ( uint16_t usX, uint16_t usY, uint16_t usWidth, uint16_t usHeight )
{
ILI9806G_Write_Cmd ( CMD_SetCoordinateX ); /* 设置X坐标 */
ILI9806G_Write_Data ( usX >> 8 ); /* 先高8位,然后低8位 */
ILI9806G_Write_Data ( usX & 0xff ); /* 设置起始点和结束点*/
ILI9806G_Write_Data ( ( usX + usWidth – 1 ) >> 8 );
ILI9806G_Write_Data ( ( usX + usWidth – 1 ) & 0xff );
ILI9806G_Write_Cmd ( CMD_SetCoordinateY ); /* 设置Y坐标*/
ILI9806G_Write_Data ( usY >> 8 );
ILI9806G_Write_Data ( usY & 0xff );
ILI9806G_Write_Data ( ( usY + usHeight – 1 ) >> 8 );
ILI9806G_Write_Data ( ( usY + usHeight – 1) & 0xff );
}
/**
* @brief 设定ILI9806G的光标坐标
* @param usX :在特定扫描方向下光标的X坐标
* @param usY :在特定扫描方向下光标的Y坐标
* @retval 无
*/
static void ILI9806G_SetCursor ( uint16_t usX, uint16_t usY )
{
ILI9806G_OpenWindow ( usX, usY, 1, 1 );
}
/**
* @brief 在ILI9806G显示器上以某一颜色填充像素点
* @param ulAmout_Point :要填充颜色的像素点的总数目
* @param usColor :颜色
* @retval 无
*/
static __inline void ILI9806G_FillColor ( uint32_t ulAmout_Point, uint16_t usColor )
{
uint32_t i = 0;
/* memory write */
ILI9806G_Write_Cmd ( CMD_SetPixel );
for ( i = 0; i < ulAmout_Point; i ++ )
ILI9806G_Write_Data ( usColor );
}
/**
* @brief 对ILI9806G显示器的某一窗口以某种颜色进行清屏
* @param usX :在特定扫描方向下窗口的起点X坐标
* @param usY :在特定扫描方向下窗口的起点Y坐标
* @param usWidth :窗口的宽度
* @param usHeight :窗口的高度
* @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
* @retval 无
*/
void ILI9806G_Clear ( uint16_t usX, uint16_t usY, uint16_t usWidth, uint16_t usHeight )
{
ILI9806G_OpenWindow ( usX, usY, usWidth, usHeight );
ILI9806G_FillColor ( usWidth * usHeight, CurrentBackColor );
}
/**
* @brief 对ILI9806G显示器的某一点以某种颜色进行填充
* @param usX :在特定扫描方向下该点的X坐标
* @param usY :在特定扫描方向下该点的Y坐标
* @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
* @retval 无
*/
void ILI9806G_SetPointPixel ( uint16_t usX, uint16_t usY )
{
if ( ( usX < LCD_X_LENGTH ) && ( usY < LCD_Y_LENGTH ) )
{
ILI9806G_SetCursor ( usX, usY );
ILI9806G_FillColor ( 1, CurrentTextColor );
}
}
/**
* @brief 读取ILI9806G GRAN 的一个像素数据
* @param 无
* @retval 像素数据
*/
static uint16_t ILI9806G_Read_PixelData ( void )
{
uint16_t usR=0, usG=0, usB=0 ;
ILI9806G_Write_Cmd ( 0x2E ); /* 读数据 */
usR = ILI9806G_Read_Data (); /*FIRST READ OUT DUMMY DATA*/
usR = ILI9806G_Read_Data (); /*READ OUT RED DATA */
usB = ILI9806G_Read_Data (); /*READ OUT BLUE DATA*/
usG = ILI9806G_Read_Data (); /*READ OUT GREEN DATA*/
return ( ( ( usR >> 11 ) << 11 ) | ( ( usG >> 10 ) << 5 ) | ( usB >> 11 ) );
}
/**
* @brief 获取 ILI9806G 显示器上某一个坐标点的像素数据
* @param usX :在特定扫描方向下该点的X坐标
* @param usY :在特定扫描方向下该点的Y坐标
* @retval 像素数据
*/
uint16_t ILI9806G_GetPointPixel ( uint16_t usX, uint16_t usY )
{
uint16_t usPixelData;
ILI9806G_SetCursor ( usX, usY );
usPixelData = ILI9806G_Read_PixelData ();
return usPixelData;
}
/**
* @brief 在 ILI9806G 显示器上使用 Bresenham 算法画线段
* @param usX1 :在特定扫描方向下线段的一个端点X坐标
* @param usY1 :在特定扫描方向下线段的一个端点Y坐标
* @param usX2 :在特定扫描方向下线段的另一个端点X坐标
* @param usY2 :在特定扫描方向下线段的另一个端点Y坐标
* @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
* @retval 无
*/
void ILI9806G_DrawLine ( uint16_t usX1, uint16_t usY1, uint16_t usX2, uint16_t usY2 )
{
uint16_t us;
uint16_t usX_Current, usY_Current;
int32_t lError_X = 0, lError_Y = 0, lDelta_X, lDelta_Y, lDistance;
int32_t lIncrease_X, lIncrease_Y;
lDelta_X = usX2 – usX1; //计算坐标增量
lDelta_Y = usY2 – usY1;
usX_Current = usX1;
usY_Current = usY1;
if ( lDelta_X > 0 )
lIncrease_X = 1; //设置单步方向
else if ( lDelta_X == 0 )
lIncrease_X = 0;//垂直线
else
{
lIncrease_X = –1;
lDelta_X = – lDelta_X;
}
if ( lDelta_Y > 0 )
lIncrease_Y = 1;
else if ( lDelta_Y == 0 )
lIncrease_Y = 0;//水平线
else
{
lIncrease_Y = –1;
lDelta_Y = – lDelta_Y;
}
if ( lDelta_X > lDelta_Y )
lDistance = lDelta_X; //选取基本增量坐标轴
else
lDistance = lDelta_Y;
for ( us = 0; us <= lDistance + 1; us ++ )//画线输出
{
ILI9806G_SetPointPixel ( usX_Current, usY_Current );//画点
lError_X += lDelta_X ;
lError_Y += lDelta_Y ;
if ( lError_X > lDistance )
{
lError_X -= lDistance;
usX_Current += lIncrease_X;
}
if ( lError_Y > lDistance )
{
lError_Y -= lDistance;
usY_Current += lIncrease_Y;
}
}
}
/**
* @brief 在 ILI9806G 显示器上画一个矩形
* @param usX_Start :在特定扫描方向下矩形的起始点X坐标
* @param usY_Start :在特定扫描方向下矩形的起始点Y坐标
* @param usWidth:矩形的宽度(单位:像素)
* @param usHeight:矩形的高度(单位:像素)
* @param ucFilled :选择是否填充该矩形
* 该参数为以下值之一:
* @arg 0 :空心矩形
* @arg 1 :实心矩形
* @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
* @retval 无
*/
void ILI9806G_DrawRectangle ( uint16_t usX_Start, uint16_t usY_Start, uint16_t usWidth, uint16_t usHeight, uint8_t ucFilled )
{
if ( ucFilled )
{
ILI9806G_OpenWindow ( usX_Start, usY_Start, usWidth, usHeight );
ILI9806G_FillColor ( usWidth * usHeight ,CurrentTextColor);
}
else
{
ILI9806G_DrawLine ( usX_Start, usY_Start, usX_Start + usWidth – 1, usY_Start );
ILI9806G_DrawLine ( usX_Start, usY_Start + usHeight – 1, usX_Start + usWidth – 1, usY_Start + usHeight – 1 );
ILI9806G_DrawLine ( usX_Start, usY_Start, usX_Start, usY_Start + usHeight – 1 );
ILI9806G_DrawLine ( usX_Start + usWidth – 1, usY_Start, usX_Start + usWidth – 1, usY_Start + usHeight – 1 );
}
}
/**
* @brief 在 ILI9806G 显示器上使用 Bresenham 算法画圆
* @param usX_Center :在特定扫描方向下圆心的X坐标
* @param usY_Center :在特定扫描方向下圆心的Y坐标
* @param usRadius:圆的半径(单位:像素)
* @param ucFilled :选择是否填充该圆
* 该参数为以下值之一:
* @arg 0 :空心圆
* @arg 1 :实心圆
* @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
* @retval 无
*/
void ILI9806G_DrawCircle ( uint16_t usX_Center, uint16_t usY_Center, uint16_t usRadius, uint8_t ucFilled )
{
int16_t sCurrentX, sCurrentY;
int16_t sError;
sCurrentX = 0; sCurrentY = usRadius;
sError = 3 – ( usRadius << 1 ); //判断下个点位置的标志
while ( sCurrentX <= sCurrentY )
{
int16_t sCountY;
if ( ucFilled )
for ( sCountY = sCurrentX; sCountY <= sCurrentY; sCountY ++ )
{
ILI9806G_SetPointPixel ( usX_Center + sCurrentX, usY_Center + sCountY ); //1,研究对象
ILI9806G_SetPointPixel ( usX_Center – sCurrentX, usY_Center + sCountY ); //2
ILI9806G_SetPointPixel ( usX_Center – sCountY, usY_Center + sCurrentX ); //3
ILI9806G_SetPointPixel ( usX_Center – sCountY, usY_Center – sCurrentX ); //4
ILI9806G_SetPointPixel ( usX_Center – sCurrentX, usY_Center – sCountY ); //5
ILI9806G_SetPointPixel ( usX_Center + sCurrentX, usY_Center – sCountY ); //6
ILI9806G_SetPointPixel ( usX_Center + sCountY, usY_Center – sCurrentX ); //7
ILI9806G_SetPointPixel ( usX_Center + sCountY, usY_Center + sCurrentX ); //0
}
else
{
ILI9806G_SetPointPixel ( usX_Center + sCurrentX, usY_Center + sCurrentY ); //1,研究对象
ILI9806G_SetPointPixel ( usX_Center – sCurrentX, usY_Center + sCurrentY ); //2
ILI9806G_SetPointPixel ( usX_Center – sCurrentY, usY_Center + sCurrentX ); //3
ILI9806G_SetPointPixel ( usX_Center – sCurrentY, usY_Center – sCurrentX ); //4
ILI9806G_SetPointPixel ( usX_Center – sCurrentX, usY_Center – sCurrentY ); //5
ILI9806G_SetPointPixel ( usX_Center + sCurrentX, usY_Center – sCurrentY ); //6
ILI9806G_SetPointPixel ( usX_Center + sCurrentY, usY_Center – sCurrentX ); //7
ILI9806G_SetPointPixel ( usX_Center + sCurrentY, usY_Center + sCurrentX ); //0
}
sCurrentX ++;
if ( sError < 0 )
sError += 4 * sCurrentX + 6;
else
{
sError += 10 + 4 * ( sCurrentX – sCurrentY );
sCurrentY —;
}
}
}
基本液晶显示例程的 main 函数
1.调用了 ILI9806G_Init 函数初始化液晶屏,然后再初始化串口 2.调用 LCD_Test 函数显示各种图形进行测试 (如直线、矩形、圆形)
#include "stm32f4xx.h"
#include "./usart/bsp_debug_usart.h"
#include "./led/bsp_led.h"
#include "./lcd/bsp_ili9806g_lcd.h"
static void LCD_Test(void);
static void Delay ( __IO uint32_t nCount );
void Printf_Charater(void) ;
/**
* @brief 主函数
* @param 无
* @retval 无
*/
int main ( void )
{
LED_GPIO_Config();
ILI9806G_Init (); //LCD 初始化
Debug_USART_Config();
printf("\\r\\n ********** 液晶屏英文显示程序*********** \\r\\n");
printf("\\r\\n 本程序不支持中文,显示中文的程序请学习下一章 \\r\\n");
//其中0、3、5、6 模式适合从左至右显示文字,
//不推荐使用其它模式显示文字其它模式显示文字会有镜像效果
//其中 6 模式为大部分液晶例程的默认显示方向
ILI9806G_GramScan ( 6 );
while ( 1 )
{
LCD_Test();
}
}
/*用于测试各种液晶的函数*/
void LCD_Test(void)
{
/*演示显示变量*/
static uint8_t testCNT = 0;
char dispBuff[100];
testCNT++;
LCD_SetFont(&Font16x32);
LCD_SetColors(RED,BLACK);
ILI9806G_Clear(0,0,LCD_X_LENGTH,LCD_Y_LENGTH);/* 清屏,显示全黑 */
/********显示字符串示例*******/
ILI9806G_DispStringLine_EN(LINE(0),"YH 4.3 inch LCD");
ILI9806G_DispStringLine_EN(LINE(2),"resolution:480x800px");
ILI9806G_DispStringLine_EN(LINE(3),"LCD driver:ILI9806G");
ILI9806G_DispStringLine_EN(LINE(4),"Touch driver:GT911");
/********显示变量示例*******/
LCD_SetTextColor(GREEN);
/*使用c标准库把变量转化成字符串*/
sprintf(dispBuff,"Count : %d ",testCNT);
ILI9806G_ClearLine(LINE(7));/* 清除单行文字 */
/*然后显示该字符串即可,其它变量也是这样处理*/
ILI9806G_DispStringLine_EN(LINE(7),dispBuff);
/*******显示图形示例******/
/* 画直线 */
ILI9806G_ClearLine(LINE(7));/* 清除单行文字 */
LCD_SetTextColor(BLUE);
ILI9806G_DispStringLine_EN(LINE(7),"Draw line:");
LCD_SetTextColor(RED);
ILI9806G_DrawLine(50,270,420,275);
ILI9806G_DrawLine(50,300,420,375);
LCD_SetTextColor(GREEN);
ILI9806G_DrawLine(50,370,420,475);
ILI9806G_DrawLine(50,400,420,475);
LCD_SetTextColor(BLUE);
ILI9806G_DrawLine(50,420,420,325);
ILI9806G_DrawLine(50,450,420,395);
Delay(0x2FFFFFF);
ILI9806G_Clear(0,32*7,LCD_X_LENGTH,LCD_Y_LENGTH–32*7);/* 清屏,显示全黑 */
/*画矩形*/
ILI9806G_ClearLine(LINE(7));/* 清除单行文字 */
LCD_SetTextColor(BLUE);
ILI9806G_DispStringLine_EN(LINE(7),"Draw Rect:");
LCD_SetTextColor(RED);
ILI9806G_DrawRectangle(50,300,200,100,1);
LCD_SetTextColor(GREEN);
ILI9806G_DrawRectangle(100,300,200,120,0);
LCD_SetTextColor(BLUE);
ILI9806G_DrawRectangle(250,300,200,150,1);
Delay(0x2FFFFFF);
ILI9806G_Clear(0,32*7,LCD_X_LENGTH,LCD_Y_LENGTH–32*7);/* 清屏,显示全黑 */
/* 画圆 */
ILI9806G_ClearLine(LINE(7));/* 清除单行文字 */
LCD_SetTextColor(BLUE);
ILI9806G_DispStringLine_EN(LINE(7),"Draw Cir:");
LCD_SetTextColor(RED);
ILI9806G_DrawCircle(150,400,60,1);
LCD_SetTextColor(GREEN);
ILI9806G_DrawCircle(250,400,60,0);
LCD_SetTextColor(BLUE);
ILI9806G_DrawCircle(350,400,60,1);
Delay(0x2FFFFFF);
ILI9806G_Clear(0,32*7,LCD_X_LENGTH,LCD_Y_LENGTH–32*7);/* 清屏,显示全黑 */
}
/**
* @brief 简单延时函数
* @param nCount :延时计数值
* @retval 无
*/
static void Delay ( __IO uint32_t nCount )
{
for ( ; nCount != 0; nCount — );
}
/*********************************************END OF FILE**********************/
液晶坐标方向演示的 main 函数
本工程的 main 函数中主要调用了 LCD_Direction_Show 函数,该函数主要添加了液晶屏在不同 扫描模式下的显示效果演示,了解液晶屏的各个扫描模式。 注意: 其中部分模式显示文字时会因为镜像效果导致无法阅读,这是由扫描模式决定的,并不是代码错 误,只要使用适当的模式即可实现正常的文字显示效果。
#include "stm32f4xx.h"
#include "./usart/bsp_debug_usart.h"
#include "./led/bsp_led.h"
#include "./lcd/bsp_ili9806g_lcd.h"
static void LCD_Test(void);
static void LCD_Direction_Show(void);
static void Delay ( __IO uint32_t nCount );
void Printf_Charater(void) ;
/**
* @brief 主函数
* @param 无
* @retval 无
*/
int main ( void )
{
LED_GPIO_Config();
ILI9806G_Init (); //LCD 初始化
Debug_USART_Config();
printf("\\r\\n ********** 液晶屏英文显示程序*********** \\r\\n");
printf("\\r\\n 本程序不支持中文,显示中文的程序请学习下一章 \\r\\n");
//其中0、3、5、6 模式适合从左至右显示文字,
//不推荐使用其它模式显示文字其它模式显示文字会有镜像效果
//其中 6 模式为大部分液晶例程的默认显示方向
ILI9806G_GramScan ( 6 );
while ( 1 )
{
LCD_Direction_Show();
}
}
/*用于展示LCD的八种方向模式*/
void LCD_Direction_Show(void)
{
uint8_t i = 0;
char dispBuff[100];
//轮流展示各个方向模式
for(i=0;i<8;i++)
{
LCD_SetFont(&Font16x32);
LCD_SetColors(RED,BLACK);
ILI9806G_Clear(0,0,LCD_X_LENGTH,LCD_Y_LENGTH);/* 清屏,显示全黑 */
//其中0、3、5、6 模式适合从左至右显示文字,
//不推荐使用其它模式显示文字其它模式显示文字会有镜像效果
//其中 6 模式为大部分液晶例程的默认显示方向
ILI9806G_GramScan ( i );
sprintf(dispBuff,"o%d. X —>",i);
ILI9806G_DispStringLine_EN(LINE(0),dispBuff);//沿X方向显示文字
sprintf(dispBuff,"o%d.Y|V",i);
ILI9806G_DispString_EN_YDir(0,0,dispBuff);//沿Y方向显示文字
Delay(0x2FFFFFF);
//显示测试
// *!!!其中0、3、5、6 模式适合从左至右显示文字,不推荐使用其它模式显示文字
//其它模式显示文字会有镜像效果
LCD_Test();
}
}
/*用于测试各种液晶的函数*/
void LCD_Test(void)
{
/*演示显示变量*/
static uint8_t testCNT = 0;
char dispBuff[100];
testCNT++;
LCD_SetFont(&Font16x32);
LCD_SetColors(RED,BLACK);
ILI9806G_Clear(0,0,LCD_X_LENGTH,LCD_Y_LENGTH);/* 清屏,显示全黑 */
/********显示字符串示例*******/
ILI9806G_DispStringLine_EN(LINE(0),"YH 4.3 inch LCD");
ILI9806G_DispStringLine_EN(LINE(2),"resolution:480x800px");
ILI9806G_DispStringLine_EN(LINE(3),"LCD driver:ILI9806G");
ILI9806G_DispStringLine_EN(LINE(4),"Touch driver:GT911");
/********显示变量示例*******/
LCD_SetTextColor(GREEN);
/*使用c标准库把变量转化成字符串*/
sprintf(dispBuff,"Count : %d ",testCNT);
ILI9806G_ClearLine(LINE(7));/* 清除单行文字 */
/*然后显示该字符串即可,其它变量也是这样处理*/
ILI9806G_DispStringLine_EN(LINE(7),dispBuff);
/*******显示图形示例******/
/* 画直线 */
ILI9806G_ClearLine(LINE(7));/* 清除单行文字 */
LCD_SetTextColor(BLUE);
ILI9806G_DispStringLine_EN(LINE(7),"Draw line:");
LCD_SetTextColor(RED);
ILI9806G_DrawLine(50,270,420,275);
ILI9806G_DrawLine(50,300,420,375);
LCD_SetTextColor(GREEN);
ILI9806G_DrawLine(50,370,420,475);
ILI9806G_DrawLine(50,400,420,475);
LCD_SetTextColor(BLUE);
ILI9806G_DrawLine(50,420,420,325);
ILI9806G_DrawLine(50,450,420,395);
Delay(0x2FFFFFF);
ILI9806G_Clear(0,32*7,LCD_X_LENGTH,LCD_Y_LENGTH–32*7);/* 清屏,显示全黑 */
/*画矩形*/
ILI9806G_ClearLine(LINE(7));/* 清除单行文字 */
LCD_SetTextColor(BLUE);
ILI9806G_DispStringLine_EN(LINE(7),"Draw Rect:");
LCD_SetTextColor(RED);
ILI9806G_DrawRectangle(50,300,200,100,1);
LCD_SetTextColor(GREEN);
ILI9806G_DrawRectangle(100,300,200,120,0);
LCD_SetTextColor(BLUE);
ILI9806G_DrawRectangle(250,300,200,150,1);
Delay(0x2FFFFFF);
ILI9806G_Clear(0,32*7,LCD_X_LENGTH,LCD_Y_LENGTH–32*7);/* 清屏,显示全黑 */
/* 画圆 */
ILI9806G_ClearLine(LINE(7));/* 清除单行文字 */
LCD_SetTextColor(BLUE);
ILI9806G_DispStringLine_EN(LINE(7),"Draw Cir:");
LCD_SetTextColor(RED);
ILI9806G_DrawCircle(150,400,60,1);
LCD_SetTextColor(GREEN);
ILI9806G_DrawCircle(250,400,60,0);
LCD_SetTextColor(BLUE);
ILI9806G_DrawCircle(350,400,60,1);
Delay(0x2FFFFFF);
ILI9806G_Clear(0,32*7,LCD_X_LENGTH,LCD_Y_LENGTH–32*7);/* 清屏,显示全黑 */
}
/**
* @brief 简单延时函数
* @param nCount :延时计数值
* @retval 无
*/
static void Delay ( __IO uint32_t nCount )
{
for ( ; nCount != 0; nCount — );
}
/*********************************************END OF FILE**********************/

