如何成功驱动 HC32L196 和 ST7789v:经验分享

        ST7789v是Sitronix公司研制的,用于驱动LCD的芯片,在市场上有很多TFT屏使用这款芯片驱动,虽然驱动芯片相同,但不同TFT厂家在设计接口时各有不同。一时兴起,研究了一下HC32L196芯片驱动ST7789v,经过一段时间的努力,在朋友们的支持下。对GPIO模拟SPI、硬件SPI、8位并口、16位并口四种接口形式进行了探索。记录下来,与朋友们分享。

     1 ST7789v的接口

        按照《ST7789v Datasheet》的描述,ST7789v的接口有以下几种:

                – Parallel 8080-series MCU Interface (8-bit, 9-bit, 16-bit & 18-bit)

                – 6/16/18 RGB Interface(VSYNC, HSYNC, DOTCLK, ENABLE, DB[17:0])

                – Serial Peripheral Interface(SPI Interface)

                – VSYNC Interface

        其中Parallel 8080-series MCU Interface、Serial Peripheral Interface两种使用最多,市场上的TFT屏提供的基本是这两中接口或其中之一。由于条件限制,我仅探索了这两种接口中的80-8bit parallel I/F、4-line 8bit serial I/F、80-16bit parallel I/F Ⅱ、80-8bit parallel I/F Ⅱ、4-line 8bit serial I/F
Ⅱ。

        在《ST7789v Datasheet》的6.2 Interface Logic Pins”中有详细的说明,不再赘述。这里有几点需要注意:

        (1)TFT厂家提供的接口描述与《ST7789v Datasheet》里的可能不一致,特别是引脚名称,需要核对清除;

        (2)TFT屏幕内的IM3是连接的高电平还是低电平,这直接约束可以使用哪些接口;

        (3)并口引脚的线序必须与厂家核对清楚。

      1.1 SPI接口的硬件连接

         SPI接口使用的连线少,相对简单,这也是市面上这种屏多的原因吧。我实验的是4-line 8bit serial I/F 和4-line 8bit serial I/F Ⅱ,这两种接口在硬件连接上相近(IM3,它常常被TFT厂家在内部连好了,4-line 8bit serial I/F Ⅱ下的SDO我没有使用)。

        连接图很简单,看端口定义更好些: 

/*MCU连接ST7789V端口定义*/
#define LCD_CS_PORT      	GpioPortA
#define LCD_CS_PIN       	GpioPin4			//CS
#define LCD_DCX_PORT     	GpioPortA
#define LCD_DCX_PIN      	GpioPin5			//不同显示屏厂家标识不同,如:RS/SPISCL/SCK		
#define LCD_SDA_PORT    	GpioPortA
#define LCD_SDA_PIN     	GpioPin7			//SDA/MOSI

#define LCD_WRX_PORT    	GpioPortA
#define LCD_WRX_PIN     	GpioPin3			//不同显示屏厂家标识不同,如:WR

/*ST7789 Reset控制端口定义*/
#define LCD_RESX_PORT		GpioPortA
#define LCD_RESX_PIN		GpioPin10			//不同显示屏厂家标识不同,如:RESET/RES

/**/
#define LCD_WRX(n) (n ? Gpio_SetIO(LCD_WRX_PORT, LCD_WRX_PIN):Gpio_ClrIO(LCD_WRX_PORT, LCD_WRX_PIN))		//1数据,0命令

      1.2 Parallel接口的硬件连接

        并口连线相对麻烦一些,特别是DB口,不同TFT厂家的标识不同,与芯片引脚并不对应,直接按照Datasheet调试会有问题,我就是因为这个浪费了好多时间。上代码:

/*MCU连接ST7789V端口定义*/
#define LCD_DB_PORT		GpioPortB
#define LCD_DB0_PIN		GpioPin0
#define LCD_DB1_PIN		GpioPin1
#define LCD_DB2_PIN		GpioPin2
#define LCD_DB3_PIN		GpioPin3
#define LCD_DB4_PIN		GpioPin4
#define LCD_DB5_PIN		GpioPin5
#define LCD_DB6_PIN		GpioPin6
#define LCD_DB7_PIN		GpioPin7
#define LCD_DB8_PIN		GpioPin8
#define LCD_DB9_PIN		GpioPin9
#define LCD_DB10_PIN	GpioPin10
#define LCD_DB11_PIN	GpioPin11
#define LCD_DB12_PIN	GpioPin12
#define LCD_DB13_PIN	GpioPin13
#define LCD_DB14_PIN	GpioPin14
#define LCD_DB15_PIN	GpioPin15

#define LCD_CS_PORT		GpioPortA
#define LCD_CS_PIN		GpioPin4
#define LCD_DCX_PORT	GpioPortA			
#define LCD_DCX_PIN		GpioPin5			//不同显示屏厂家标识不同,如:RS/SPISCL,
#define LCD_WRX_PORT	GpioPortA
#define LCD_WRX_PIN		GpioPin3
#define LCD_RDX_PORT	GpioPortA
#define LCD_RDX_PIN		GpioPin8
#define LCD_RESX_PORT	GpioPortA
#define LCD_RESX_PIN	GpioPin10			//不同显示屏厂家标识不同,如:RESET/RES

#define LCD_TE_PORT		GpioPortC
#define LCD_TE_PIN		GpioPin3			//TE,未使用。

