使用8080并口协议驱动NT35510LCD显示屏

使用8080并口协议驱动NT35510LCD显示屏

   本文记录如何使用8080协议驱动LCD显示屏,其中LCD显示屏驱动为NT35510芯片,正点原子的4.3寸显示屏,像素480X800,基于正点原子STM32精英板开发平台。
  想要驱动一个芯片,第一步便是阅读芯片手册,读协议时序图,读指令集。正点原子硬件资料里面给出了NT35510的芯片手册。
在这里插入图片描述
  可以看出,NT35510支持多种接口协议,IIC,MIPI,8080,由于显示屏很大,数据量大,采用串行传输方式显然很难满足快速刷屏的要求,因此采用并口传输的方式,一次性可以传输多位数据。我们翻到手册第26页。
在这里插入图片描述
  我们发现8080并口也支持多种方式,根据IM0,IM1,IM3不同的配置,可以分为8位并口,16位并口,24位并口三种方式。我们打开正点原子原理图资料,打开4.3寸显示屏资料(看左边),明显可以看出使用的是16位并口方式。

LCD_D0~LCD_D15代表16根数据线
LCD_CS(Chip Select)片选端
LCD_RST(Reset)复位端
LCD_RS(不知道)未知端,根据后面手册推断是D/C端即Data/Cmd端·
LCD_WR(Write)写数据端
LCD_RD(Read)读数据端
在这里插入图片描述
  我们再继续看NT35510数据手册,根据图名可以知道这是一个写数据到寄存器的过程,从左边阴影区看,一个 过程需要:
(1)拉低CS片选端;
(2)拉高RD读端;
(3)D/C端拉低代表传输CMD,即命令,拉高代表传输Data,即数据,对应LCD上面的RS端口。
(4)数据挂载在数据总线上。
(5)WR拉低。(这里采用先把数据准备好,在开始传输的方式)
(6)WR端来一个上升沿代表数据发送结束
在这里插入图片描述
在这里插入图片描述

  同样,对于过程,结合下面两幅图来看,注意观察下面第一幅图中的Driver to MPU,需要

(1)拉低CS片选端;
(2)拉高WR读端;
(3)D/C端拉低代表传输CMD,即命令,拉高代表传输Data,即数据,对应LCD上面的RS端口。
(4)RD来一个下降沿
(5)NT35510将数据挂载在数据总线上。
(6)紧接着RD信号来一个上升沿代表数据读取结束。

在这里插入图片描述
在这里插入图片描述
  根据上述时序,我们可以写出如下代码,代码工程基于eclipse。

/*
 * i80.c
 *
 *  Created on: 2022年4月12日
 *      Author: djz
 */
#include "i80.h"

#define CS PGout(12)
#define RS PGout(0)
#define WR PDout(5)
#define RD PDout(4)

#define CMD 0
#define DATA 1
/*
 * 8080协议初始化
 */

/**
  * @brief  将16根数据线设置为输出模式
  * @param None
  *
  * @retval None
  */
void Data_SetOut(void) {
	//将数据信号线设置为输出模式
	GPIOE->CRL &= ~(0xF << 28);
	GPIOE->CRL |= (u32) (0x03 << 28);

	GPIOE->CRH &= ~(u32) (0xFFFFFFFF);
	GPIOE->CRH |= (u32) (0x33333333);

	GPIOD->CRL &= ~(0x000000FF);
	GPIOD->CRL |= (u32) (0x00000033);

	GPIOD->CRH &= ~(u32) (0xFF000FFF);
	GPIOD->CRH |= (u32) (0X33000333);

}
/**
  * @brief  将16根数据线设置为输入模式
  * @param None
  *
  * @retval None
  */
void Data_SetIn(void) {
	//将数据信号线设置为输入模式
	GPIOE->CRL &= ~(0xF << 28);
	GPIOE->CRL |= (u32) (0x08 << 28);

	GPIOE->CRH &= ~(u32) (0xFFFFFFFF);
	GPIOE->CRH |= (u32) (0x88888888);

	GPIOD->CRL &= ~(u32) (0x000000FF);
	GPIOD->CRL |= (u32) (0x00000088);

	GPIOD->CRH &= ~(u32) (0xFF000FFF);
	GPIOD->CRH |= (u32) (0x88000888);
}
/**
  * @brief  将数据挂载在16根数据线上
  * @param None
  *
  * @retval None
  */
void Send_Data(u16 data) {
	PDout(10) = (data >> 15) & (0x01);
	PDout(9) = (data >> 14) & (0x01);
	PDout(8) = (data >> 13) & (0x01);
	PEout(15) = (data >> 12) & (0x01);
	PEout(14) = (data >> 11) & (0x01);
	PEout(13) = (data >> 10) & (0x01);
	PEout(12) = (data >> 9) & (0x01);
	PEout(11) = (data >> 8) & (0x01);
	PEout(10) = (data >> 7) & (0x01);
	PEout(9) = (data >> 6) & (0x01);
	PEout(8) = (data >> 5) & (0x01);
	PEout(7) = (data >> 4) & (0x01);
	PDout(1) = (data >> 3) & (0x01);
	PDout(0) = (data >> 2) & (0x01);
	PDout(15) = (data >> 1) & (0x01);
	PDout(14) = (data >> 0) & (0x01);

}
/**
  * @brief  将数据从16根数据线上读出来
  * @param None
  *
  * @retval None
  */
