一.设置液晶显示窗口
根据液晶屏的要求,在发送显示数据前,需要先设置显示窗口确定后面发送的像素数据的显示区域。下面的0x2A和0x2B分别对应的是y轴与x轴的命令。

/********** ILI934 命令 ********************************/ #define CMD_SetCoordinateX 0x2A // 设置 X 坐标 #define CMD_SetCoordinateY 0x2B // 设置 Y 坐标 /** * @brief 在 ILI9341 显示器上开辟一个窗口 * @param usX :在特定扫描方向下窗口的起点 X 坐标 * @param usY :在特定扫描方向下窗口的起点 Y 坐标 * @param usWidth :窗口的宽度 * @param usHeight :窗口的高度 * @retval 无 */ void ILI9341_OpenWindow ( uint16_t usX, uint16_t usY, uint16_t usWidth, uint16_t usHeight ) { ILI9341_Write_Cmd ( CMD_SetCoordinateX ); /* 设置 X 坐标 */ ILI9341_Write_Data ( usX >> 8 ); /* 先高 8 位,然后低 8 位 */ ILI9341_Write_Data ( usX & 0xff ); /* 设置起始点和结束点 */ ILI9341_Write_Data ( ( usX + usWidth - 1 ) >> 8 ); ILI9341_Write_Data ( ( usX + usWidth - 1 ) & 0xff ); ILI9341_Write_Cmd ( CMD_SetCoordinateY ); /* 设置 Y 坐标 */ ILI9341_Write_Data ( usY >> 8 ); ILI9341_Write_Data ( usY & 0xff ); ILI9341_Write_Data ( ( usY + usHeight - 1 ) >> 8 ); ILI9341_Write_Data ( ( usY + usHeight - 1 ) & 0xff ); } |
代码中定义的 ILI9341_OpenWindow 函数实现了图 设置显示窗口的 X 坐标 及图 设置液晶显示窗口的 Y 坐标 的 0x2A 和 0x2B 命令,它们分别用于设置显示窗口的起始及结束的 X 坐标和 Y 坐标,每个命令后包含 4 个 8 位的参数,这些参数组合后成起始坐标和结束坐标各 1 个用 16 位表示的值。ILI9341_OpenWindow 把它的四个函数输入参数 X 、 Y 起始坐标,宽度、高度转化成命令参数的格式,写入到液晶屏中,从而设置出一个显示窗口。
二.发送像素数据
调用上面的 ILI9341_OpenWindow 函数设置显示窗口后,再向液晶屏发送像素数据时,这些数据就会直接显示在它设定的窗口位置中。
#define CMD_SetPixel 0x2C // 填充像素 /** * @brief 在 ILI9341 显示器上以某一颜色填充像素点 * @param ulAmout_Point :要填充颜色的像素点的总数目 * @param usColor :颜色 * @retval 无 */ static __inline void ILI9341_FillColor ( uint32_t ulAmout_Point, uint16_t usColor ) { uint32_t i = 0 ; /* memory write */ ILI9341_Write_Cmd ( CMD_SetPixel ); for ( i = 0 ; i < ulAmout_Point; i ++ ) ILI9341_Write_Data ( usColor ); } |
发送像素数据的命令非常简单,首先发送命令代码 0x2C,然后后面紧跟着要传输的像素数据即
可。按照本液晶屏的配置,像素点的格式为 RGB565 ,所以像素数据就是要显示的 RGB565 格式
的颜色值。 本 ILI9341_FillColor 函数包含两个输入参数,分别用于设置要发送的像素数据个数 ulAmout_Point 及像素点的颜色值 usColor ,在代码实现中它调用 ILI9341_Write_Cmd 发送一次命令代码,接着使用 for 循环调用 ILI9341_Write_Data 写入 ulAmout_Po int 个同样的颜色值。这些颜色值会按顺序填充到前面使用 ILI9341_OpenWindow 函数设置的显示窗口中,例如,若设置了一个usX=10 , usY=30 , usWidth=50 , usHeight=20 的窗口,然后再连续填充 50*20 个颜色值为 0XFFFF 的像素数据,即可在 (10,30) 的起始坐标处显示一个宽 50 像素高 20 像素的白色矩形。
三.设置液晶的扫描方向
控制液晶屏时,还有一个非常重要的参数,就是设置液晶屏的扫描方向.
#define ILI9341_LESS_PIXEL 240 // 液晶屏较短方向的像素宽度 #define ILI9341_MORE_PIXEL 320 // 液晶屏较长方向的像素宽度 // 根据液晶扫描方向而变化的 XY 像素宽度 // 调用 ILI9341_GramScan 函数设置方向时会自动更改 uint16_t LCD_X_LENGTH = ILI9341_LESS_PIXEL; uint16_t LCD_Y_LENGTH = ILI9341_MORE_PIXEL; // 液晶屏扫描模式,本变量主要用于方便选择触摸屏的计算参数 // 参数可选值为 0-7 // 调用 ILI9341_GramScan 函数设置方向时会自动更改 //LCD 刚初始化完成时会使用本默认值 uint8_t LCD_SCAN_MODE = 6 ; /** * @brief 设置 ILI9341 的 GRAM 的扫描方向 * @param ucOption :选择 GRAM 的扫描方向 * @arg 0-7 : 参数可选值为 0-7 这八个方向 * * !!!其中 0 、 3 、 5 、 6 模式适合从左至右显示文字, * 不推荐使用其它模式显示文字 其它模式显示文字会有镜像效果 * * 其中 0 、 2 、 4 、 6 模式的 X 方向像素为 240 , Y 方向像素为 320 * 其中 1 、 3 、 5 、 7 模式下 X 方向像素为 320 , Y 方向像素为 240 * * 其中 6 模式为大部分液晶例程的默认显示方向 * 其中 3 模式为摄像头例程使用的方向 * 其中 0 模式为 BMP 图片显示例程使用的方向 * * @retval 无 * @note 坐标图例:A 表示向上, V 表示向下, < 表示向左, > 表示向右 X 表示 X 轴,Y 表示 Y 轴 *******************************************************/ void ILI9341_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 方向像素宽度为 240 , Y 方向为 320 LCD_X_LENGTH = ILI9341_LESS_PIXEL; LCD_Y_LENGTH = ILI9341_MORE_PIXEL; } else { //1 3 5 7 模式下 X 方向像素宽度为 320 , Y 方向为 240 LCD_X_LENGTH = ILI9341_MORE_PIXEL; LCD_Y_LENGTH = ILI9341_LESS_PIXEL; } //0x36 命令参数的高 3 位可用于设置 GRAM 扫描方向 ILI9341_Write_Cmd ( 0x36 ); ILI9341_Write_Data ( 0x08 | (ucOption << 5 )); // 根据 ucOption 的值设置 LCD 参 数,共 0-7 种模式 ILI9341_Write_Cmd ( CMD_SetCoordinateX ); ILI9341_Write_Data ( 0x00 ); /* x 起始坐标高 8 位 */ ILI9341_Write_Data ( 0x00 ); /* x 起始坐标低 8 位 */ ILI9341_Write_Data ( ((LCD_X_LENGTH -1 ) >> 8 ) & 0xFF ); /* x 结束坐标高 8 位 */ ILI9341_Write_Data ( (LCD_X_LENGTH -1 ) & 0xFF ); /* x 结束坐标低 8 位 */ ILI9341_Write_Cmd ( CMD_SetCoordinateY ); ILI9341_Write_Data ( 0x00 ); /* y 起始坐标高 8 位 */ ILI9341_Write_Data ( 0x00 ); /* y 起始坐标低 8 位 */ ILI9341_Write_Data ( ((LCD_Y_LENGTH -1 ) >> 8 ) & 0xFF ); /*y 结束坐标高 8 位 */ ILI9341_Write_Data ( (LCD_Y_LENGTH -1 ) & 0xFF ); /*y 结束坐标低 8 位 */ /* write gram start */ ILI9341_Write_Cmd ( CMD_SetPixel ); } |
液晶屏的 8 种扫描模式

