基于STM32 GPIO模拟8080时序操作ILI9341-学习笔记12

1、我本人使用是野火STM32指南者开发板。

2、LCD为ILI9341,3.2英寸屏幕,分辨率320*240.

3、了解8080时序通信原理,及学会使用LCD液晶屏。

4、本次实验可能是由于硬件原因设计原因吧,数据线上没有上拉电阻,当读取LCD屏发来的数据时,数据端口配置上拉输入或下拉输入均读取数据异常,本次我配置为浮空输入就没有问题,另外数据端口配置为开漏模式也是可以的。

5、本次用到的数据线为16条,对应的端口为Proc_D、Proc_E

6、本次用到的纳秒延迟是不精确的大概125纳秒吧,也是尽量小,但不能太小要满足通信要求。

7、现场图片后面在添加,反正后面还需要加入字符串的输出显示。

8、感觉不错的可以点赞关注一下哈,感谢!

main.c

#include "stm32f10x.h"
#include "stdio.h"
#include "./usart/usart.h"
#include "./ili9341/ili9341.h"

uint16_t buff[200*150];

int main(void)
{
	usart_init_config();//串口初始化
	LCD_init_config();//初始化lcd液晶屏


	Read_LCD_REG(LCD_Read_Pixel_Cmd,buff);//读取显示点格式
	printf("\r\nbuff=%x",buff[1]);

	Read_LCD_REG(LCD_Read_ID_Cmd,buff);//读取id值
	printf("\r\nbuff=%x",buff[1]);
	printf("\r\nbuff=%x",buff[2]);
	printf("\r\nbuff=%x",buff[3]);
	
	LCD_Fill_Color(0,0,LCD_SCREEN_XRES,30,buff,LCD_RED);

	while(1);
}


ILI9341.C

//作者:金丝草
#include "./ili9341/ili9341.h"

static LCD_Data_Union LCD_Data;//lcd输入输出数据
static LCD_Port_Union Port_D;//lcd数据引脚对应端口D
static LCD_Port_Union Port_E;//lcd数据引脚对应端口E