u16 Read_Data(void) {
	u16 data = 0;
	data |= PDin(10) << 15;
	data |= PDin(9) << 14;
	data |= PDin(8) << 13;
	data |= PEin(15) << 12;
	data |= PEin(14) << 11;
	data |= PEin(13) << 10;
	data |= PEin(12) << 9;
	data |= PEin(11) << 8;
	data |= PEin(10) << 7;
	data |= PEin(9) << 6;
	data |= PEin(8) << 5;
	data |= PEin(7) << 4;
	data |= PDin(1) << 3;
	data |= PDin(0) << 2;
	data |= PDin(15) << 1;
	data |= PDin(14) << 0;
	return data;

}
/**
  * @brief  8080协议写数据
  * @param u16 data, u8 type(data:16位数据,type:写命令还是写数据)
  *
  * @retval None
  */
void I80_WR(u16 data, u8 type) {

	RS = type;
	Data_SetOut(); //设置数据线为输出方式

	RD = 1;
	CS = 0;

	Send_Data(data); //挂载数据

	WR = 0;
	WR = 1;

	CS = 1;
}
/**
  * @brief  8080协议读数据
  * @param  u8 type(type:写命令还是写数据)
  *
  * @retval u16(16位数据)
  */
u16 I80_RD(u8 type) {
	u16 data = 0;
	RS = type;
	Data_SetIn(); //设置数据线为输出方式

	WR = 1;
	CS = 0;
	RD = 1;
	RD = 0;
	sleep_us(1);
	//可能需要sleep
	data = Read_Data();
	RD = 1;
	CS = 1;
	return data;
}
/**
  * @brief  8080协议写命令
  * @param 	u16 cmd(命令)
  *
  * @retval None
  */
void I80_WR_CMD(u16 cmd) {
	I80_WR(cmd, CMD);
}
/**
  * @brief  8080协议写数据
  * @param 	u16 data(数据)
  *
  * @retval None
  */
void I80_WR_DATA(u16 data) {
	I80_WR(data, DATA);
}
/**
  * @brief  8080协议读命令
  * @param 	None
  *
  * @retval u16(16位命令)
  */
u16 I80_RD_CMD(void) {
	return I80_RD(CMD);
}
/**
  * @brief  8080协议读数据
  * @param 	None
  *
  * @retval u16(16位数据)
  */
u16 I80_RD_DATA(void) {
	return I80_RD(DATA);
}
/**
 * NE4->PG12 CS
 * NWE->PD5 WR
 * RD->PD4 RD
 * RS->PG0 RS
 *====DATA数据线===
 * D0 D1->PD14 PD15
 * D2 D3 ->PD0 PD1
 * D4~D12->PE7~PE15
 * D13~D15->PD8~PD10
 */
void i80_GPIOInit(void) {
//先初始化与8080控制器相关的
#if MY_USE_STDPERIPH   //是否使用库函数,1:使用,0:不使用
#else

//1、时钟初始化
	/*配置为复用推挽输出*/
	//RCC->APB2ENR |= (1 << 3) | (1 << 5) | (1 << 6) | (1 << 8); //使能GPIO时钟
	RCC->APB2ENR |= 0x01 << 5;	//设置GPIOD时钟
	RCC->APB2ENR |= 0x01 << 6;	//设置GPIOE时钟
	RCC->APB2ENR |= 0x01 << 8;	//设置GPIOG时钟
	//数据信号线
//2.GPIO初始化
	GPIOG->CRH &= ~(0x0F) << 16;
	GPIOG->CRH |= (0x03) << 16;	 //设置PG12为通用推挽输出模式

	GPIOG->CRL &= ~(0x0F) << 0;
	GPIOG->CRL |= (0x03) << 0;	 //设置PG12为通用推挽输出模式

	GPIOD->CRL &= ~(0x0F) << 20;
	GPIOD->CRL |= (0X03) << 20;

	GPIOD->CRL &= ~(0x0F) << 16;
	GPIOD->CRL |= (0x03) << 16;

//	GPIOB->CRL &= ~(0x0F) << 0;
//	GPIOB->CRL |= (0x03) << 0;

	Data_SetOut();
//控制信号线

#endif

}


  至此,我们已经完成了8080并口协议的封装,掌握了与NT35510芯片沟通的方法,那么下面便是向NT35510芯片中写入命令与数据,将LCD显示屏设置成我们想要的显示模式。我们首先来看开发板上的电路图

在这里插入图片描述
  CS,RS,RD,WR以及DB1~DB16均已经配置过了,RESET引脚为开发板上的复位引脚,不需要管,下面字母T开头的为触摸功能,还剩一个LCD_BL,为背光控制,背光这个词我不理解,但是不开背光屏幕量不起来,因此在LCD进行初始化的时候,不仅需要进行8080协议的初始化,还需要打开背光,不然屏幕就是黑的。
在这里插入图片描述
  初始化命令由这一堆子命令构成,若是不闲得没事,请不要尝试。我们直接参考原子哥的代码,打开原子哥的TFT_LCD例程,从这个id=5510开始复制到后面,CV大法。然后根据他写的函数,我们进行补充就行了。
在这里插入图片描述
在这里插入图片描述
  代码如下