当设置了液晶显示窗口,再连续向液晶屏写入像素点时,它会一个点一个点地往液晶屏的 X 方
向填充,填充完一行 X 方向的像素点后,向 Y 方向下移一行, X 坐标回到起始位置,再往 X 方
向一个点一个点地填充,如此循环直至填充完整个显示窗口。
而屏幕的坐标原点和 XY 方向都可以根据实际需要使用 0X36 命令来配置的。0X36 命令参数中的 MY 、 MX 、 MV 这三个数据位用于配置扫描方向,因此一共有 2^ 3 = 8 种模式。
ILI9341_GramScan 函数就是根据输入的模式设置这三个数据位,并且根据相应的模式更改 XY 方
向的分辨率 LCD_X_LENGTH 和 LCD_Y_LENGTH ,使得其它函数可以利用这两个全局变量获屏
幕实际的 XY 方向分辨率信息;同时,函数内还设置了全局变量 LCD_SCAN_MODE 的值用于记
录当前的屏幕扫描模式,这在后面计算触摸屏坐标的时候会使用到。设置完扫描方向后,代码中
还调用设置液晶显示窗口的命令 CMD_SetCoordinateX/Y ( 0X2A/0X2B 命令)默认打开一个与屏
幕大小一致的显示窗口,方便后续的显示操作。
其中模式 6 最符合我们的阅读习惯,扫描方向与文字方向一致,都是从左到右,从上到下,所以
本开发板中的大部分液晶程序都是默认使用模式 6 。
其实模式 0 、 3 、 5 、 6 的液晶扫描方向都与文字方向一致,比较适合显示文字,只要适当旋转屏
幕即可,使得用屏幕四个边沿作为正面看去都有适合的文字显示模式。而其它模式由于扫描方向
与文字方向不一致,要想实现同样的效果非常麻烦,也没有实现的必要。