day28:画矩形、画点、画直线、画圆
其他文件和day27一样
bsp_ili9341_lcd.h
#ifndef __BSP_ILI9341_LCD_H__ #define __BSP_ILI9341_LCD_H__ #include "stm32f10x.h" /* ------------------------------- 变量宏定义 ------------------------------ */ // CS(NSS)引脚 片选选普通GPIO即可 #define ILI9341_CS_CLK RCC_APB2Periph_GPIOC #define ILI9341_CS_PORT GPIOC #define ILI9341_CS_PIN GPIO_Pin_4 // RD引脚 片选选普通GPIO即可 #define ILI9341_RD_CLK RCC_APB2Periph_GPIOC #define ILI9341_RD_PORT GPIOC #define ILI9341_RD_PIN GPIO_Pin_5 // WE引脚 片选选普通GPIO即可 #define ILI9341_WE_CLK RCC_APB2Periph_GPIOC #define ILI9341_WE_PORT GPIOC #define ILI9341_WE_PIN GPIO_Pin_6 // DC引脚 片选选普通GPIO即可 #define ILI9341_DC_CLK RCC_APB2Periph_GPIOC #define ILI9341_DC_PORT GPIOC #define ILI9341_DC_PIN GPIO_Pin_7 // BK引脚 片选选普通GPIO即可 #define ILI9341_BK_CLK RCC_APB2Periph_GPIOD #define ILI9341_BK_PORT GPIOD #define ILI9341_BK_PIN GPIO_Pin_2 // D0-D15引脚 片选选普通GPIO即可(数据引脚) #define ILI9341_DATA_CLK RCC_APB2Periph_GPIOB #define ILI9341_DATA_PORT GPIOB #define ILI9341_DATA_PIN GPIO_Pin_All /******************************* 定义 ILI934 常用命令 ********************************/ #define CMD_SetCoordinateX 0x2A //设置X坐标 #define CMD_SetCoordinateY 0x2B //设置Y坐标 #define CMD_SetPixel 0x2C //填充像素 #define ILI9341_LESS_PIXEL 240 //液晶屏较短方向的像素宽度 #define ILI9341_MORE_PIXEL 320 //液晶屏较长方向的像素宽度 /******************************* 定义 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 /* ------------------------------- 函数宏定义 ------------------------------ */ // BK:背光引脚的GPIO打开或关闭 #define LCD_BK_ON() GPIO_ResetBits(ILI9341_BK_PORT, ILI9341_BK_PIN) #define LCD_BK_OFF() GPIO_SetBits(ILI9341_BK_PORT, ILI9341_BK_PIN) // CS #define LCD_CS_HIGH() GPIO_SetBits(ILI9341_CS_PORT, ILI9341_CS_PIN) #define LCD_CS_LOW() GPIO_ResetBits(ILI9341_CS_PORT, ILI9341_CS_PIN) // RD #define LCD_RD_HIGH() GPIO_SetBits(ILI9341_RD_PORT, ILI9341_RD_PIN) #define LCD_RD_LOW() GPIO_ResetBits(ILI9341_RD_PORT, ILI9341_RD_PIN) // WE #define LCD_WE_HIGH() GPIO_SetBits(ILI9341_WE_PORT, ILI9341_WE_PIN) #define LCD_WE_LOW() GPIO_ResetBits(ILI9341_WE_PORT, ILI9341_WE_PIN) // DC #define LCD_DC_HIGH() GPIO_SetBits(ILI9341_DC_PORT, ILI9341_DC_PIN) #define LCD_DC_LOW() GPIO_ResetBits(ILI9341_DC_PORT, ILI9341_DC_PIN) // D0-D15 #define LCD_DATA_OUT(data) GPIO_Write(ILI9341_DATA_PORT, data) // ILI9341_DATA_PORT->ODR = data #define LCD_DATA_IN() GPIO_ReadInputData(ILI9341_DATA_PORT) /* 初始化delay */ #define DEBUG_DELAY() ILI9341_Delay(0xFFFF) /* ------------------------------- 函数 ------------------------------ */ /* ILI9341初始化 */ void ILI9341_GPIO_Init(void); /* ILI9341绘制图形初始化 */ void ILI9341_Init(void); /* 写命令 */ void ILI9341_Write_Cmd(uint16_t cmd); /* 写数据 */ void ILI9341_Write_Data(uint16_t data); /* 读数据 */ uint16_t ILI9341_Read_Data(void); /* 读取ID */ uint16_t ILI9341_Read_ID(void); /* 设置要显示的矩形区域 */ void ILI9341_Open_Window(uint16_t x, uint16_t y, uint16_t width, uint16_t height); //画矩形 void ILI9341_Draw_Rect(uint16_t x,uint16_t y,uint16_t width, uint16_t heigh,uint16_t color); #endif /* __BSP_ILI9341_LCD_H__ */
bsp_ili9341_lcd.c
/*
1.初始化跟液晶控制相关的引脚
初始化时要确认配置GPIOB使用的PB3/PB4引脚,
需要重定义才能用作普通GPIO
2.模拟8080时序
写命令
写数据
读数据
3.通过读取ILI9341的ID测试函数
4.初始化液晶屏及配置扫描方向
5.往LCD坐标x,y写一个特定颜色像素点
*/
#include "./lcd/bsp_ili9341_lcd.h"
/*
根据液晶扫描方向而变化的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;
// 这里定义一个宏,目的是不用大幅度修改代码,方便程序维护
#define ILI9341_DELAY() //ILI9341_Delay(10)
static void ILI9341_Delay(__IO uint32_t nCount)
{
for(; nCount!=0; nCount--);
}
/* ILI9341初始化 */
void ILI9341_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*
把PB3,PB4引脚用作普通GPIO
因为PB3和PB4引脚和JTAG功能引脚共用,所以要把JTAG功能禁用,让PB3和PB4引脚可以使用
*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); // 使能复用时钟AFIO
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
/* 使能引脚相关的时钟 */
RCC_APB2PeriphClockCmd(ILI9341_CS_CLK|
ILI9341_RD_CLK|
ILI9341_WE_CLK|
ILI9341_DC_CLK|
ILI9341_BK_CLK|
ILI9341_DATA_CLK, ENABLE);
/* 默认全配置成输出模式 */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
// CS
GPIO_InitStructure.GPIO_Pin = ILI9341_CS_PIN;
GPIO_Init(ILI9341_CS_PORT, &GPIO_InitStructure);
// RD
GPIO_InitStructure.GPIO_Pin = ILI9341_RD_PIN;
GPIO_Init(ILI9341_RD_PORT, &GPIO_InitStructure);
// WE
GPIO_InitStructure.GPIO_Pin = ILI9341_WE_PIN;
GPIO_Init(ILI9341_DC_PORT, &GPIO_InitStructure);
// DC
GPIO_InitStructure.GPIO_Pin = ILI9341_DC_PIN;
GPIO_Init(ILI9341_WE_PORT, &GPIO_InitStructure);
// BK
GPIO_InitStructure.GPIO_Pin = ILI9341_BK_PIN;
GPIO_Init(ILI9341_BK_PORT, &GPIO_InitStructure);
// D0-D15
GPIO_InitStructure.GPIO_Pin = ILI9341_DATA_PIN;
GPIO_Init(ILI9341_DATA_PORT, &GPIO_InitStructure);
// 默认点亮背光
LCD_BK_ON();
}
/* 写命令:根据时序写 */
void ILI9341_Write_Cmd(uint16_t cmd)
{
LCD_CS_LOW();
ILI9341_DELAY();
LCD_DC_LOW();
ILI9341_DELAY();
LCD_RD_HIGH();
ILI9341_DELAY();
LCD_DATA_OUT(cmd);
ILI9341_DELAY();
LCD_WE_LOW();
ILI9341_DELAY();
LCD_WE_HIGH();
ILI9341_DELAY();
LCD_CS_HIGH();
}
/* 写数据:根据时序写 */
void ILI9341_Write_Data(uint16_t data)
{
LCD_CS_LOW();
ILI9341_DELAY();
LCD_DC_HIGH(); /* 和写命令的区别,这里DC为高电平 */
ILI9341_DELAY();
LCD_RD_HIGH();
ILI9341_DELAY();
LCD_DATA_OUT(data);
ILI9341_DELAY();
LCD_WE_LOW();
ILI9341_DELAY();
LCD_WE_HIGH();
ILI9341_DELAY();
LCD_CS_HIGH();
}
/* 读数据:根据时序写 */
uint16_t ILI9341_Read_Data()
{
uint16_t data = 0;
// 切换data端口为输入模式【因为输出模式常用,输入不常用,所以默认定义成输出模式】
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = ILI9341_DATA_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(ILI9341_DATA_PORT, &GPIO_InitStructure);
/* 根据时序写 */
LCD_CS_LOW();
ILI9341_DELAY();
LCD_DC_HIGH();
ILI9341_DELAY();
LCD_WE_HIGH();
ILI9341_DELAY();
LCD_RD_LOW();
ILI9341_DELAY();
data = LCD_DATA_IN(); /* 读取到的数据 */
ILI9341_DELAY();
LCD_RD_HIGH();
ILI9341_DELAY();
LCD_CS_HIGH();
/* 切换data端口为输出模式,方便其他方法使用 */
GPIO_InitStructure.GPIO_Pin = ILI9341_DATA_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(ILI9341_DATA_PORT, &GPIO_InitStructure);
// 返回数据
return data;
}
/* 读取ID */
uint16_t ILI9341_Read_ID()
{
uint16_t temp = 0 ;
// 发送读取ID的命令:0XD3
ILI9341_Write_Cmd(0xD3);
// 读取前面两个用不到的字节
ILI9341_Read_Data();
ILI9341_Read_Data();
// 开始正式的读取数据
temp = ILI9341_Read_Data();
// 将读取到的数据向左移动8位,腾出位置
temp <<= 8;
// 继续读取数据放到temp变量中
temp |= ILI9341_Read_Data();
// 返回读取到的ID数据
return temp;
}
/**
* @brief 初始化ILI9341寄存器
* @param 无
* @retval 无
*/
void ILI9341_REG_Config ( void )
{
/* Power control B (CFh) */
DEBUG_DELAY();
ILI9341_Write_Cmd ( 0xCF );
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0x81 );
ILI9341_Write_Data ( 0x30 );
/* Power on sequence control (EDh) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xED );
ILI9341_Write_Data ( 0x64 );
ILI9341_Write_Data ( 0x03 );
ILI9341_Write_Data ( 0x12 );
ILI9341_Write_Data ( 0x81 );
/* Driver timing control A (E8h) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xE8 );
ILI9341_Write_Data ( 0x85 );
ILI9341_Write_Data ( 0x10 );
ILI9341_Write_Data ( 0x78 );
/* Power control A (CBh) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xCB );
ILI9341_Write_Data ( 0x39 );
ILI9341_Write_Data ( 0x2C );
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0x34 );
ILI9341_Write_Data ( 0x02 );
/* Pump ratio control (F7h) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xF7 );
ILI9341_Write_Data ( 0x20 );
/* Driver timing control B */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xEA );
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0x00 );
/* Frame Rate Control (In Normal Mode/Full Colors) (B1h) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xB1 );
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0x1B );
/* Display Function Control (B6h) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xB6 );
ILI9341_Write_Data ( 0x0A );
ILI9341_Write_Data ( 0xA2 );
/* Power Control 1 (C0h) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xC0 );
ILI9341_Write_Data ( 0x35 );
/* Power Control 2 (C1h) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xC1 );
ILI9341_Write_Data ( 0x11 );
/* VCOM Control 1 (C5h) */
ILI9341_Write_Cmd ( 0xC5 );
ILI9341_Write_Data ( 0x45 );
ILI9341_Write_Data ( 0x45 );
/* VCOM Control 2 (C7h) */
ILI9341_Write_Cmd ( 0xC7 );
ILI9341_Write_Data ( 0xA2 );
/* Enable 3G (F2h) */
ILI9341_Write_Cmd ( 0xF2 );
ILI9341_Write_Data ( 0x00 );
/* Gamma Set (26h) */
ILI9341_Write_Cmd ( 0x26 );
ILI9341_Write_Data ( 0x01 );
DEBUG_DELAY ();
/* Positive Gamma Correction */
ILI9341_Write_Cmd ( 0xE0 ); //Set Gamma
ILI9341_Write_Data ( 0x0F );
ILI9341_Write_Data ( 0x26 );
ILI9341_Write_Data ( 0x24 );
ILI9341_Write_Data ( 0x0B );
ILI9341_Write_Data ( 0x0E );
ILI9341_Write_Data ( 0x09 );
ILI9341_Write_Data ( 0x54 );
ILI9341_Write_Data ( 0xA8 );
ILI9341_Write_Data ( 0x46 );
ILI9341_Write_Data ( 0x0C );
ILI9341_Write_Data ( 0x17 );
ILI9341_Write_Data ( 0x09 );
ILI9341_Write_Data ( 0x0F );
ILI9341_Write_Data ( 0x07 );
ILI9341_Write_Data ( 0x00 );
/* Negative Gamma Correction (E1h) */
ILI9341_Write_Cmd ( 0XE1 ); //Set Gamma
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0x19 );
ILI9341_Write_Data ( 0x1B );
ILI9341_Write_Data ( 0x04 );
ILI9341_Write_Data ( 0x10 );
ILI9341_Write_Data ( 0x07 );
ILI9341_Write_Data ( 0x2A );
ILI9341_Write_Data ( 0x47 );
ILI9341_Write_Data ( 0x39 );
ILI9341_Write_Data ( 0x03 );
ILI9341_Write_Data ( 0x06 );
ILI9341_Write_Data ( 0x06 );
ILI9341_Write_Data ( 0x30 );
ILI9341_Write_Data ( 0x38 );
ILI9341_Write_Data ( 0x0F );
/* memory access control set */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0x36 );
ILI9341_Write_Data ( 0xC8 ); /*竖屏 左上角到 (起点)到右下角 (终点)扫描方式*/
DEBUG_DELAY ();
/* column address control set */
ILI9341_Write_Cmd ( CMD_SetCoordinateX );
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0xEF );
/* page address control set */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( CMD_SetCoordinateY );
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0x01 );
ILI9341_Write_Data ( 0x3F );
/* Pixel Format Set (3Ah) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0x3a );
ILI9341_Write_Data ( 0x55 );
/* Sleep Out (11h) */
ILI9341_Write_Cmd ( 0x11 );
ILI9341_Delay ( 0xAFFf<<2 );
DEBUG_DELAY ();
/* Display ON (29h) */
ILI9341_Write_Cmd ( 0x29 );
}
/**
* @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轴
------------------------------------------------------------
模式0: . 模式1: . 模式2: . 模式3:
A . A . A . A
| . | . | . |
Y . X . Y . X
0 . 1 . 2 . 3
<--- X0 o . <----Y1 o . 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 |
| |
| |
| |
| |
| |
| |
| |
| |
|-----------------|
屏幕正面(宽240,高320)
*******************************************************/
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 );
}
/* ILI9341绘制图形初始化 */
void ILI9341_Init()
{
// ILI9341的GPIO初始化
ILI9341_GPIO_Init();
// ILI9341寄存器初始化
ILI9341_REG_Config();
// 设置ILI9341的GRAM的扫描方向
ILI9341_GramScan(6); // 模式6
ILI9341_Draw_Rect(0,0,LCD_X_LENGTH,LCD_Y_LENGTH,BLACK); // 屏幕的初始化背景颜色是BLACK
}
/* 设置要显示的矩形区域 */
void ILI9341_Open_Window(uint16_t x, uint16_t y, uint16_t width, uint16_t heigh)
{
ILI9341_Write_Cmd(CMD_SetCoordinateX);
ILI9341_Write_Data( (x&0xFF00) >> 8); //sc高8位
ILI9341_Write_Data( (x&0xFF) ); //sc低8位
ILI9341_Write_Data( ((x+width-1) & 0xFF00) >> 8); //ec高8位
ILI9341_Write_Data( ((x+width-1)&0xFF) ); //ec低8位
ILI9341_Write_Cmd(CMD_SetCoordinateY);
ILI9341_Write_Data( (y&0xFF00) >> 8); //sp高8位
ILI9341_Write_Data( (y&0xFF) ); //sp低8位
ILI9341_Write_Data( ((y+heigh-1) & 0xFF00) >> 8); //ep高8位
ILI9341_Write_Data( ((y+heigh-1)&0xFF) ); //ep低8位
}
// 填充像素
void ILI9341_Draw_Rect(uint16_t x,uint16_t y,uint16_t width, uint16_t heigh,uint16_t color)
{
uint32_t i;
ILI9341_Open_Window(x,y,width,heigh);
ILI9341_Write_Cmd(CMD_SetPixel);
for(i=0;i<width*heigh;i++)
{
ILI9341_Write_Data(color);
}
}
main.c
#include "stm32f10x.h"
#include "./usart/bsp_usart.h"
#include "./led/bsp_led.h"
#include "./lcd/bsp_ili9341_lcd.h"
int main(void)
{
/* LED引脚初始化 */
//LED_GPIO_Config();
/* USART串口初始化 */
DEBUG_USART_Config();
printf("这是一个LCD实验\r\n");
/* ILI9341初始化(用ILI9341_Init替代) */
//ILI9341_GPIO_Init();
// 读取ID
printf("读取到的ID = %x\r\n\r\n", ILI9341_Read_ID());
// 绘图初始化
ILI9341_Init();
// 绘图区域
//ILI9341_Open_Window(0, 0, 100, 100);
// 画矩形(屏幕大小是:240*320,在中心画100*100的矩形,红色)
ILI9341_Draw_Rect(45, 110, 150, 100, RED);
while(1);
}
烧录进去,实现现象:

画点:
bsp_ili9341_lcd.h
// 画点 void ILI9341_Draw_Point(uint16_t x,uint16_t y,uint16_t color);
bsp_ili9341_lcd.c
// 画点
void ILI9341_Draw_Point(uint16_t x,uint16_t y,uint16_t color)
{
ILI9341_Open_Window(x,y,1,1);
ILI9341_Write_Cmd(CMD_SetPixel);
ILI9341_Write_Data(color);
}
main.c
#include "stm32f10x.h"
#include "./usart/bsp_usart.h"
#include "./led/bsp_led.h"
#include "./lcd/bsp_ili9341_lcd.h"
int main(void)
{
/* LED引脚初始化 */
//LED_GPIO_Config();
/* USART串口初始化 */
DEBUG_USART_Config();
printf("这是一个LCD实验\r\n");
/* ILI9341初始化(用ILI9341_Init替代) */
//ILI9341_GPIO_Init();
// 读取ID
printf("读取到的ID = %x\r\n\r\n", ILI9341_Read_ID());
// 绘图初始化
ILI9341_Init();
// 绘图区域
//ILI9341_Open_Window(0, 0, 100, 100);
// 画矩形(屏幕大小是:240*320,在中心画100*100的矩形,红色)
ILI9341_Draw_Rect(45, 110, 150, 100, RED);
// 画点
{
uint16_t i;
for(i=0; i<10; i++)
{
// 画5行点
ILI9341_Draw_Point(10*i, 10, GREEN);
ILI9341_Draw_Point(10*i, 20, BLUE);
ILI9341_Draw_Point(10*i, 30, RED);
ILI9341_Draw_Point(10*i, 40, YELLOW);
ILI9341_Draw_Point(10*i, 50, MAGENTA);
}
}
while(1);
}
实验结果:

