2.8寸 ILI9341 TFTLCD 学习移植到STM32F103C8T6

2.8寸 ILI9341 TFTLCD 学习移植到STM32F103C8T6



前言

最近在做一个显示小实验,需要用STM32F103C8来驱动正点原子的2.8寸 TFTLCD屏进行功能显示,综合考虑了下该C8T6核心板的引脚资源是足够的,只要显示功能就基本够用了。该屏分辨率是 320×240 ,使用8080并口时序进行驱动,本文只用了LCD的显示功能部分,虽然这个屏是支持触摸功能,但是本文章没有使用到,节省了几个单片机IO口,注意使用的屏幕IC是ILI9341

下面的内容均是摘抄于正点原子开发板的开发指南和PPT等资料内容。


第1章 LCD简介

液晶显示器,即Liquid Crystal Display,其原理是利用了液晶导电后透光性可变的特性,配合显示器光源、彩色滤光片和电压控制等工艺,最终可以在液晶阵列上显示彩色的图像。简单理解就是由玻璃基板、背光、驱动IC等组成全彩LCD,是一种全彩显示屏,支持RGB565、RGB888显示颜色模式,所以该显示屏可以显示各种颜色。
目前液晶显示技术以 TN、STN、TFT 三种技术为主,TFTLCD 即采用了 TFT(Thin Film Transistor)薄膜晶体管技术的液晶显示器,也叫薄膜晶体管液晶显示器。
TFT-LCD 与无源 TN-LCD、STN-LCD 的简单矩阵不同的是,它在液晶显示屏的每一个象素上都设置有一个薄膜晶体管(TFT),可有效地克服非选通时的串扰,使显示液晶屏的静态特性与扫描线数无关,因此大大提高了图像质量。
2.8 寸的 TFTLCD 模块支持 65K 色显示,显示分辨率为 320×240,接口为 16 位的 8080 并口,自带触摸功能(本文没用到)。

1.1 LCD硬件接口介绍

LCD的引脚原理图如下图:

在这里插入图片描述

LCD屏幕对应板子引脚接线如下图:

2.8’ TFTLCD(显示部分引脚) STM32F103C8T6 MCU
CS PA3
BL PA4
RST PA5
RD PA6
WR PA7
RS PA8
D0~D15 PB0~PB15

LCD引脚功能介绍如下表:

在这里插入图片描述

第2章 LCD指令介绍

一般了解熟悉下表6条指令即可完成对 ILI9341 TFTLCD的基本显示功能了。

在这里插入图片描述
详细的指令用法描述,可以参考屏幕手册即可,这里就不详细展开了。

第3章 LCD 8080驱动方式

并口总线时序,常用于MCU屏驱动IC的访问,由Intel提出,也叫英特尔总线。

3.1 8080写时序

数据(RS=1)/命令(RS=0)在WR的上升沿,写入LCD驱动IC,RD保持高电平。

在这里插入图片描述

3.2 8080读时序

数据(RS=1)/命令(RS=0)在RD的上升沿,读取到MCU,WR保持高电平。

在这里插入图片描述

注意:上面的引脚名字是原子官方自定义的一个用于易记的名字,屏幕手册的名字对应如下表:
LCD 8080时序信号引脚说明如下表:

在这里插入图片描述

LCD 8080时序信号说明如下表:

在这里插入图片描述

第4章 LCD 驱动代码部分

拷贝STM32F103RCT6开发板的工程实验 TFTLCD实验HARDWARE下的LCD文件夹进行修改即可,大部分都不要修改,基本就改下引脚就可以了。

例程默认是做了很多款屏幕的兼容处理的,所以看起来比较复杂,代码量比较庞大,如果把没有相关屏幕的驱动删除就可以使工程代码比较简洁了,当然不处理也不影响功能的使用。

4.1 修改代码部分

lcd.h LCD引脚定义代码如下(部分示例):

//-----------------------LCD端口定义----------------------//
#define LCD_LED     PAout(4)            //LCD背光       PA4
#define LCD_RST     PAout(5)            //LCD复位       PA5

#define LCD_CS_SET  GPIOA->BSRR=1<<3    //片选端口      PA3
#define LCD_RS_SET  GPIOA->BSRR=1<<8    //数据/命令     PA8
#define LCD_WR_SET  GPIOA->BSRR=1<<7    //写数据        PA7
#define LCD_RD_SET  GPIOA->BSRR=1<<6    //读数据        PA6