#define LCD_BL PBout(0)
void LCD_Init(void) {

	i80_GPIOInit();
	RCC->APB2ENR |= 0x01 << 3;	//设置GPIOB时钟
	GPIOB->CRL &= ~(0x0F << 0);
	GPIOB->CRL |= 0x03 << 0;	//LCD_BL

	sleep_ms(50);//等于正点原子的delay_ms()

	LCD_WriteReg(0xF000, 0x55);
	LCD_WriteReg(0xF001, 0xAA);
	LCD_WriteReg(0xF002, 0x52);
	LCD_WriteReg(0xF003, 0x08);
	LCD_WriteReg(0xF004, 0x01);
	//AVDD Set AVDD 5.2V
	LCD_WriteReg(0xB000, 0x0D);
	LCD_WriteReg(0xB001, 0x0D);
	LCD_WriteReg(0xB002, 0x0D);
	//AVDD ratio
	LCD_WriteReg(0xB600, 0x34);
	LCD_WriteReg(0xB601, 0x34);
	LCD_WriteReg(0xB602, 0x34);
	//AVEE -5.2V
	LCD_WriteReg(0xB100, 0x0D);
	LCD_WriteReg(0xB101, 0x0D);
	LCD_WriteReg(0xB102, 0x0D);
	//AVEE ratio
	LCD_WriteReg(0xB700, 0x34);
	LCD_WriteReg(0xB701, 0x34);
	LCD_WriteReg(0xB702, 0x34);
	//VCL -2.5V
	LCD_WriteReg(0xB200, 0x00);
	LCD_WriteReg(0xB201, 0x00);
	LCD_WriteReg(0xB202, 0x00);
	//VCL ratio
	LCD_WriteReg(0xB800, 0x24);
	LCD_WriteReg(0xB801, 0x24);
	LCD_WriteReg(0xB802, 0x24);
	//VGH 15V (Free pump)
	LCD_WriteReg(0xBF00, 0x01);
	LCD_WriteReg(0xB300, 0x0F);
	LCD_WriteReg(0xB301, 0x0F);
	LCD_WriteReg(0xB302, 0x0F);
	//VGH ratio
	LCD_WriteReg(0xB900, 0x34);
	LCD_WriteReg(0xB901, 0x34);
	LCD_WriteReg(0xB902, 0x34);
	//VGL_REG -10V
	LCD_WriteReg(0xB500, 0x08);
	LCD_WriteReg(0xB501, 0x08);
	LCD_WriteReg(0xB502, 0x08);
	LCD_WriteReg(0xC200, 0x03);
	//VGLX ratio
	LCD_WriteReg(0xBA00, 0x24);
	LCD_WriteReg(0xBA01, 0x24);
	LCD_WriteReg(0xBA02, 0x24);
	//VGMP/VGSP 4.5V/0V
	LCD_WriteReg(0xBC00, 0x00);
	LCD_WriteReg(0xBC01, 0x78);
	LCD_WriteReg(0xBC02, 0x00);
	//VGMN/VGSN -4.5V/0V
	LCD_WriteReg(0xBD00, 0x00);
	LCD_WriteReg(0xBD01, 0x78);
	LCD_WriteReg(0xBD02, 0x00);
	//VCOM
	LCD_WriteReg(0xBE00, 0x00);
	LCD_WriteReg(0xBE01, 0x64);
	//Gamma Setting
	LCD_WriteReg(0xD100, 0x00);
	LCD_WriteReg(0xD101, 0x33);
	LCD_WriteReg(0xD102, 0x00);
	LCD_WriteReg(0xD103, 0x34);
	LCD_WriteReg(0xD104, 0x00);
	LCD_WriteReg(0xD105, 0x3A);
	LCD_WriteReg(0xD106, 0x00);
	LCD_WriteReg(0xD107, 0x4A);
	LCD_WriteReg(0xD108, 0x00);
	LCD_WriteReg(0xD109, 0x5C);
	LCD_WriteReg(0xD10A, 0x00);
	LCD_WriteReg(0xD10B, 0x81);
	LCD_WriteReg(0xD10C, 0x00);
	LCD_WriteReg(0xD10D, 0xA6);
	LCD_WriteReg(0xD10E, 0x00);
	LCD_WriteReg(0xD10F, 0xE5);
	LCD_WriteReg(0xD110, 0x01);
	LCD_WriteReg(0xD111, 0x13);
	LCD_WriteReg(0xD112, 0x01);
	LCD_WriteReg(0xD113, 0x54);
	LCD_WriteReg(0xD114, 0x01);
	LCD_WriteReg(0xD115, 0x82);
	LCD_WriteReg(0xD116, 0x01);
	LCD_WriteReg(0xD117, 0xCA);
	LCD_WriteReg(0xD118, 0x02);
	LCD_WriteReg(0xD119, 0x00);
	LCD_WriteReg(0xD11A, 0x02);
	LCD_WriteReg(0xD11B, 0x01);
	LCD_WriteReg(0xD11C, 0x02);
	LCD_WriteReg(0xD11D, 0x34);
	LCD_WriteReg(0xD11E, 0x02);
	LCD_WriteReg(0xD11F, 0x67);
	LCD_WriteReg(0xD120, 0x02);
	LCD_WriteReg(0xD121, 0x84);
	LCD_WriteReg(0xD122, 0x02);
	LCD_WriteReg(0xD123, 0xA4);
	LCD_WriteReg(0xD124, 0x02);
	LCD_WriteReg(0xD125, 0xB7);
	LCD_WriteReg(0xD126, 0x02);
	LCD_WriteReg(0xD127, 0xCF);
	LCD_WriteReg(0xD128, 0x02);
	LCD_WriteReg(0xD129, 0xDE);
	LCD_WriteReg(0xD12A, 0x02);
	LCD_WriteReg(0xD12B, 0xF2);
	LCD_WriteReg(0xD12C, 0x02);
	LCD_WriteReg(0xD12D, 0xFE);
	LCD_WriteReg(0xD12E, 0x03);
	LCD_WriteReg(0xD12F, 0x10);
	LCD_WriteReg(0xD130, 0x03);
	LCD_WriteReg(0xD131, 0x33);
	LCD_WriteReg(0xD132, 0x03);
	LCD_WriteReg(0xD133, 0x6D);
	LCD_WriteReg(0xD200, 0x00);
	LCD_WriteReg(0xD201, 0x33);
	LCD_WriteReg(0xD202, 0x00);
	LCD_WriteReg(0xD203, 0x34);
	LCD_WriteReg(0xD204, 0x00);
	LCD_WriteReg(0xD205, 0x3A);
	LCD_WriteReg(0xD206, 0x00);
	LCD_WriteReg(0xD207, 0x4A);
	LCD_WriteReg(0xD208, 0x00);
	LCD_WriteReg(0xD209, 0x5C);
	LCD_WriteReg(0xD20A, 0x00);

	LCD_WriteReg(0xD20B, 0x81);
	LCD_WriteReg(0xD20C, 0x00);
	LCD_WriteReg(0xD20D, 0xA6);
	LCD_WriteReg(0xD20E, 0x00);
	LCD_WriteReg(0xD20F, 0xE5);
	LCD_WriteReg(0xD210, 0x01);
	LCD_WriteReg(0xD211, 0x13);
	LCD_WriteReg(0xD212, 0x01);
	LCD_WriteReg(0xD213, 0x54);
	LCD_WriteReg(0xD214, 0x01);
	LCD_WriteReg(0xD215, 0x82);
	LCD_WriteReg(0xD216, 0x01);
	LCD_WriteReg(0xD217, 0xCA);
	LCD_WriteReg(0xD218, 0x02);
	LCD_WriteReg(0xD219, 0x00);
	LCD_WriteReg(0xD21A, 0x02);
	LCD_WriteReg(0xD21B, 0x01);
	LCD_WriteReg(0xD21C, 0x02);
	LCD_WriteReg(0xD21D, 0x34);
	LCD_WriteReg(0xD21E, 0x02);
	LCD_WriteReg(0xD21F, 0x67);
	LCD_WriteReg(0xD220, 0x02);
	LCD_WriteReg(0xD221, 0x84);
	LCD_WriteReg(0xD222, 0x02);
	LCD_WriteReg(0xD223, 0xA4);
	LCD_WriteReg(0xD224, 0x02);
	LCD_WriteReg(0xD225, 0xB7);
	LCD_WriteReg(0xD226, 0x02);
	LCD_WriteReg(0xD227, 0xCF);
	LCD_WriteReg(0xD228, 0x02);
	LCD_WriteReg(0xD229, 0xDE);
	LCD_WriteReg(0xD22A, 0x02);
	LCD_WriteReg(0xD22B, 0xF2);
	LCD_WriteReg(0xD22C, 0x02);
	LCD_WriteReg(0xD22D, 0xFE);
	LCD_WriteReg(0xD22E, 0x03);
	LCD_WriteReg(0xD22F, 0x10);
	LCD_WriteReg(0xD230, 0x03);
	LCD_WriteReg(0xD231, 0x33);
	LCD_WriteReg(0xD232, 0x03);
	LCD_WriteReg(0xD233, 0x6D);
	LCD_WriteReg(0xD300, 0x00);
	LCD_WriteReg(0xD301, 0x33);
	LCD_WriteReg(0xD302, 0x00);
	LCD_WriteReg(0xD303, 0x34);
	LCD_WriteReg(0xD304, 0x00);
	LCD_WriteReg(0xD305, 0x3A);
	LCD_WriteReg(0xD306, 0x00);
	LCD_WriteReg(0xD307, 0x4A);
	LCD_WriteReg(0xD308, 0x00);
	LCD_WriteReg(0xD309, 0x5C);
	LCD_WriteReg(0xD30A, 0x00);

	LCD_WriteReg(0xD30B, 0x81);
	LCD_WriteReg(0xD30C, 0x00);
	LCD_WriteReg(0xD30D, 0xA6);
	LCD_WriteReg(0xD30E, 0x00);
	LCD_WriteReg(0xD30F, 0xE5);
	LCD_WriteReg(0xD310, 0x01);
	LCD_WriteReg(0xD311, 0x13);
	LCD_WriteReg(0xD312, 0x01);
	LCD_WriteReg(0xD313, 0x54);
	LCD_WriteReg(0xD314, 0x01);
	LCD_WriteReg(0xD315, 0x82);
	LCD_WriteReg(0xD316, 0x01);
	LCD_WriteReg(0xD317, 0xCA);
	LCD_WriteReg(0xD318, 0x02);
	LCD_WriteReg(0xD319, 0x00);
	LCD_WriteReg(0xD31A, 0x02);
	LCD_WriteReg(0xD31B, 0x01);
	LCD_WriteReg(0xD31C, 0x02);
	LCD_WriteReg(0xD31D, 0x34);
	LCD_WriteReg(0xD31E, 0x02);
	LCD_WriteReg(0xD31F, 0x67);
	LCD_WriteReg(0xD320, 0x02);
	LCD_WriteReg(0xD321, 0x84);
	LCD_WriteReg(0xD322, 0x02);
	LCD_WriteReg(0xD323, 0xA4);
	LCD_WriteReg(0xD324, 0x02);
	LCD_WriteReg(0xD325, 0xB7);
	LCD_WriteReg(0xD326, 0x02);
	LCD_WriteReg(0xD327, 0xCF);
	LCD_WriteReg(0xD328, 0x02);
	LCD_WriteReg(0xD329, 0xDE);
	LCD_WriteReg(0xD32A, 0x02);
	LCD_WriteReg(0xD32B, 0xF2);
	LCD_WriteReg(0xD32C, 0x02);
	LCD_WriteReg(0xD32D, 0xFE);
	LCD_WriteReg(0xD32E, 0x03);
	LCD_WriteReg(0xD32F, 0x10);
	LCD_WriteReg(0xD330, 0x03);
	LCD_WriteReg(0xD331, 0x33);
	LCD_WriteReg(0xD332, 0x03);
	LCD_WriteReg(0xD333, 0x6D);
	LCD_WriteReg(0xD400, 0x00);
	LCD_WriteReg(0xD401, 0x33);
	LCD_WriteReg(0xD402, 0x00);
	LCD_WriteReg(0xD403, 0x34);
	LCD_WriteReg(0xD404, 0x00);
	LCD_WriteReg(0xD405, 0x3A);
	LCD_WriteReg(0xD406, 0x00);
	LCD_WriteReg(0xD407, 0x4A);
	LCD_WriteReg(0xD408, 0x00);
	LCD_WriteReg(0xD409, 0x5C);
	LCD_WriteReg(0xD40A, 0x00);
	LCD_WriteReg(0xD40B, 0x81);

	LCD_WriteReg(0xD40C, 0x00);
	LCD_WriteReg(0xD40D, 0xA6);
	LCD_WriteReg(0xD40E, 0x00);
	LCD_WriteReg(0xD40F, 0xE5);
	LCD_WriteReg(0xD410, 0x01);
	LCD_WriteReg(0xD411, 0x13);
	LCD_WriteReg(0xD412, 0x01);
	LCD_WriteReg(0xD413, 0x54);
	LCD_WriteReg(0xD414, 0x01);
	LCD_WriteReg(0xD415, 0x82);
	LCD_WriteReg(0xD416, 0x01);
	LCD_WriteReg(0xD417, 0xCA);
	LCD_WriteReg(0xD418, 0x02);
	LCD_WriteReg(0xD419, 0x00);
	LCD_WriteReg(0xD41A, 0x02);
	LCD_WriteReg(0xD41B, 0x01);
	LCD_WriteReg(0xD41C, 0x02);
	LCD_WriteReg(0xD41D, 0x34);
	LCD_WriteReg(0xD41E, 0x02);
	LCD_WriteReg(0xD41F, 0x67);
	LCD_WriteReg(0xD420, 0x02);
	LCD_WriteReg(0xD421, 0x84);
	LCD_WriteReg(0xD422, 0x02);
	LCD_WriteReg(0xD423, 0xA4);
	LCD_WriteReg(0xD424, 0x02);
	LCD_WriteReg(0xD425, 0xB7);
	LCD_WriteReg(0xD426, 0x02);
	LCD_WriteReg(0xD427, 0xCF);
	LCD_WriteReg(0xD428, 0x02);
	LCD_WriteReg(0xD429, 0xDE);
	LCD_WriteReg(0xD42A, 0x02);
	LCD_WriteReg(0xD42B, 0xF2);
	LCD_WriteReg(0xD42C, 0x02);
	LCD_WriteReg(0xD42D, 0xFE);
	LCD_WriteReg(0xD42E, 0x03);
	LCD_WriteReg(0xD42F, 0x10);
	LCD_WriteReg(0xD430, 0x03);
	LCD_WriteReg(0xD431, 0x33);
	LCD_WriteReg(0xD432, 0x03);
	LCD_WriteReg(0xD433, 0x6D);
	LCD_WriteReg(0xD500, 0x00);
	LCD_WriteReg(0xD501, 0x33);
	LCD_WriteReg(0xD502, 0x00);
	LCD_WriteReg(0xD503, 0x34);
	LCD_WriteReg(0xD504, 0x00);
	LCD_WriteReg(0xD505, 0x3A);
	LCD_WriteReg(0xD506, 0x00);
	LCD_WriteReg(0xD507, 0x4A);
	LCD_WriteReg(0xD508, 0x00);
	LCD_WriteReg(0xD509, 0x5C);
	LCD_WriteReg(0xD50A, 0x00);
	LCD_WriteReg(0xD50B, 0x81);

	LCD_WriteReg(0xD50C, 0x00);
	LCD_WriteReg(0xD50D, 0xA6);
	LCD_WriteReg(0xD50E, 0x00);
	LCD_WriteReg(0xD50F, 0xE5);
	LCD_WriteReg(0xD510, 0x01);
	LCD_WriteReg(0xD511, 0x13);
	LCD_WriteReg(0xD512, 0x01);
	LCD_WriteReg(0xD513, 0x54);
	LCD_WriteReg(0xD514, 0x01);
	LCD_WriteReg(0xD515, 0x82);
	LCD_WriteReg(0xD516, 0x01);
	LCD_WriteReg(0xD517, 0xCA);
	LCD_WriteReg(0xD518, 0x02);
	LCD_WriteReg(0xD519, 0x00);
	LCD_WriteReg(0xD51A, 0x02);
	LCD_WriteReg(0xD51B, 0x01);
	LCD_WriteReg(0xD51C, 0x02);
	LCD_WriteReg(0xD51D, 0x34);
	LCD_WriteReg(0xD51E, 0x02);
	LCD_WriteReg(0xD51F, 0x67);
	LCD_WriteReg(0xD520, 0x02);
	LCD_WriteReg(0xD521, 0x84);
	LCD_WriteReg(0xD522, 0x02);
	LCD_WriteReg(0xD523, 0xA4);
	LCD_WriteReg(0xD524, 0x02);
	LCD_WriteReg(0xD525, 0xB7);
	LCD_WriteReg(0xD526, 0x02);
	LCD_WriteReg(0xD527, 0xCF);
	LCD_WriteReg(0xD528, 0x02);
	LCD_WriteReg(0xD529, 0xDE);
	LCD_WriteReg(0xD52A, 0x02);
	LCD_WriteReg(0xD52B, 0xF2);
	LCD_WriteReg(0xD52C, 0x02);
	LCD_WriteReg(0xD52D, 0xFE);
	LCD_WriteReg(0xD52E, 0x03);
	LCD_WriteReg(0xD52F, 0x10);
	LCD_WriteReg(0xD530, 0x03);
	LCD_WriteReg(0xD531, 0x33);
	LCD_WriteReg(0xD532, 0x03);
	LCD_WriteReg(0xD533, 0x6D);
	LCD_WriteReg(0xD600, 0x00);
	LCD_WriteReg(0xD601, 0x33);
	LCD_WriteReg(0xD602, 0x00);
	LCD_WriteReg(0xD603, 0x34);
	LCD_WriteReg(0xD604, 0x00);
	LCD_WriteReg(0xD605, 0x3A);
	LCD_WriteReg(0xD606, 0x00);
	LCD_WriteReg(0xD607, 0x4A);
	LCD_WriteReg(0xD608, 0x00);
	LCD_WriteReg(0xD609, 0x5C);
	LCD_WriteReg(0xD60A, 0x00);
	LCD_WriteReg(0xD60B, 0x81);

	LCD_WriteReg(0xD60C, 0x00);
	LCD_WriteReg(0xD60D, 0xA6);
	LCD_WriteReg(0xD60E, 0x00);
	LCD_WriteReg(0xD60F, 0xE5);
	LCD_WriteReg(0xD610, 0x01);
	LCD_WriteReg(0xD611, 0x13);
	LCD_WriteReg(0xD612, 0x01);
	LCD_WriteReg(0xD613, 0x54);
	LCD_WriteReg(0xD614, 0x01);
	LCD_WriteReg(0xD615, 0x82);
	LCD_WriteReg(0xD616, 0x01);
	LCD_WriteReg(0xD617, 0xCA);
	LCD_WriteReg(0xD618, 0x02);
	LCD_WriteReg(0xD619, 0x00);
	LCD_WriteReg(0xD61A, 0x02);
	LCD_WriteReg(0xD61B, 0x01);
	LCD_WriteReg(0xD61C, 0x02);
	LCD_WriteReg(0xD61D, 0x34);
	LCD_WriteReg(0xD61E, 0x02);
	LCD_WriteReg(0xD61F, 0x67);
	LCD_WriteReg(0xD620, 0x02);
	LCD_WriteReg(0xD621, 0x84);
	LCD_WriteReg(0xD622, 0x02);
	LCD_WriteReg(0xD623, 0xA4);
	LCD_WriteReg(0xD624, 0x02);
	LCD_WriteReg(0xD625, 0xB7);
	LCD_WriteReg(0xD626, 0x02);
	LCD_WriteReg(0xD627, 0xCF);
	LCD_WriteReg(0xD628, 0x02);
	LCD_WriteReg(0xD629, 0xDE);
	LCD_WriteReg(0xD62A, 0x02);
	LCD_WriteReg(0xD62B, 0xF2);
	LCD_WriteReg(0xD62C, 0x02);
	LCD_WriteReg(0xD62D, 0xFE);
	LCD_WriteReg(0xD62E, 0x03);
	LCD_WriteReg(0xD62F, 0x10);
	LCD_WriteReg(0xD630, 0x03);
	LCD_WriteReg(0xD631, 0x33);
	LCD_WriteReg(0xD632, 0x03);
	LCD_WriteReg(0xD633, 0x6D);
	//LV2 Page 0 enable
	LCD_WriteReg(0xF000, 0x55);
	LCD_WriteReg(0xF001, 0xAA);
	LCD_WriteReg(0xF002, 0x52);
	LCD_WriteReg(0xF003, 0x08);
	LCD_WriteReg(0xF004, 0x00);
	//Display control
	LCD_WriteReg(0xB100, 0xCC);
	LCD_WriteReg(0xB101, 0x00);
	//Source hold time
	LCD_WriteReg(0xB600, 0x05);
	//Gate EQ control
	LCD_WriteReg(0xB700, 0x70);
	LCD_WriteReg(0xB701, 0x70);
	//Source EQ control (Mode 2)
	LCD_WriteReg(0xB800, 0x01);
	LCD_WriteReg(0xB801, 0x03);
	LCD_WriteReg(0xB802, 0x03);
	LCD_WriteReg(0xB803, 0x03);
	//Inversion mode (2-dot)
	LCD_WriteReg(0xBC00, 0x02);
	LCD_WriteReg(0xBC01, 0x00);
	LCD_WriteReg(0xBC02, 0x00);
	//Timing control 4H w/ 4-delay
	LCD_WriteReg(0xC900, 0xD0);
	LCD_WriteReg(0xC901, 0x02);
	LCD_WriteReg(0xC902, 0x50);
	LCD_WriteReg(0xC903, 0x50);
	LCD_WriteReg(0xC904, 0x50);
	LCD_WriteReg(0x3500, 0x00);
	LCD_WriteReg(0x3A00, 0x55);  //16-bit/pixel
	//
	LCD_WR(0x1100);
	sleep_us(120);//等于正点原子的delay_us
	LCD_WR(0x2900);
	LCD_BL = 1;	//打开背光显示
}

  接着我们便是去封装这些函数,说白了就是用8080我们已经写好的读写方法去封装一个LCD的读写方法,本质没有改变。