画直线:
bsp_ili9341_lcd.h
// 画线
void ILI9341_Draw_Line(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,uint16_t color);
bsp_ili9341_lcd.c
/*
画线:x1,y1为起点坐标,x2,y2为终点坐标,color为直线颜色
*/
void ILI9341_Draw_Line(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,uint16_t color)
{
uint16_t x, k, y, min, max;
k = (y2-y1)/(x2-x1);
if(x1==x2)
{
min = y1>y2?y2:y1;
max = y1>y2?y1:y2;
for(y=min; y<max; y++)
{
y+=5; // 需要画虚线就加这句
ILI9341_Draw_Point(x1,y,color);
}
}
else
{
min = x1>x2?x2:x1;
max = x1>x2?x1:x2;
for(x=min; x<max; x++)
{
x+=5;
y = k*(x-x1) + y1;
ILI9341_Draw_Point(x,y,color);
}
}
}
main.c
// 画线 ILI9341_Draw_Line(0, 0, 1, RED);
实验结果:

bsp_ili9341_lcd.h
#ifndef __BSP_ILI9341_LCD_H__ #define __BSP_ILI9341_LCD_H__ #include "stm32f10x.h" /* ------------------------------- 变量宏定义 ------------------------------ */ // CS(NSS)引脚 片选选普通GPIO即可 #define ILI9341_CS_CLK RCC_APB2Periph_GPIOC #define ILI9341_CS_PORT GPIOC #define ILI9341_CS_PIN GPIO_Pin_4 // RD引脚 片选选普通GPIO即可 #define ILI9341_RD_CLK RCC_APB2Periph_GPIOC #define ILI9341_RD_PORT GPIOC #define ILI9341_RD_PIN GPIO_Pin_5 // WE引脚 片选选普通GPIO即可 #define ILI9341_WE_CLK RCC_APB2Periph_GPIOC #define ILI9341_WE_PORT GPIOC #define ILI9341_WE_PIN GPIO_Pin_6 // DC引脚 片选选普通GPIO即可 #define ILI9341_DC_CLK RCC_APB2Periph_GPIOC #define ILI9341_DC_PORT GPIOC #define ILI9341_DC_PIN GPIO_Pin_7 // BK引脚 片选选普通GPIO即可 #define ILI9341_BK_CLK RCC_APB2Periph_GPIOD #define ILI9341_BK_PORT GPIOD #define ILI9341_BK_PIN GPIO_Pin_2 // D0-D15引脚 片选选普通GPIO即可(数据引脚) #define ILI9341_DATA_CLK RCC_APB2Periph_GPIOB #define ILI9341_DATA_PORT GPIOB #define ILI9341_DATA_PIN GPIO_Pin_All /******************************* 定义 ILI934 常用命令 ********************************/ #define CMD_SetCoordinateX 0x2A //设置X坐标 #define CMD_SetCoordinateY 0x2B //设置Y坐标 #define CMD_SetPixel 0x2C //填充像素 #define ILI9341_LESS_PIXEL 240 //液晶屏较短方向的像素宽度 #define ILI9341_MORE_PIXEL 320 //液晶屏较长方向的像素宽度 /******************************* 定义 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 #define PI 3.141592653 /* ------------------------------- 函数宏定义 ------------------------------ */ // BK:背光引脚的GPIO打开或关闭 #define LCD_BK_ON() GPIO_ResetBits(ILI9341_BK_PORT, ILI9341_BK_PIN) #define LCD_BK_OFF() GPIO_SetBits(ILI9341_BK_PORT, ILI9341_BK_PIN) // CS #define LCD_CS_HIGH() GPIO_SetBits(ILI9341_CS_PORT, ILI9341_CS_PIN) #define LCD_CS_LOW() GPIO_ResetBits(ILI9341_CS_PORT, ILI9341_CS_PIN) // RD #define LCD_RD_HIGH() GPIO_SetBits(ILI9341_RD_PORT, ILI9341_RD_PIN) #define LCD_RD_LOW() GPIO_ResetBits(ILI9341_RD_PORT, ILI9341_RD_PIN) // WE #define LCD_WE_HIGH() GPIO_SetBits(ILI9341_WE_PORT, ILI9341_WE_PIN) #define LCD_WE_LOW() GPIO_ResetBits(ILI9341_WE_PORT, ILI9341_WE_PIN) // DC #define LCD_DC_HIGH() GPIO_SetBits(ILI9341_DC_PORT, ILI9341_DC_PIN) #define LCD_DC_LOW() GPIO_ResetBits(ILI9341_DC_PORT, ILI9341_DC_PIN) // D0-D15 #define LCD_DATA_OUT(data) GPIO_Write(ILI9341_DATA_PORT, data) // ILI9341_DATA_PORT->ODR = data #define LCD_DATA_IN() GPIO_ReadInputData(ILI9341_DATA_PORT) /* 初始化delay */ #define DEBUG_DELAY() ILI9341_Delay(0xFFFF) /* ------------------------------- 函数 ------------------------------ */ /* ILI9341初始化 */ void ILI9341_GPIO_Init(void); /* ILI9341绘制图形初始化 */ void ILI9341_Init(void); /* 写命令 */ void ILI9341_Write_Cmd(uint16_t cmd); /* 写数据 */ void ILI9341_Write_Data(uint16_t data); /* 读数据 */ uint16_t ILI9341_Read_Data(void); /* 读取ID */ uint16_t ILI9341_Read_ID(void); /* 设置要显示的矩形区域 */ void ILI9341_Open_Window(uint16_t x, uint16_t y, uint16_t width, uint16_t height); // 画矩形 void ILI9341_Draw_Rect(uint16_t x,uint16_t y,uint16_t width, uint16_t heigh,uint16_t color); // 画点 void ILI9341_Draw_Point(uint16_t x,uint16_t y,uint16_t color); // 画线 void ILI9341_Draw_Line(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,uint16_t color); // 画圆 void ILI9341_Draw_Circle(uint16_t x,uint16_t y,uint16_t r,uint16_t color); #endif /* __BSP_ILI9341_LCD_H__ */
bsp_ili9341_lcd.c
/*
1.初始化跟液晶控制相关的引脚
初始化时要确认配置GPIOB使用的PB3/PB4引脚,
需要重定义才能用作普通GPIO
2.模拟8080时序
写命令
写数据
读数据
3.通过读取ILI9341的ID测试函数
4.初始化液晶屏及配置扫描方向
5.往LCD坐标x,y写一个特定颜色像素点
*/
#include "./lcd/bsp_ili9341_lcd.h"
#include "math.h"
/*
根据液晶扫描方向而变化的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;
// 这里定义一个宏,目的是不用大幅度修改代码,方便程序维护
#define ILI9341_DELAY() //ILI9341_Delay(10)
static void ILI9341_Delay(__IO uint32_t nCount)
{
for(; nCount!=0; nCount--);
}
/* ILI9341初始化 */
void ILI9341_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*
把PB3,PB4引脚用作普通GPIO
因为PB3和PB4引脚和JTAG功能引脚共用,所以要把JTAG功能禁用,让PB3和PB4引脚可以使用
*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); // 使能复用时钟AFIO
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
/* 使能引脚相关的时钟 */
RCC_APB2PeriphClockCmd(ILI9341_CS_CLK|
ILI9341_RD_CLK|
ILI9341_WE_CLK|
ILI9341_DC_CLK|
ILI9341_BK_CLK|
ILI9341_DATA_CLK, ENABLE);
/* 默认全配置成输出模式 */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
// CS
GPIO_InitStructure.GPIO_Pin = ILI9341_CS_PIN;
GPIO_Init(ILI9341_CS_PORT, &GPIO_InitStructure);
// RD
GPIO_InitStructure.GPIO_Pin = ILI9341_RD_PIN;
GPIO_Init(ILI9341_RD_PORT, &GPIO_InitStructure);
// WE
GPIO_InitStructure.GPIO_Pin = ILI9341_WE_PIN;
GPIO_Init(ILI9341_DC_PORT, &GPIO_InitStructure);
// DC
GPIO_InitStructure.GPIO_Pin = ILI9341_DC_PIN;
GPIO_Init(ILI9341_WE_PORT, &GPIO_InitStructure);
// BK
GPIO_InitStructure.GPIO_Pin = ILI9341_BK_PIN;
GPIO_Init(ILI9341_BK_PORT, &GPIO_InitStructure);
// D0-D15
GPIO_InitStructure.GPIO_Pin = ILI9341_DATA_PIN;
GPIO_Init(ILI9341_DATA_PORT, &GPIO_InitStructure);
// 默认点亮背光
LCD_BK_ON();
}
/* 写命令:根据时序写 */
void ILI9341_Write_Cmd(uint16_t cmd)
{
LCD_CS_LOW();
ILI9341_DELAY();
LCD_DC_LOW();
ILI9341_DELAY();
LCD_RD_HIGH();
ILI9341_DELAY();
LCD_DATA_OUT(cmd);
ILI9341_DELAY();
LCD_WE_LOW();
ILI9341_DELAY();
LCD_WE_HIGH();
ILI9341_DELAY();
LCD_CS_HIGH();
}
/* 写数据:根据时序写 */
void ILI9341_Write_Data(uint16_t data)
{
LCD_CS_LOW();
ILI9341_DELAY();
LCD_DC_HIGH(); /* 和写命令的区别,这里DC为高电平 */
ILI9341_DELAY();
LCD_RD_HIGH();
ILI9341_DELAY();
LCD_DATA_OUT(data);
ILI9341_DELAY();
LCD_WE_LOW();
ILI9341_DELAY();
LCD_WE_HIGH();
ILI9341_DELAY();
LCD_CS_HIGH();
}
/* 读数据:根据时序写 */
uint16_t ILI9341_Read_Data()
{
uint16_t data = 0;
// 切换data端口为输入模式【因为输出模式常用,输入不常用,所以默认定义成输出模式】
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = ILI9341_DATA_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(ILI9341_DATA_PORT, &GPIO_InitStructure);
/* 根据时序写 */
LCD_CS_LOW();
ILI9341_DELAY();
LCD_DC_HIGH();
ILI9341_DELAY();
LCD_WE_HIGH();
ILI9341_DELAY();
LCD_RD_LOW();
ILI9341_DELAY();
data = LCD_DATA_IN(); /* 读取到的数据 */
ILI9341_DELAY();
LCD_RD_HIGH();
ILI9341_DELAY();
LCD_CS_HIGH();
/* 切换data端口为输出模式,方便其他方法使用 */
GPIO_InitStructure.GPIO_Pin = ILI9341_DATA_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(ILI9341_DATA_PORT, &GPIO_InitStructure);
// 返回数据
return data;
}
/* 读取ID */
uint16_t ILI9341_Read_ID()
{
uint16_t temp = 0 ;
// 发送读取ID的命令:0XD3
ILI9341_Write_Cmd(0xD3);
// 读取前面两个用不到的字节
ILI9341_Read_Data();
ILI9341_Read_Data();
// 开始正式的读取数据
temp = ILI9341_Read_Data();
// 将读取到的数据向左移动8位,腾出位置
temp <<= 8;
// 继续读取数据放到temp变量中
temp |= ILI9341_Read_Data();
// 返回读取到的ID数据
return temp;
}
/**
* @brief 初始化ILI9341寄存器
* @param 无
* @retval 无
*/
void ILI9341_REG_Config ( void )
{
/* Power control B (CFh) */
DEBUG_DELAY();
ILI9341_Write_Cmd ( 0xCF );
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0x81 );
ILI9341_Write_Data ( 0x30 );
/* Power on sequence control (EDh) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xED );
ILI9341_Write_Data ( 0x64 );
ILI9341_Write_Data ( 0x03 );
ILI9341_Write_Data ( 0x12 );
ILI9341_Write_Data ( 0x81 );
/* Driver timing control A (E8h) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xE8 );
ILI9341_Write_Data ( 0x85 );
ILI9341_Write_Data ( 0x10 );
ILI9341_Write_Data ( 0x78 );
/* Power control A (CBh) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xCB );
ILI9341_Write_Data ( 0x39 );
ILI9341_Write_Data ( 0x2C );
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0x34 );
ILI9341_Write_Data ( 0x02 );
/* Pump ratio control (F7h) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xF7 );
ILI9341_Write_Data ( 0x20 );
/* Driver timing control B */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xEA );
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0x00 );
/* Frame Rate Control (In Normal Mode/Full Colors) (B1h) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xB1 );
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0x1B );
/* Display Function Control (B6h) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xB6 );
ILI9341_Write_Data ( 0x0A );
ILI9341_Write_Data ( 0xA2 );
/* Power Control 1 (C0h) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xC0 );
ILI9341_Write_Data ( 0x35 );
/* Power Control 2 (C1h) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0xC1 );
ILI9341_Write_Data ( 0x11 );
/* VCOM Control 1 (C5h) */
ILI9341_Write_Cmd ( 0xC5 );
ILI9341_Write_Data ( 0x45 );
ILI9341_Write_Data ( 0x45 );
/* VCOM Control 2 (C7h) */
ILI9341_Write_Cmd ( 0xC7 );
ILI9341_Write_Data ( 0xA2 );
/* Enable 3G (F2h) */
ILI9341_Write_Cmd ( 0xF2 );
ILI9341_Write_Data ( 0x00 );
/* Gamma Set (26h) */
ILI9341_Write_Cmd ( 0x26 );
ILI9341_Write_Data ( 0x01 );
DEBUG_DELAY ();
/* Positive Gamma Correction */
ILI9341_Write_Cmd ( 0xE0 ); //Set Gamma
ILI9341_Write_Data ( 0x0F );
ILI9341_Write_Data ( 0x26 );
ILI9341_Write_Data ( 0x24 );
ILI9341_Write_Data ( 0x0B );
ILI9341_Write_Data ( 0x0E );
ILI9341_Write_Data ( 0x09 );
ILI9341_Write_Data ( 0x54 );
ILI9341_Write_Data ( 0xA8 );
ILI9341_Write_Data ( 0x46 );
ILI9341_Write_Data ( 0x0C );
ILI9341_Write_Data ( 0x17 );
ILI9341_Write_Data ( 0x09 );
ILI9341_Write_Data ( 0x0F );
ILI9341_Write_Data ( 0x07 );
ILI9341_Write_Data ( 0x00 );
/* Negative Gamma Correction (E1h) */
ILI9341_Write_Cmd ( 0XE1 ); //Set Gamma
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0x19 );
ILI9341_Write_Data ( 0x1B );
ILI9341_Write_Data ( 0x04 );
ILI9341_Write_Data ( 0x10 );
ILI9341_Write_Data ( 0x07 );
ILI9341_Write_Data ( 0x2A );
ILI9341_Write_Data ( 0x47 );
ILI9341_Write_Data ( 0x39 );
ILI9341_Write_Data ( 0x03 );
ILI9341_Write_Data ( 0x06 );
ILI9341_Write_Data ( 0x06 );
ILI9341_Write_Data ( 0x30 );
ILI9341_Write_Data ( 0x38 );
ILI9341_Write_Data ( 0x0F );
/* memory access control set */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0x36 );
ILI9341_Write_Data ( 0xC8 ); /*竖屏 左上角到 (起点)到右下角 (终点)扫描方式*/
DEBUG_DELAY ();
/* column address control set */
ILI9341_Write_Cmd ( CMD_SetCoordinateX );
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0xEF );
/* page address control set */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( CMD_SetCoordinateY );
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0x00 );
ILI9341_Write_Data ( 0x01 );
ILI9341_Write_Data ( 0x3F );
/* Pixel Format Set (3Ah) */
DEBUG_DELAY ();
ILI9341_Write_Cmd ( 0x3a );
ILI9341_Write_Data ( 0x55 );
/* Sleep Out (11h) */
ILI9341_Write_Cmd ( 0x11 );
ILI9341_Delay ( 0xAFFf<<2 );
DEBUG_DELAY ();
/* Display ON (29h) */
ILI9341_Write_Cmd ( 0x29 );
}
/**
* @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轴
------------------------------------------------------------
模式0: . 模式1: . 模式2: . 模式3:
A . A . A . A
| . | . | . |
Y . X . Y . X
0 . 1 . 2 . 3
<--- X0 o . <----Y1 o . 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 |
| |
| |
| |
| |
| |
| |
| |
| |
|-----------------|
屏幕正面(宽240,高320)
*******************************************************/
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 );
}
/* ILI9341绘制图形初始化 */
void ILI9341_Init()
{
// ILI9341的GPIO初始化
ILI9341_GPIO_Init();
// ILI9341寄存器初始化
ILI9341_REG_Config();
// 设置ILI9341的GRAM的扫描方向
ILI9341_GramScan(6); // 模式6
ILI9341_Draw_Rect(0,0,LCD_X_LENGTH,LCD_Y_LENGTH,BLACK); // 屏幕的初始化背景颜色是BLACK
}
/* 设置要显示的矩形区域 */
void ILI9341_Open_Window(uint16_t x, uint16_t y, uint16_t width, uint16_t heigh)
{
ILI9341_Write_Cmd(CMD_SetCoordinateX);
ILI9341_Write_Data( (x&0xFF00) >> 8); //sc高8位
ILI9341_Write_Data( (x&0xFF) ); //sc低8位
ILI9341_Write_Data( ((x+width-1) & 0xFF00) >> 8); //ec高8位
ILI9341_Write_Data( ((x+width-1)&0xFF) ); //ec低8位
ILI9341_Write_Cmd(CMD_SetCoordinateY);
ILI9341_Write_Data( (y&0xFF00) >> 8); //sp高8位
ILI9341_Write_Data( (y&0xFF) ); //sp低8位
ILI9341_Write_Data( ((y+heigh-1) & 0xFF00) >> 8); //ep高8位
ILI9341_Write_Data( ((y+heigh-1)&0xFF) ); //ep低8位
}
// 填充像素
void ILI9341_Draw_Rect(uint16_t x,uint16_t y,uint16_t width, uint16_t heigh,uint16_t color)
{
uint32_t i;
ILI9341_Open_Window(x,y,width,heigh);
ILI9341_Write_Cmd(CMD_SetPixel);
for(i=0;i<width*heigh;i++)
{
ILI9341_Write_Data(color);
}
}
// 画点
void ILI9341_Draw_Point(uint16_t x,uint16_t y,uint16_t color)
{
ILI9341_Open_Window(x,y,1,1);
ILI9341_Write_Cmd(CMD_SetPixel);
ILI9341_Write_Data(color);
}
/*
画线:x1,y1为起点坐标,x2,y2为终点坐标,color为直线颜色
*/
void ILI9341_Draw_Line(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,uint16_t color)
{
uint16_t x, k, y, min, max;
k = (y2-y1)/(x2-x1);
if(x1==x2)
{
min = y1>y2?y2:y1;
max = y1>y2?y1:y2;
for(y=min; y<max; y++)
{
y+=5;
ILI9341_Draw_Point(x1,y,color);
}
}
else
{
min = x1>x2?x2:x1;
max = x1>x2?x1:x2;
for(x=min; x<max; x++)
{
x+=5;
y = k*(x-x1) + y1;
ILI9341_Draw_Point(x,y,color);
}
}
}
/*
画圆:x,y为圆心坐标,r为圆半径,color为圆颜色
*/
void ILI9341_Draw_Circle(uint16_t x,uint16_t y,uint16_t r,uint16_t color)
{
uint16_t i, x1, y1, y2;
ILI9341_Draw_Point(x, y, color); // 画圆心
// 画圆轨迹
for(i=x-r; i<=x+r; i++)
{
x1 = i;
y1 = y + sqrt(pow(r, 2)-pow(x1-x, 2));
y2 = y - sqrt(pow(r, 2)-pow(x1-x, 2));
ILI9341_Draw_Point(x1, y1, color);
ILI9341_Draw_Point(x1, y2, color);
}
}
main.c
#include "stm32f10x.h"
#include "./usart/bsp_usart.h"
#include "./led/bsp_led.h"
#include "./lcd/bsp_ili9341_lcd.h"
void Delay(__IO uint32_t nCount)
{
for(; nCount != 0; nCount--);
}
int main(void)
{
/* LED引脚初始化 */
//LED_GPIO_Config();
/* USART串口初始化 */
DEBUG_USART_Config();
printf("这是一个LCD实验\r\n");
/* ILI9341初始化(用ILI9341_Init替代) */
//ILI9341_GPIO_Init();
// 读取ID
printf("读取到的ID = %x\r\n\r\n", ILI9341_Read_ID());
// 绘图初始化
ILI9341_Init();
// 绘图区域
//ILI9341_Open_Window(0, 0, 100, 100);
// 画矩形(屏幕大小是:240*320,在中心画100*100的矩形,红色)
//ILI9341_Draw_Rect(45, 110, 150, 100, RED);
// 画5行点
/*
{
uint16_t i;
for(i=0; i<10; i++)
{
ILI9341_Draw_Point(10*i, 10, GREEN);
ILI9341_Draw_Point(10*i, 20, BLUE);
ILI9341_Draw_Point(10*i, 30, RED);
ILI9341_Draw_Point(10*i, 40, YELLOW);
ILI9341_Draw_Point(10*i, 50, MAGENTA);
}
}
*/
// 画线
ILI9341_Draw_Line(0, ILI9341_MORE_PIXEL/2, ILI9341_LESS_PIXEL, ILI9341_MORE_PIXEL/2, GREY);
ILI9341_Draw_Line(ILI9341_LESS_PIXEL/2, 0, ILI9341_LESS_PIXEL/2, ILI9341_MORE_PIXEL, GREY);
// 画圆:动画圆
while(1){
uint16_t i, COLOR;
for(i=0; i<13; i++)
{
switch(i)
{
case 0:
COLOR = WHITE;
break;
case 1:
COLOR = BLUE;
break;
case 2:
COLOR = RED;
break;
case 3:
COLOR = MAGENTA;
break;
case 4:
COLOR = GREEN;
break;
case 5:
COLOR = CYAN;
break;
case 6:
COLOR = YELLOW;
break;
case 7:
COLOR = BRED;
break;
case 8:
COLOR = BLUE;
break;
case 9:
COLOR = GREEN;
break;
case 10:
COLOR = GREY;
break;
case 11:
COLOR = RED;
break;
case 12:
COLOR = MAGENTA;
break;
default:
break;
}
ILI9341_Draw_Circle(ILI9341_LESS_PIXEL/2, ILI9341_MORE_PIXEL/2, 10*i, COLOR);
}
}
while(1);
}
实验结果:


浙公网安备 33010602011771号