#define LCD_CS(n) (n ? Gpio_SetIO(LCD_CS_PORT, LCD_CS_PIN) : Gpio_ClrIO(LCD_CS_PORT, LCD_CS_PIN))
#define LCD_DCX(n) (n ? Gpio_SetIO(LCD_DCX_PORT, LCD_DCX_PIN) : Gpio_ClrIO(LCD_DCX_PORT, LCD_DCX_PIN))
#define LCD_WRX(n) (n ? Gpio_SetIO(LCD_WRX_PORT, LCD_WRX_PIN) : Gpio_ClrIO(LCD_WRX_PORT, LCD_WRX_PIN))
#define LCD_RDX(n) (n ? Gpio_SetIO(LCD_RDX_PORT, LCD_RDX_PIN) : Gpio_ClrIO(LCD_RDX_PORT, LCD_RDX_PIN))

      2 TFT复位HWReset

        这是驱动ST7789v的第一步,复位正确与否直接决定ST7789v能否正常工作。在Datasheet中“7.4.5 Reset Timing”有详细描述,主要看TRW的时间,只要时间给够,基本不会有问题。网上的例程很多。延迟时间可以重新设置,实测并不需要代码中那么长的延时。

void LCD_HWReset(void)
{
	Gpio_SetIO(LCD_RESX_PORT, LCD_RESX_PIN);
	delay1ms(1);
	Gpio_ClrIO(LCD_RESX_PORT, LCD_RESX_PIN);
	delay1ms(50);
	Gpio_SetIO(LCD_RESX_PORT, LCD_RESX_PIN);
	
	Spi_SetCS(M0P_SPI0, TRUE);
	delay1ms(120);
}

      3 TFT初始化

        对ST7789v的寄存器进行设置,使其工作在需要的状态。

void LCD_Init(en_original_location_t original)
{
	//初始化LCD
	LCD_WR_CMD(0x11);     
	delay1ms(120);      
	
	LCD_WR_CMD(0x36); 
	LCD_WR_Data8(original);

	LCD_WR_CMD(0x3A);     
	LCD_WR_Data8(0x05); 
	
	LCD_WR_CMD(0xB2);     
	LCD_WR_Data8(0x0C); 
	LCD_WR_Data8(0x0C);   
	LCD_WR_Data8(0x00);   
	LCD_WR_Data8(0x33);   
	LCD_WR_Data8(0x33);  

	LCD_WR_CMD(0xB7);     
	LCD_WR_Data8(0x35);   

	LCD_WR_CMD(0xBB);     
	LCD_WR_Data8(0x32);     

	LCD_WR_CMD(0xC2);     
	LCD_WR_Data8(0x01);   

	LCD_WR_CMD(0xC3);     
	LCD_WR_Data8(0x15);//4.5V   

	LCD_WR_CMD(0xC4);     
	LCD_WR_Data8(0x20);    

	LCD_WR_CMD(0xC6);     
	LCD_WR_Data8(0x0F);   

	LCD_WR_CMD(0xD0);     
	LCD_WR_Data8(0xA4);   
	LCD_WR_Data8(0xA1);   

	LCD_WR_CMD(0xE0);
	LCD_WR_Data8(0xD0);
	LCD_WR_Data8(0x0A);
	LCD_WR_Data8(0x10);
	LCD_WR_Data8(0x0C);
	LCD_WR_Data8(0x0C);
	LCD_WR_Data8(0x18);
	LCD_WR_Data8(0x35);
	LCD_WR_Data8(0x43);
	LCD_WR_Data8(0x4D);
	LCD_WR_Data8(0x39);
	LCD_WR_Data8(0x13);
	LCD_WR_Data8(0x13);
	LCD_WR_Data8(0x2D);
	LCD_WR_Data8(0x34);

	LCD_WR_CMD(0xE1);
	LCD_WR_Data8(0xD0);
	LCD_WR_Data8(0x05);
	LCD_WR_Data8(0x0B);
	LCD_WR_Data8(0x06);
	LCD_WR_Data8(0x05);
	LCD_WR_Data8(0x02);
	LCD_WR_Data8(0x35);
	LCD_WR_Data8(0x43);
	LCD_WR_Data8(0x4D);
	LCD_WR_Data8(0x16);
	LCD_WR_Data8(0x15);
	LCD_WR_Data8(0x15);
	LCD_WR_Data8(0x2E);
	LCD_WR_Data8(0x32);

	LCD_WR_CMD(0x21);  

	LCD_WR_CMD(0x29);     

}

     4 开始使用TFT

        完成以上工作就可以使用TFT进行显示了。

     5 易出问题

         (1)时序问题

           无论SPI还是Parallel,MCU和ST7789v通信的关建都是时序,时序正确,工作会正常,否则出现的问题千奇百怪。如:无法在某些特定区域显示,只能显示半屏数据,花屏…..

           MCU使用8MHz主频,仿真SPI时,显示屏正常,直接用硬件SPI,TFT根本不显示,反复检查,使用了1/128分频后,TFT才正常工作。这点和网上找到的资料描述情况不同,尚不知是何原因,按照“7.4.3 Serial Interface Characteristics (4-line serial)”的说明,不应该这么慢的速度。

          MCU使用>16MHz主频时,Parallel接口,在向ST7789v发送数据时,需要在给WRX上升沿之前做延时处理,这点与手册描述的时间状况一致。

         (2)并口的高低字节问题

           认真阅读“8.1 MPU Interface Type Selection”,这里面的DB往往和TFT厂提供的DB不一致。

物联沃分享整理
物联沃-IOTWORD物联网 » 如何成功驱动 HC32L196 和 ST7789v:经验分享

发表评论