/**
  * @brief  LCD写寄存器
  * @param 	u16 addr, u16 data(16位的地址和16位的数据)
  *
  * @retval None
  */
void LCD_WriteReg(u16 addr, u16 data) {
	I80_WR_CMD(addr);
	I80_WR_DATA(data);
}
/**
  * @brief  LCD写
  * @param 	u16 addr(16位的地址)
  *
  * @retval None
  */
void LCD_WR(u16 addr) {
	I80_WR_CMD(addr);
}
/**
  * @brief  LCD读数据
  * @param 	16位的数据
  *
  * @retval None
  */
u16 LCD_RD(void) {
	return I80_RD_DATA();
}
/**
  * @brief  LCD读寄存器
  * @param 	u16 addr(16位的地址)
  *
  * @retval 16位的数据
  */
u16 LCD_RD_Reg(u16 addr) {
	I80_WR_CMD(addr);
	//sleep_us(5);
	return I80_RD_DATA();
}

  为啥要整LCD_WriteReg和LCD_WR这两个函数呢,因为这个芯片有时候要给个地址就行了,不需要数据,或者也可以不写LCD_WR这个函数,使用LCD_WriteReg(addr,0)也可以,写个0进去。读的话需要携程两个函数,因为有时候你写一个指定地址,他能读一堆数据出来,即连续读,如果此时使用LCD_RD_Reg这个函数的话,相当于重新写地址重新开始读数据。
  到这里的话,这个显示屏已经能够成功初始化了,下面我们分析如何画一个小点,我们继续来看NT35510的数据手册,注意到下面这一堆东西。