static void LCD_GPIO_init_config(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	//打开GPIO外设时钟
	LCD_All_GPIO_Clk_EN(LCD_RCC_Periph_GPIOD_Clk,ENABLE);
	LCD_All_GPIO_Clk_EN(LCD_RCC_Periph_GPIOE_Clk,ENABLE);
	//配置GPIO_Data
	GPIO_InitStruct.GPIO_Mode  =GPIO_Mode_Out_PP;//推挽输出
	GPIO_InitStruct.GPIO_Speed =GPIO_Speed_50MHz;

	GPIO_InitStruct.GPIO_Pin   =LCD_Data0_Pin;
	GPIO_Init(LCD_Data0_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data1_Pin;
	GPIO_Init(LCD_Data1_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data2_Pin;
	GPIO_Init(LCD_Data2_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data3_Pin;
	GPIO_Init(LCD_Data3_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data4_Pin;
	GPIO_Init(LCD_Data4_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data5_Pin;
	GPIO_Init(LCD_Data5_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data6_Pin;
	GPIO_Init(LCD_Data6_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data7_Pin;
	GPIO_Init(LCD_Data7_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data8_Pin;
	GPIO_Init(LCD_Data8_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data9_Pin;
	GPIO_Init(LCD_Data9_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data10_Pin;
	GPIO_Init(LCD_Data10_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data11_Pin;
	GPIO_Init(LCD_Data11_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data12_Pin;
	GPIO_Init(LCD_Data12_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data13_Pin;
	GPIO_Init(LCD_Data13_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data14_Pin;
	GPIO_Init(LCD_Data14_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data15_Pin;
	GPIO_Init(LCD_Data15_Port,&GPIO_InitStruct);
	//配置复位引脚
	GPIO_InitStruct.GPIO_Mode  =GPIO_Mode_Out_PP;//推挽输出
	GPIO_InitStruct.GPIO_Speed =GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_Pin   =LCD_Reset_Pin;
	GPIO_Init(LCD_Reset_Port,&GPIO_InitStruct);
	//配置背光引脚
	GPIO_InitStruct.GPIO_Pin   =LCD_BLK_Pin;
	GPIO_Init(LCD_BLK_Port,&GPIO_InitStruct);
	//配置片选引脚
	GPIO_InitStruct.GPIO_Pin   =LCD_CS_Pin;
	GPIO_Init(LCD_CS_Port,&GPIO_InitStruct);
	//配置读取引脚
	GPIO_InitStruct.GPIO_Pin   =LCD_Read_Pin;
	GPIO_Init(LCD_Read_Port,&GPIO_InitStruct);
	//配置写入引脚
	GPIO_InitStruct.GPIO_Pin   =LCD_Write_Pin;
	GPIO_Init(LCD_Write_Port,&GPIO_InitStruct);
	//配置命令数据引脚
	GPIO_InitStruct.GPIO_Pin   =LCD_RS_Pin;
	GPIO_Init(LCD_RS_Port,&GPIO_InitStruct);
}

static void Write_Data(uint16_t data_)
{
	LCD_Data.Data_16_bits = data_;

	#if 0
	if(LCD_Data.bits.bit0) GPIO_SetBits(LCD_Data0_Port,LCD_Data0_Pin);
	else GPIO_ResetBits(LCD_Data0_Port,LCD_Data0_Pin);
	if(LCD_Data.bits.bit1) GPIO_SetBits(LCD_Data1_Port,LCD_Data1_Pin);
	else GPIO_ResetBits(LCD_Data1_Port,LCD_Data1_Pin);
	if(LCD_Data.bits.bit2) GPIO_SetBits(LCD_Data2_Port,LCD_Data2_Pin);
	else GPIO_ResetBits(LCD_Data2_Port,LCD_Data2_Pin);
	if(LCD_Data.bits.bit3) GPIO_SetBits(LCD_Data3_Port,LCD_Data3_Pin);
	else GPIO_ResetBits(LCD_Data3_Port,LCD_Data3_Pin);
	if(LCD_Data.bits.bit4) GPIO_SetBits(LCD_Data4_Port,LCD_Data4_Pin);
	else GPIO_ResetBits(LCD_Data4_Port,LCD_Data4_Pin);
	if(LCD_Data.bits.bit5) GPIO_SetBits(LCD_Data5_Port,LCD_Data5_Pin);
	else GPIO_ResetBits(LCD_Data5_Port,LCD_Data5_Pin);
	if(LCD_Data.bits.bit6) GPIO_SetBits(LCD_Data6_Port,LCD_Data6_Pin);
	else GPIO_ResetBits(LCD_Data6_Port,LCD_Data6_Pin);
	if(LCD_Data.bits.bit7) GPIO_SetBits(LCD_Data7_Port,LCD_Data7_Pin);
	else GPIO_ResetBits(LCD_Data7_Port,LCD_Data7_Pin);
	if(LCD_Data.bits.bit8) GPIO_SetBits(LCD_Data8_Port,LCD_Data8_Pin);
	else GPIO_ResetBits(LCD_Data8_Port,LCD_Data8_Pin);
	if(LCD_Data.bits.bit9) GPIO_SetBits(LCD_Data9_Port,LCD_Data9_Pin);
	else GPIO_ResetBits(LCD_Data9_Port,LCD_Data9_Pin);
	if(LCD_Data.bits.bit10) GPIO_SetBits(LCD_Data10_Port,LCD_Data10_Pin);
	else GPIO_ResetBits(LCD_Data10_Port,LCD_Data10_Pin);
	if(LCD_Data.bits.bit11) GPIO_SetBits(LCD_Data11_Port,LCD_Data11_Pin);
	else GPIO_ResetBits(LCD_Data11_Port,LCD_Data11_Pin);
	if(LCD_Data.bits.bit12) GPIO_SetBits(LCD_Data12_Port,LCD_Data12_Pin);
	else GPIO_ResetBits(LCD_Data12_Port,LCD_Data12_Pin);
	if(LCD_Data.bits.bit13) GPIO_SetBits(LCD_Data13_Port,LCD_Data13_Pin);
	else GPIO_ResetBits(LCD_Data13_Port,LCD_Data13_Pin);
	if(LCD_Data.bits.bit14) GPIO_SetBits(LCD_Data14_Port,LCD_Data14_Pin);
	else GPIO_ResetBits(LCD_Data14_Port,LCD_Data14_Pin);
	if(LCD_Data.bits.bit15) GPIO_SetBits(LCD_Data15_Port,LCD_Data15_Pin);
	else GPIO_ResetBits(LCD_Data15_Port,LCD_Data15_Pin);
	#else
	Port_D.Data_16_bits = GPIO_ReadOutputData(GPIOD);
	Port_E.Data_16_bits = GPIO_ReadOutputData(GPIOE);

	Port_D.bits.Pin_14  = LCD_Data.bits.bit0;
	Port_D.bits.Pin_15  = LCD_Data.bits.bit1;
	Port_D.bits.Pin_0   = LCD_Data.bits.bit2;
	Port_D.bits.Pin_1   = LCD_Data.bits.bit3;
	Port_E.bits.Pin_7   = LCD_Data.bits.bit4;
	Port_E.bits.Pin_8   = LCD_Data.bits.bit5;
	Port_E.bits.Pin_9   = LCD_Data.bits.bit6;
	Port_E.bits.Pin_10  = LCD_Data.bits.bit7;
	Port_E.bits.Pin_11  = LCD_Data.bits.bit8;
	Port_E.bits.Pin_12  = LCD_Data.bits.bit9;
	Port_E.bits.Pin_13  = LCD_Data.bits.bit10;
	Port_E.bits.Pin_14  = LCD_Data.bits.bit11;
	Port_E.bits.Pin_15  = LCD_Data.bits.bit12;
	Port_D.bits.Pin_8   = LCD_Data.bits.bit13;
	Port_D.bits.Pin_9   = LCD_Data.bits.bit14;
	Port_D.bits.Pin_10  = LCD_Data.bits.bit15;

	GPIO_Write(GPIOD,Port_D.Data_16_bits);
	GPIO_Write(GPIOE,Port_E.Data_16_bits);
	#endif
}
static uint16_t Read_Data(void)
{
	Port_D.Data_16_bits = GPIO_ReadInputData(GPIOD);
	Port_E.Data_16_bits = GPIO_ReadInputData(GPIOE);

	LCD_Data.bits.bit0  = Port_D.bits.Pin_14;
	LCD_Data.bits.bit1  = Port_D.bits.Pin_15;
	LCD_Data.bits.bit2  = Port_D.bits.Pin_0;
	LCD_Data.bits.bit3  = Port_D.bits.Pin_1;
	LCD_Data.bits.bit4  = Port_E.bits.Pin_7;
	LCD_Data.bits.bit5  = Port_E.bits.Pin_8;
	LCD_Data.bits.bit6  = Port_E.bits.Pin_9;
	LCD_Data.bits.bit7  = Port_E.bits.Pin_10;
	LCD_Data.bits.bit8  = Port_E.bits.Pin_11;
	LCD_Data.bits.bit9  = Port_E.bits.Pin_12;
	LCD_Data.bits.bit10 = Port_E.bits.Pin_13;
	LCD_Data.bits.bit11 = Port_E.bits.Pin_14;
	LCD_Data.bits.bit12 = Port_E.bits.Pin_15;
	LCD_Data.bits.bit13 = Port_D.bits.Pin_8;
	LCD_Data.bits.bit14 = Port_D.bits.Pin_9;
	LCD_Data.bits.bit15 = Port_D.bits.Pin_10;
	
	return LCD_Data.Data_16_bits;
}

static void LCD_GPIO_data_config_output(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	Write_Data(0xffff);
	//配置GPIO_Data
	GPIO_InitStruct.GPIO_Mode  =GPIO_Mode_Out_PP;//推挽输出
	GPIO_InitStruct.GPIO_Speed =GPIO_Speed_50MHz;

	GPIO_InitStruct.GPIO_Pin   =LCD_Data0_Pin;
	GPIO_Init(LCD_Data0_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data1_Pin;
	GPIO_Init(LCD_Data1_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data2_Pin;
	GPIO_Init(LCD_Data2_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data3_Pin;
	GPIO_Init(LCD_Data3_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data4_Pin;
	GPIO_Init(LCD_Data4_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data5_Pin;
	GPIO_Init(LCD_Data5_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data6_Pin;
	GPIO_Init(LCD_Data6_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data7_Pin;
	GPIO_Init(LCD_Data7_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data8_Pin;
	GPIO_Init(LCD_Data8_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data9_Pin;
	GPIO_Init(LCD_Data9_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data10_Pin;
	GPIO_Init(LCD_Data10_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data11_Pin;
	GPIO_Init(LCD_Data11_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data12_Pin;
	GPIO_Init(LCD_Data12_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data13_Pin;
	GPIO_Init(LCD_Data13_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data14_Pin;
	GPIO_Init(LCD_Data14_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data15_Pin;
	GPIO_Init(LCD_Data15_Port,&GPIO_InitStruct);
}
static void LCD_GPIO_data_config_intput(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	//Write_Data(0xffff);
	//配置GPIO_Data
	GPIO_InitStruct.GPIO_Mode  =GPIO_Mode_IN_FLOATING;//浮空输入模式,或者开漏输出模式
	GPIO_InitStruct.GPIO_Speed =GPIO_Speed_50MHz;

	GPIO_InitStruct.GPIO_Pin   =LCD_Data0_Pin;
	GPIO_Init(LCD_Data0_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data1_Pin;
	GPIO_Init(LCD_Data1_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data2_Pin;
	GPIO_Init(LCD_Data2_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data3_Pin;
	GPIO_Init(LCD_Data3_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data4_Pin;
	GPIO_Init(LCD_Data4_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data5_Pin;
	GPIO_Init(LCD_Data5_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data6_Pin;
	GPIO_Init(LCD_Data6_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data7_Pin;
	GPIO_Init(LCD_Data7_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data8_Pin;
	GPIO_Init(LCD_Data8_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data9_Pin;
	GPIO_Init(LCD_Data9_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data10_Pin;
	GPIO_Init(LCD_Data10_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data11_Pin;
	GPIO_Init(LCD_Data11_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data12_Pin;
	GPIO_Init(LCD_Data12_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data13_Pin;
	GPIO_Init(LCD_Data13_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data14_Pin;
	GPIO_Init(LCD_Data14_Port,&GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin   =LCD_Data15_Pin;
	GPIO_Init(LCD_Data15_Port,&GPIO_InitStruct);
	
}

///LCD读写驱动封装函数///
static void LCD_Write(uint8_t cmd,uint16_t *intput_buff,uint32_t count)//建议使用此函数
{
	uint32_t i;

	LCD_CS_Enable;
	LCD_RS_Enable;
	LCD_Read_Disable;
	LCD_Write_Enable;
	Write_Data(cmd);
	delay_125ns();
	LCD_Write_Disable;
	delay_125ns();
	LCD_RS_Disable;
	for (i = 0; i < count; i++)
	{
		LCD_Write_Enable;
		Write_Data(intput_buff[i]);
		delay_125ns();
		LCD_Write_Disable;
		delay_125ns();
	}
	LCD_CS_Disable;
}
static void LCD_Read(uint8_t cmd,uint16_t *output_buff,uint32_t count)//建议使用此函数
{
	uint32_t i;
	LCD_CS_Enable;    //使能片选
	LCD_RS_Enable;   //命令
	LCD_Read_Disable; //关闭读使能
	LCD_Write_Enable; //写开始
	Write_Data(cmd);  //写命令
	delay_125ns();
	LCD_Write_Disable;//写结束
	delay_125ns();
	LCD_GPIO_data_config_intput();
	LCD_RS_Disable;  //数据
	for(i = 0;i < count;i++)
	{
		LCD_Read_Enable; //开始读数据
		delay_125ns();
		LCD_Read_Disable;//读结束
		output_buff[i]=Read_Data();//读取到的数据
		delay_125ns();
	}
	LCD_CS_Disable;
	LCD_GPIO_data_config_output();
}
///LCD读写驱动封装函数///

//ILI9341内部寄存器初始化
static void ILI9341_REG_Config(void)
{
	uint16_t REG_Buff[15];
	LCD_Reset_Disable;
	delay_ms(20);
	LCD_Reset_Enable;
	delay_ms(200);
	LCD_Reset_Disable;
	delay_ms(100);
/*  Power control B (CFh)  */
	REG_Buff[0]=0x00;REG_Buff[1]=0x81;REG_Buff[2]=0x30;
	LCD_Write(0xCF,REG_Buff,3);
	/*  Power on sequence control (EDh) */
	REG_Buff[0]=0x64;REG_Buff[1]=0x03;REG_Buff[2]=0x12;REG_Buff[3]=0x81;
	LCD_Write(0xED,REG_Buff,4);
	/*  Driver timing control A (E8h) */
	REG_Buff[0]=0x85;REG_Buff[1]=0x10;REG_Buff[2]=0x78;
	LCD_Write(0xE8,REG_Buff,3);
	/*  Power control A (CBh) */
	REG_Buff[0]=0x39;REG_Buff[1]=0x2C;REG_Buff[2]=0x00;REG_Buff[3]=0x34;
	REG_Buff[4]=0x02;
	LCD_Write(0xCB,REG_Buff,5);
	/* Pump ratio control (F7h) */
	REG_Buff[0]=0x20;
	LCD_Write(0xF7,REG_Buff,1);
	/* Driver timing control B */
	REG_Buff[0]=0x00;REG_Buff[1]=0x00;
	LCD_Write(0xEA,REG_Buff,2);
	/* Frame Rate Control (In Normal Mode/Full Colors) (B1h) */
	REG_Buff[0]=0x00;REG_Buff[1]=0x1B;
	LCD_Write(0xB1,REG_Buff,2);
	/*  Display Function Control (B6h) */
	REG_Buff[0]=0x0A;REG_Buff[1]=0xA2;
	LCD_Write(0xB6,REG_Buff,2);
	/* Power Control 1 (C0h) */
	REG_Buff[0]=0x35;
	LCD_Write(0xC0,REG_Buff,1);
	/* Power Control 2 (C1h) */
	REG_Buff[0]=0x11;
	LCD_Write(0xC1,REG_Buff,1);
	/* VCOM Control 1 (C5h) */
	REG_Buff[0]=0x45;REG_Buff[1]=0x45;
	LCD_Write(0xC5,REG_Buff,2);
	/*  VCOM Control 2 (C7h)  */
	REG_Buff[0]=0xA2;
	LCD_Write(0xC7,REG_Buff,1);
	/* Enable 3G (F2h) */
	REG_Buff[0]=0x00;
	LCD_Write(0xF2,REG_Buff,1);
	/* Gamma Set (26h) */
	REG_Buff[0]=0x01;
	LCD_Write(0x26,REG_Buff,1);
	
	/* Positive Gamma Correction */
	REG_Buff[0]=0x0F;REG_Buff[1]=0x26;REG_Buff[2]=0x24;
	REG_Buff[3]=0x0B;REG_Buff[4]=0x0E;REG_Buff[5]=0x09;
	REG_Buff[6]=0x54;REG_Buff[7]=0xA8;REG_Buff[8]=0x46;
	REG_Buff[9]=0x0C;REG_Buff[10]=0x17;REG_Buff[11]=0x09;
	REG_Buff[12]=0x0F;REG_Buff[13]=0x07;REG_Buff[14]=0x00;
	LCD_Write(0xE0,REG_Buff,15);//Set Gamma
	
	/* Negative Gamma Correction (E1h) */
	REG_Buff[0]=0x00;REG_Buff[1]=0x19;REG_Buff[2]=0x1B;
	REG_Buff[3]=0x04;REG_Buff[4]=0x10;REG_Buff[5]=0x07;
	REG_Buff[6]=0x2A;REG_Buff[7]=0x47;REG_Buff[8]=0x39;
	REG_Buff[9]=0x03;REG_Buff[10]=0x06;REG_Buff[11]=0x06;
	REG_Buff[12]=0x30;REG_Buff[13]=0x38;REG_Buff[14]=0x0F;
	LCD_Write(0XE1,REG_Buff,15);//Set Gamma

	/* memory access control set */
	REG_Buff[0]=0xC8;
	LCD_Write(0x36,REG_Buff,1);/*竖屏  左上角到 (起点)到右下角 (终点)扫描方式*/
	
	/*  Pixel Format Set (3Ah)  */
	REG_Buff[0]=0x55;
	LCD_Write(0x3a,REG_Buff,1);

	/* Sleep Out (11h)  */
	LCD_Write(0x11,REG_Buff,0);
	delay_ms(200);
	/* Display ON (29h) */
	LCD_Write(0x29,REG_Buff,0);
	delay_ms(50);
}

void lcd_fill_color(uint16_t color);//lcd整个屏幕填充颜色速度应该慢点
void LCD_init_config(void)//lcd初始化总入口
{
	LCD_GPIO_init_config();
	LCD_BLK_Disable;
	LCD_CS_Disable;
	LCD_Read_Disable;
	LCD_Write_Disable;
	LCD_RS_Disable;
	ILI9341_REG_Config();
	lcd_fill_color(LCD_BLUE);
	LCD_BLK_Enable;
}

/以下为功能函数接口//
void Read_LCD_REG(uint8_t REG, uint16_t *output_buff)//读取lcd内部寄存器
{
	switch(REG)
	{
		case LCD_Read_Pixel_Cmd:LCD_Read(LCD_Read_Pixel_Cmd,output_buff,2);break;
		case LCD_Read_ID_Cmd:LCD_Read(LCD_Read_ID_Cmd,output_buff,4);break;
	}
}

//lcd屏开窗及颜色填充/
static void lcd_set_window(uint16_t sx,uint16_t sy,uint16_t ex,uint16_t ey)
{
	uint16_t window_data[4];

	window_data[0] = sx >> 8;
	window_data[1] = sx & 0xff;
	window_data[2] = ex >> 8;
	window_data[3] = ex & 0xff;
	LCD_Write(0x2a,window_data,4);//设定X坐标,lcd屏进行长的开窗

	window_data[0] = sy >> 8;
	window_data[1] = sy & 0xff;
	window_data[2] = ey >> 8;
	window_data[3] = ey & 0xff;
	LCD_Write(0x2b,window_data,4);//设定Y坐标,lcd屏进行宽的开窗
}
static void lcd_fill_data(uint16_t sx,uint16_t sy,uint16_t ex,uint16_t ey, uint16_t *intput_buff,uint32_t size)//此lcd屏数据线为16条,故2字节数据传输
{
	lcd_set_window(sx,sy,ex,ey);//开窗
	LCD_Write(LCD_SetPixel_Cmd,intput_buff,size);//发送RGB注意lcd屏的接收格式是RGB还是BGR,为了阅读方便请配置为RGB格式
}
void LCD_Fill_Color(uint16_t sx,uint16_t sy,uint16_t ex,uint16_t ey,uint16_t *intput_buff,uint16_t color)//开窗且颜色进行填充
{
	uint32_t Area_size;//填充区域面积即填充个数
	uint32_t i;

	Area_size =(ex+1 - sx ) * (ey+1 - sy );
	for (i = 0; i < Area_size; i++)
	{
		intput_buff[i] = color;
	}
	lcd_fill_data(sx,sy,ex,ey,intput_buff,Area_size);
}
void lcd_fill_color(uint16_t color)//lcd整个屏幕填充颜色速度应该慢点
{
	uint32_t Area_size;//填充区域面积即填充个数
	uint32_t i;
	Area_size = (LCD_SCREEN_XRES+1)*(LCD_SCREEN_YRES+1);
	lcd_set_window(0,0,LCD_SCREEN_XRES,LCD_SCREEN_YRES);//整个屏幕

	LCD_CS_Enable;
	LCD_RS_Enable;
	LCD_Read_Disable;
	LCD_Write_Enable;
	Write_Data(LCD_SetPixel_Cmd);
	delay_125ns();
	LCD_Write_Disable;
	delay_125ns();
	LCD_RS_Disable;
	for(i=0;i<Area_size;i++)
	{
		LCD_Write_Enable;
		Write_Data(color);
		delay_125ns();
		LCD_Write_Disable;
		delay_125ns();
	}
	LCD_CS_Disable;
}
//lcd屏开窗及颜色填充/

ILI9341.h

//作者:金丝草
#ifndef __ILI9341_H__
#define __ILI9341_H__

#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "./delay/delay.h"

/* LCD屏幕分辨率320x240 */
#define LCD_SCREEN_XRES		239
#define LCD_SCREEN_YRES		319


//GPIO模拟LCD_8080进行通信
//控制引脚配置为推挽输出模式,数据引脚默认推完输出模式,当要读取的时候在零时配置为输入模式

/LCD对应的GPIO///
//lcd data PD14 PD15 PD0 PD1 PE7 PE8 PE9 PE10 PE11 PE12 PE13 PE14 PE15 PD8 PD9 PD10
//lcd switch PE1 PD12 PD7 PD4 PD5 PD11
//涉及到的时钟端口时钟端口D 端口E 且引脚外设均挂载外设时钟APP2上
#define LCD_RCC_Periph_GPIOD_Clk      RCC_APB2Periph_GPIOD
#define LCD_RCC_Periph_GPIOE_Clk      RCC_APB2Periph_GPIOE
#define LCD_All_GPIO_Clk_EN           RCC_APB2PeriphClockCmd//启动或者禁用RCC外围电路的时钟
//lcd对应的16位数据线
#define LCD_Data0_Port                GPIOD
#define LCD_Data0_Pin                 GPIO_Pin_14
#define LCD_Data1_Port                GPIOD
#define LCD_Data1_Pin                 GPIO_Pin_15
#define LCD_Data2_Port                GPIOD
#define LCD_Data2_Pin                 GPIO_Pin_0
#define LCD_Data3_Port                GPIOD
#define LCD_Data3_Pin                 GPIO_Pin_1
#define LCD_Data4_Port                GPIOE
#define LCD_Data4_Pin                 GPIO_Pin_7
#define LCD_Data5_Port                GPIOE
#define LCD_Data5_Pin                 GPIO_Pin_8
#define LCD_Data6_Port                GPIOE
#define LCD_Data6_Pin                 GPIO_Pin_9
#define LCD_Data7_Port                GPIOE
#define LCD_Data7_Pin                 GPIO_Pin_10
#define LCD_Data8_Port                GPIOE
#define LCD_Data8_Pin                 GPIO_Pin_11
#define LCD_Data9_Port                GPIOE
#define LCD_Data9_Pin                 GPIO_Pin_12
#define LCD_Data10_Port               GPIOE
#define LCD_Data10_Pin                GPIO_Pin_13
#define LCD_Data11_Port               GPIOE
#define LCD_Data11_Pin                GPIO_Pin_14
#define LCD_Data12_Port               GPIOE
#define LCD_Data12_Pin                GPIO_Pin_15
#define LCD_Data13_Port               GPIOD
#define LCD_Data13_Pin                GPIO_Pin_8
#define LCD_Data14_Port               GPIOD
#define LCD_Data14_Pin                GPIO_Pin_9
#define LCD_Data15_Port               GPIOD
#define LCD_Data15_Pin                GPIO_Pin_10
//lcd的复位引脚
#define LCD_Reset_Port                GPIOE
#define LCD_Reset_Pin                 GPIO_Pin_1
//lcd的背光脚
#define LCD_BLK_Port                  GPIOD
#define LCD_BLK_Pin                   GPIO_Pin_12
//lcd的片选脚
#define LCD_CS_Port                   GPIOD
#define LCD_CS_Pin                    GPIO_Pin_7
//lcd的读使能脚
#define LCD_Read_Port                 GPIOD
#define LCD_Read_Pin                  GPIO_Pin_4
//lcd的写使能脚
#define LCD_Write_Port                GPIOD
#define LCD_Write_Pin                 GPIO_Pin_5
//lcd的数据或命令脚
#define LCD_RS_Port                   GPIOD
#define LCD_RS_Pin                    GPIO_Pin_11
/LCD对应的GPIO///
//lcd复位控制
#define LCD_Reset_Enable              GPIO_ResetBits(LCD_Reset_Port,LCD_Reset_Pin)
#define LCD_Reset_Disable             GPIO_SetBits(LCD_Reset_Port,LCD_Reset_Pin)
//lcd背光控制
#define LCD_BLK_Enable                GPIO_ResetBits(LCD_BLK_Port,LCD_BLK_Pin)
#define LCD_BLK_Disable               GPIO_SetBits(LCD_BLK_Port,LCD_BLK_Pin)
//lcd片选控制
#define LCD_CS_Enable                 GPIO_ResetBits(LCD_CS_Port,LCD_CS_Pin)
#define LCD_CS_Disable                GPIO_SetBits(LCD_CS_Port,LCD_CS_Pin)
//lcd读控制
#define LCD_Read_Enable               GPIO_ResetBits(LCD_Read_Port,LCD_Read_Pin)
#define LCD_Read_Disable              GPIO_SetBits(LCD_Read_Port,LCD_Read_Pin)
//lcd写控制
#define LCD_Write_Enable              GPIO_ResetBits(LCD_Write_Port,LCD_Write_Pin)
#define LCD_Write_Disable             GPIO_SetBits(LCD_Write_Port,LCD_Write_Pin)
//lcd命令数据控制
#define LCD_RS_Enable                 GPIO_ResetBits(LCD_RS_Port,LCD_RS_Pin)
#define LCD_RS_Disable                GPIO_SetBits(LCD_RS_Port,LCD_RS_Pin)

/*lcd常用命令*/
#define	LCD_Read_Pixel_Cmd              0x0c//读取像素点格式
#define LCD_Read_ID_Cmd                 0xd3//读取lcd的id值
#define	LCD_Read_Dispaly_Power_Mode_Cmd 0x0a//读取显示电源模式
#define	LCD_SetCoordinateX_Cmd          0x2a//设置X坐标
#define	LCD_SetCoordinateY_Cmd          0x2b//设置Y坐标
#define	LCD_SetPixel_Cmd                0x2C//填充像素    


typedef union//stm32为小端模式
{
	uint16_t Data_16_bits;
	struct
	{
		uint16_t bit0  : 1;
		uint16_t bit1  : 1;
		uint16_t bit2  : 1;
		uint16_t bit3  : 1;
		uint16_t bit4  : 1;
		uint16_t bit5  : 1;
		uint16_t bit6  : 1;
		uint16_t bit7  : 1;
		uint16_t bit8  : 1;
		uint16_t bit9  : 1;
		uint16_t bit10 : 1;
		uint16_t bit11 : 1;
		uint16_t bit12 : 1;
		uint16_t bit13 : 1;
		uint16_t bit14 : 1;
		uint16_t bit15 : 1;
	}bits;
}LCD_Data_Union;
typedef union
{
	uint16_t Data_16_bits;
	struct
	{
		uint16_t Pin_0  : 1;
		uint16_t Pin_1  : 1;
		uint16_t Pin_2  : 1;
		uint16_t Pin_3  : 1;
		uint16_t Pin_4  : 1;
		uint16_t Pin_5  : 1;
		uint16_t Pin_6  : 1;
		uint16_t Pin_7  : 1;
		uint16_t Pin_8  : 1;
		uint16_t Pin_9  : 1;
		uint16_t Pin_10 : 1;
		uint16_t Pin_11 : 1;
		uint16_t Pin_12 : 1;
		uint16_t Pin_13 : 1;
		uint16_t Pin_14 : 1;
		uint16_t Pin_15 : 1;
	}bits;
}LCD_Port_Union;

///RGB565常用颜色对照表/
#define   LCD_BLACK     0x0000    //  黑色
#define   LCD_NAVY      0x000F    //  深蓝色
#define   LCD_DGREEN    0x03E0    //  深绿色
#define   LCD_DCYAN     0x03EF    //  深青色
#define   LCD_MAROON    0x7800    //  深红色
#define   LCD_PURPLE    0x780F    //  紫色
#define   LCD_OLIVE     0x7BE0    //  橄榄绿
#define   LCD_LGRAY     0xC618    //  灰白色
#define   LCD_DGRAY     0x7BEF    //  深灰色
#define   LCD_BLUE      0x001F    //  蓝色
#define   LCD_GREEN     0x07E0    //  绿色
#define   LCD_CYAN      0x07FF    //  青色
#define   LCD_RED       0xF800    //  红色
#define   LCD_MAGENTA   0xF81F    //  品红
#define   LCD_YELLOW    0xFFE0    //  黄色
#define   LCD_WHITE     0xFFFF    //  白色
///RGB565常用颜色对照表/


void LCD_init_config(void);//初始化lcd液晶屏
void Read_LCD_REG(uint8_t REG, uint16_t *output_buff);//读取lcd内部寄存器
void LCD_Fill_Color(uint16_t sx,uint16_t sy,uint16_t ex,uint16_t ey, uint16_t *intput_buff,uint16_t color);//开窗且颜色进行填充
void lcd_fill_color(uint16_t color);//lcd整个屏幕填充颜色速度应该慢点
void LCD_Puts(char *s);//lcd屏字符串的显示


#endif /*__ILI9341_H__*/

  • 7
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论
### 回答1: //以下是基于stm32f103 ili9341的驱动代码:#include "stm32f10x.h" #include "ili9341.h"//声明SPI1口硬件结构体变量 SPI_InitTypeDef SPI_InitStructure;//初始化SPI1口 void SPI_ILI9341_Init(void){ //使能SPI1口时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); //配置SPI1口 SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //双线双向全双工 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主模式 SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //数据大小为8位 SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //时钟极性,空闲时为高 SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //第二个边沿有效,即上升沿为采样时刻 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由软件产生 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; //波特率分频器,9MHz SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //高位在前 SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式 SPI_Init(SPI1, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器 //使能SPI1 SPI_Cmd(SPI1, ENABLE); }//读取ili9341状态 //返回值:状态值 uint16_t SPI_ILI9341_Read(void){ uint16_t data = 0; while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); //等待发送区空 SPI_I2S_SendData(SPI1, 0x00); //发送0x00,读取状态 while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); //等待接收完一个字 data = SPI_I2S_ReceiveData(SPI1); //返回状态值 return data; }//写入ili9341数据 //data:要写入的数据 void SPI_ILI9341_WriteData(uint16_t data){ while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); //等待发送区空 SPI_I2S_SendData(SPI1, data); //发送数据 } ### 回答2: stm32f103是一款32位ARM Cortex-M3内核的微控制器,而ili9341是一款2.2寸TFT液晶显示屏。下面是一个基于stm32f103和ili9341的驱动代码示例: 首先,需要包含相应的头文件和库文件。这包括stm32f103的相关头文件以及ili9341的驱动库文件。 #include "stm32f10x.h" #include "ili9341_driver.h" 然后,需要进行硬件初始化,包括设置GPIO口和SPI总线。 void ili9341_init(void) { /* 设置GPIO口和SPI总线 */ /* 向ILI9341发送初始化序列 */ ili9341_send_command(0xCB); ili9341_send_data(0x39); ili9341_send_data(0x2C); ... /* 设置其他初始化参数 */ /* 开启显示 */ ili9341_send_command(0x29); } 接下来,编写相关函数来进行ILI9341的控制。 void ili9341_set_pixel(uint16_t x, uint16_t y, uint16_t color) { /* 设置像素颜色 */ ili9341_send_command(0x2A); // 设置X坐标 ili9341_send_data(x >> 8); ili9341_send_data(x & 0xFF); ili9341_send_command(0x2B); // 设置Y坐标 ili9341_send_data(y >> 8); ili9341_send_data(y & 0xFF); ili9341_send_command(0x2C); // 写入颜色数据 ili9341_send_data(color >> 8); ili9341_send_data(color & 0xFF); } void ili9341_fill_screen(uint16_t color) { /* 填充整个屏幕 */ ili9341_send_command(0x2A); // 设置X坐标 ili9341_send_data(0 >> 8); ili9341_send_data(0 & 0xFF); ili9341_send_data((ILI9341_WIDTH - 1) >> 8); ili9341_send_data((ILI9341_WIDTH - 1) & 0xFF); ili9341_send_command(0x2B); // 设置Y坐标 ili9341_send_data(0 >> 8); ili9341_send_data(0 & 0xFF); ili9341_send_data((ILI9341_HEIGHT - 1) >> 8); ili9341_send_data((ILI9341_HEIGHT - 1) & 0xFF); ili9341_send_command(0x2C); // 写入颜色数据 for(uint16_t i = 0; i < ILI9341_WIDTH * ILI9341_HEIGHT; i++) { ili9341_send_data(color >> 8); ili9341_send_data(color & 0xFF); } } 通过以上代码,我们可以实现ILI9341的基本功能,包括设置像素和填充屏幕等。需要注意的是,以上代码只是一个示例,实际应用中还需要根据具体需求进行适当的修改和优化。 ### 回答3: STM32F103是一款32位的ARM Cortex-M3微控制器,而ILI9341是一款2.2寸TFT彩色LCD显示屏。以下是基于STM32F103和ILI9341的驱动代码示例: 首先,我们需要定义一些常量和变量: #define LCD_WIDTH 240 #define LCD_HEIGHT 320 #define LCD_COMMAND 0 #define LCD_DATA 1 然后,我们定义一些函数来操作控制IO口的初始化和设置: void LCD_GPIO_Init() { RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; GPIOB->CRL &= 0xFFFFFF00; //设置PB0-PB7为推挽输出模式 GPIOB->CRL |= 0x00000033; RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; GPIOC->CRH &= 0xFF00FFFF; //设置PC13为推挽输出模式 GPIOC->CRH |= 0x00300000; } void LCD_Write_Command(uint8_t cmd) { GPIOB->ODR &= ~(0xFF); //将数据线置低 GPIOC->BSRR = GPIO_BSRR_BR13; //将命令/数据线置低 GPIOB->ODR |= cmd; //将命令写入数据线 GPIOC->BSRR = GPIO_BSRR_BS13; //将命令/数据线置高 } void LCD_Write_Data(uint8_t data) { GPIOB->ODR &= ~(0xFF); //将数据线置低 GPIOC->BSRR = GPIO_BSRR_BS13; //将命令/数据线置高 GPIOB->ODR |= data; //将数据写入数据线 GPIOC->BSRR = GPIO_BSRR_BR13; //将命令/数据线置低 } 然后,我们定义一些高级函数来进行LCD屏幕的初始化和绘制操作: void LCD_Init() { LCD_GPIO_Init(); // 发送初始化命令 LCD_Write_Command(0xCF); // ... // 设置显示方向 LCD_Write_Command(0x36); LCD_Write_Data(0x08); // 清屏 LCD_Clear(); } void LCD_Clear() { // ... } void LCD_DrawPixel(int16_t x, int16_t y, uint16_t color) { if (x < 0 || x >= LCD_WIDTH || y < 0 || y >= LCD_HEIGHT) { return; } // 计算像素位置 uint32_t index = y * LCD_WIDTH + x; // 发送写像素命令 LCD_Write_Command(0x2C); // 设置像素数据 LCD_Write_Data(color >> 8); LCD_Write_Data(color & 0xFF); } 这些示例代码展示了如何初始化并使用STM32F103和ILI9341进行LCD显示操作。您可以根据这些示例代码进行进一步的开发和扩展,以满足实际需求。请注意,由于代码长度限制,这里只展示了一部分基本的操作,实际应用中可能涉及更多的功能和细节。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

金丝草

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值