#define LCD_CS_CLR  GPIOA->BRR=1<<3     //片选端口      PA3
#define LCD_RS_CLR  GPIOA->BRR=1<<8     //数据/命令     PA8
#define LCD_WR_CLR  GPIOA->BRR=1<<7     //写数据        PA7
#define LCD_RD_CLR  GPIOA->BRR=1<<6     //读数据        PA6

//PB0~15,作为数据线
#define DATAOUT(x)  GPIOB->ODR=x;       //数据输出
#define DATAIN      GPIOB->IDR;         //数据输入

这里使用了寄存器的方式操作引脚,目的是为了提升屏幕的刷新速度,如果对这个速度要求不高的话,可以使用库函数的方式实现,影响不大。

lcd.c LCD引脚定义代码如下(部分示例):

void LCD_Init(void)
{
    
     
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE); //使能PORTA,B时钟和AFIO时钟
    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE);       //开启SWD,失能JTAG

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8;  //PORTA3~8复用推挽输出
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);  //GPIOA
    GPIO_SetBits(GPIOA,GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; //PORTB推挽输出
    GPIO_Init(GPIOB, &GPIO_InitStructure);      //GPIOB
    GPIO_SetBits(GPIOB,GPIO_Pin_All);

	//如果接了屏幕不能显示要把复位引脚接到一个IO上
    LCD_RST=0;
    delay_ms(120);
    LCD_RST=1;
    
    delay_ms(50); // delay 50 ms 
    LCD_WriteReg(0x0000,0x0001);
    delay_ms(50); // delay 50 ms 
    
    //尝试9341 ID的读取
    LCD_WR_REG(0XD3);
    lcddev.id = LCD_RD_DATA();          //dummy read
    lcddev.id = LCD_RD_DATA();          //读到0X00
    lcddev.id = LCD_RD_DATA();          //读取0X93
    lcddev.id <<= 8;
    lcddev.id |= LCD_RD_DATA();         //读取0X41

    printf(" LCD ID:%x\r\n", lcddev.id); //打印LCD ID

    //ILI9341初始化序列
    ......
}

main.c 代码如下:

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "lcd.h"

 int main(void)
 {
    
     
	u8 x=0;
	u8 lcd_id[12];			//存放LCD ID字符串	
	delay_init();	    	 //延时函数初始化	  
	uart_init(9600);	 	//串口初始化为9600
	LED_Init();		  		//初始化与LED连接的硬件接口
 	LCD_Init();
	POINT_COLOR=RED; 
	sprintf((char*)lcd_id,"LCD ID:%04X",lcddev.id);//将LCD ID打印到lcd_id数组。				 	
  	while(1) 
	{
    
    		 
		switch(x)
		{
    
    
			case 0:LCD_Clear(WHITE);break;
			case 1:LCD_Clear(BLACK);break;
			case 2:LCD_Clear(BLUE);break;
			case 3:LCD_Clear(RED);break;
			case 4:LCD_Clear(MAGENTA);break;
			case 5:LCD_Clear(GREEN);break;
			case 6:LCD_Clear(CYAN);break;

			case 7:LCD_Clear(YELLOW);break;
			case 8:LCD_Clear(BRRED);break;
			case 9:LCD_Clear(GRAY);break;
			case 10:LCD_Clear(LGRAY);break;
			case 11:LCD_Clear(BROWN);break;
		}
		POINT_COLOR=RED;	  
		LCD_ShowString(30,40,200,24,24,"Mini STM32 ^_^");	
		LCD_ShowString(30,70,200,16,16,"TFTLCD TEST");
		LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
 		LCD_ShowString(30,110,200,16,16,lcd_id);		//显示LCD ID	      					 
		LCD_ShowString(30,130,200,12,12,"2014/3/7");	      					 
	    x++;
		if(x==12)x=0;
		LED0=!LED0;	 
		delay_ms(1000);	
	} 
}

4.2 代码工程下载

可以直接下载mini开发板的TFTLCD工程代码,修改比较简单,没有涉及太复杂的代码。

第5章 LCD 实验现象

实验现象(略)

和官方的代码现象效果一致的。


总结

这个移植过程步骤还是比较简单的,只要基本懂得LCD的驱动原理,GPIO的配置基本就可以完成本次的移植操作了,后面就可以在此基础上显示各种内容了。

猜你喜欢

转载自blog.csdn.net/weixin_53944340/article/details/134757161