在这里插入图片描述
  首先需要建立一个概念,横着的叫行,竖着的叫列,第几列是x方向,第几行是y方向,Column是列的意思,Row是行的意思。我们首先来看Column。
在这里插入图片描述
  看下面的Restriction,MV代表横竖屏幕的意思,我们可以理解出这个芯片总共有4个地址用来控制显示屏,2个16位的寄存器,XS和XE,其中XS必然小于等于XE,那我们大致可以知道,总共有32位地址数据,但我们的显示屏很小,X方向只有480,所以我们的x的最大为479,小于2的9次方大于2的8次方,因此我们需要9位数据,需要设置XS这个16位寄存器即可,需要向XS的高位地址,即2A00,XS的低位地址,即2A00+1,写入X轴的数据。那么同样,我们来看Row寄存器,我们屏幕y方向为800,小于2的10次方大于2的9次方,也是需要用到YS的高8位和低8位。
  那么当我们需要定位x和y坐标时,首先需要一个16位的数据地址,因为8位不够用了,需要一个u16类型的,其次就是将高八位给2A00或者2B00地址,将地8位给2A01或2B01地址即可。
在这里插入图片描述

void LCD_SetCursor(u16 x, u16 y) {
	LCD_WriteReg(0x2A00, x >> 8);
	LCD_WriteReg(0x2A00 + 1, x & 0XFF);
	LCD_WriteReg(0x2B00, y >> 8);
	LCD_WriteReg(0x2B00 + 1, y & 0XFF);
}

  有了上述的基础,我们已经能够定位屏幕的各个方向了。但我们只是完成了定位,还没有往里面塞东西,下面来看memory寄存器,也就相当于以前的GRAM地址,往2C00里面写一个像素的颜色,便完成了显示一个点的任务了。
在这里插入图片描述

//foreground 画笔颜色
void LCD_WR_Point(u16 x, u16 y, u16 foreground) {
	LCD_WriteReg(0x2A00, x >> 8);
	LCD_WriteReg(0x2A00 + 1, x & 0XFF);
	LCD_WriteReg(0x2B00, y >> 8);
	LCD_WriteReg(0x2B00 + 1, y & 0XFF);
	I80_WR_CMD(0X2C00); //写memory,即填充眼色
	I80_WR_DATA(foreground);
}

至此,我们便实现了画点的工作,至于显示字符串,那只需要填充点即可,给出一张图即可理解,本质就是往里面塞点。

请添加图片描述

本文基于米嗨Stm32教程编写,大家如果想学习STM32,可以淘宝搜索米嗨教育。
工程链接
链接:https://pan.baidu.com/s/10qnvbycjwXbyyLKeruf0sg?pwd=kxtl
提取码:kxtl
–来自百度网盘超级会员V5的分享

  • 3
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: 要使用STM32F103RCT6驱动1.44寸TFT LCD显示屏,首先需要了解TFT LCD显示屏的基本工作原理和通信接口。 TFT LCD显示屏由控制器和显示面板组成,控制器负责将图像数据发送到显示面板,并控制显示面板的驱动方式。STM32F103RCT6是一款32位ARM Cortex-M3核心的微控制器,具有丰富的外设和较高的处理能力,适合用于驱动TFT LCD显示屏。 接下来需要确定TFT LCD显示屏的通信接口是什么,常见的通信接口有SPI、I2C和8080并行接口等。对于1.44寸TFT LCD显示屏,通常采用SPI接口进行通信。 在进行硬件连接之前,需要查看TFT LCD显示屏的规格书和STM32F103RC6的数据手册来了解各个引脚的功能和连接方式。通常,SPI接口需要如下连接:使用STM32F103RCT6的SPI主机模式,分别连接STM32F103RCT6的SPI主机的SCK、MISO、MOSI管脚(对应SPI1或SPI2)与TFT LCD显示屏的SCK、SDO、SDI管脚,还需要连接片选管脚,以及连接显示屏的复位管脚和片选管脚以及电源供应和地。 在软件方面,需要先配置STM32F103RCT6的SPI外设,并设置通信速率、数据位长度等参数。然后,编写驱动程序,通过SPI与TFT LCD显示屏进行数据通信,将显示数据发送到TFT LCD显示屏,以实现图像显示的功能。 总的来说,驱动1.44寸TFT LCD显示屏需要进行硬件设置和软件编程。通过了解TFT LCD显示屏的通信接口和STM32F103RCT6的外设特性,并编写相应的驱动程序,就可以实现TFT LCD显示屏驱动及图像显示功能。 ### 回答2: 要驱动1.44寸TFTLCD显示屏,首先要使用STM32F103RCT6开发板与显示屏进行连接。我们可以通过GPIO口实现数据线与显示屏相连,而控制线则通过专门的引脚连接。 接下来需要编写相关的驱动代码来控制显示屏。我们可以使用HAL库提供的函数,来设置GPIO口的输出模式,以及数据传输相关的操作。利用SPI或者I2C通信协议,我们可以通过发送命令和数据来控制显示屏的显示内容。 在驱动代码中,我们需要先初始化SPI或者I2C通信,并配置相应的参数,比如时钟频率、传输模式等。 接着,我们需要编写命令和数据的发送函数,通过SPI或I2C发送相关指令给显示屏。比如,我们可以通过发送命令来设置显示区域、背光亮度等参数。 最后,我们可以编写显示函数来实现在显示屏上显示图像或者文字。通过发送数据来更新显示内容,并且可以设置不同的显示模式,如图形显示、字符显示等。 需要注意的是,针对不同的显示屏型号,具体的驱动代码可能会有所不同。因此,在编写驱动代码时,需要结合显示屏的数据手册来编写相应的控制指令和函数。 以上是关于如何驱动1.44寸TFTLCD显示屏的大致步骤。在实际应用中,还需要对具体的硬件结构和功能要求进行详细调试和开发。 ### 回答3: STM32F103RCT6是一款ARM Cortex-M3内核的微控制器,可以用于控制各种外设和驱动显示屏。在驱动1.44寸TFT LCD显示屏时,我们需要按照以下步骤进行设置和编程: 1. 连接硬件:首先,将STM32F103RCT6与1.44寸TFT LCD显示屏连接起来。根据显示屏和微控制器的规格书或引脚配置表,将引脚正确连接。 2. 配置GPIO引脚:在STM32F103RCT6的寄存器中,通过设置GPIO引脚的模式和速度,将其配置为输出模式。将对应的引脚配置为控制显示屏的D/C引脚(用于选择数据/指令)、CS引脚(用于片选)、以及时钟引脚和数据引脚等。 3. 编写驱动程序:使用C语言或其他适合的编程语言,编写代码来控制和驱动1.44寸TFT LCD显示屏。根据显示屏的数据手册和命令集,实现显示屏的初始化、清屏、写入像素数据等功能。 4. 设置显示屏参数:根据需要,设置显示屏的相关参数,例如屏幕分辨率、颜色模式、显示方向等。这些参数需要根据具体的显示屏型号来设置。 5. 显示数据:通过驱动程序发送像素数据,将需要显示的图像或文本等内容写入显示屏。 6. 刷新显示:根据需要,定时刷新显示屏内容,以保持实时更新的效果。 通过以上步骤,我们可以实现STM32F103RCT6对1.44寸TFT LCD显示屏驱动。需要根据具体的硬件和显示屏型号进行适配和调试,确保驱动程序的正确性和稳定性。同时,根据项目的需求和复杂度,可能需要更详细的代码和配置设置。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值