一个适合单片机初学者的娱乐(五、中景园1.83寸LCD屏)

        为了使之前实现的功能更加完善,决定外接一个LCD屏作为显示,后期移植LVGL实现一些界面操作

        屏幕具体的型号为如下图:1.83英寸,采用ST7789T3驱动,240*280,接口采用3line  9bit。由于未详细的看说明,此处的3line 9bit 虽然采用spi接口但是发送数据极为不便捷,采用的是官方提供的GPIO模拟的方式。具体的发送数据方式下图,所以购买屏幕一定一定要看清楚接口方式以及数据发送方式等因素,这些都会影响后续的开发进度,以及显示的效果。

        此屏幕还有一个问题就是采用FH35C-13s-0.5SHW(50) 接口,此接口对刚刚接触焊接的小伙伴很不友好,尽量选择直接焊接接口的LCD屏幕或者购买LCD模块,这样节省自己焊接和PCB制作过程。

        根据官方提供的原理图,自行设计的PCB ,如下:

                电路图相对简单,PCB制作完成后,还是采用stm32f103rct6进行通信调试。具体的代码实现,见下面,后续进行LVGL移植说明。

lcd_init.c 代码主要根据提供的demo进行自行更改合适的接口IO

#include "zjy_lcdinit.h"

/*---------------------------
中景园LCD 240(H)RGB x280(V) 1.83寸
TE   --->   			 (PB1)  EXIT
MOSI ---> SPI1_MOSI(PA7) 
SCLK ---> SPI1_SCK (PA5)
CS   ---> 				 (PA4)
D/C  --->          (PA6)  0--> 写REG
													1--> 写DATA
								
RESET --> 				 (PC4)  0--> 复位

BLK   --> 				 (PC5)  1--> 开启背光  0--> 关闭背光

----------------------------*/


void LCD_GPIO_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;

	__HAL_RCC_GPIOA_CLK_ENABLE();
	__HAL_RCC_GPIOC_CLK_ENABLE();
	__HAL_RCC_GPIOB_CLK_ENABLE();
	

	// CS MOSI SCLK
	GPIO_InitStructure.Pin 		= SPIx_SCK_PIN | SPIx_MOSI_PIN | SPIx_CS_PIN;	 
 	GPIO_InitStructure.Mode 	= GPIO_MODE_OUTPUT_PP; 		 	//推挽输出
	GPIO_InitStructure.Speed 	= GPIO_SPEED_FREQ_HIGH;		//速度50MHz
 	HAL_GPIO_Init(SPIx_SPI_GPIO_PORT, &GPIO_InitStructure);
 	HAL_GPIO_WritePin(SPIx_SPI_GPIO_PORT,SPIx_SCK_PIN | SPIx_MOSI_PIN | SPIx_CS_PIN, GPIO_PIN_SET);
	
	//RESET
	GPIO_InitStructure.Pin 		= LCD_RESET_PIN;	 
 	GPIO_InitStructure.Mode 	= GPIO_MODE_OUTPUT_PP; 		 	//推挽输出
	GPIO_InitStructure.Speed 	=  GPIO_SPEED_FREQ_HIGH;		//速度50MHz
 	HAL_GPIO_Init(LCD_RESET_GPIO_PORT, &GPIO_InitStructure);
 	HAL_GPIO_WritePin(LCD_RESET_GPIO_PORT,LCD_RESET_PIN, GPIO_PIN_SET);
	
	
	//BLK
	GPIO_InitStructure.Pin 		= LCD_BLK_PIN;	 
 	GPIO_InitStructure.Mode 	= GPIO_MODE_OUTPUT_PP; 		 	//推挽输出
	GPIO_InitStructure.Speed 	=  GPIO_SPEED_FREQ_HIGH;		//速度50MHz
 	HAL_GPIO_Init(LCD_BLK_GPIO_PORT, &GPIO_InitStructure);
 	HAL_GPIO_WritePin(LCD_BLK_GPIO_PORT,LCD_BLK_PIN, GPIO_PIN_SET);


	//TE
	GPIO_InitStructure.Pin 		= LCD_TE_PIN;	 
 	GPIO_InitStructure.Mode 	= GPIO_MODE_INPUT; 		 	//
 	HAL_GPIO_Init(LCD_TE_GPIO_PORT, &GPIO_InitStructure);
 	

}



/******************************************************************************
      函数说明:LCD串行数据写入函数
      入口数据:dat  要写入的串行数据
      返回值:  无
******************************************************************************/
void LCD_Writ_Bus(uint8_t dat) 
{	
	uint8_t i;
	for(i=0;i<8;i++)
	{			  
		LCD_SCLK_Clr();
		if(dat&0x80)
		{
		   LCD_MOSI_Set();
		}
		else
		{
		   LCD_MOSI_Clr();
		}
		LCD_SCLK_Set();
		dat<<=1;
	}	
}


/******************************************************************************
      函数说明:LCD写入数据
      入口数据:dat 写入的数据
      返回值:  无
******************************************************************************/
void LCD_WR_DATA8(uint8_t dat)
{
  LCD_CS_Clr();
	LCD_SCLK_Clr();
	LCD_MOSI_Set();
	LCD_SCLK_Set();
	LCD_Writ_Bus(dat);
	LCD_CS_Set();	
}


/******************************************************************************
      函数说明:LCD写入数据
      入口数据:dat 写入的数据
      返回值:  无
******************************************************************************/
void LCD_WR_DATA(uint16_t dat)
{
	LCD_WR_DATA8(dat>>8);
	LCD_WR_DATA8(dat);
}


/******************************************************************************
      函数说明:LCD写入命令
      入口数据:dat 写入的命令
      返回值:  无
******************************************************************************/
void LCD_WR_REG(uint8_t dat)
{
  LCD_CS_Clr();
	LCD_SCLK_Clr();
	LCD_MOSI_Clr();
	LCD_SCLK_Set();
//	LCD_DC_Clr();//写命令
	LCD_Writ_Bus(dat);
//	LCD_DC_Set();//写数据	
	LCD_CS_Set();	
}


/******************************************************************************
      函数说明:设置起始和结束地址
      入口数据:x1,x2 设置列的起始和结束地址
                y1,y2 设置行的起始和结束地址
      返回值:  无
******************************************************************************/
void LCD_Address_Set(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2)
{
	if(USE_HORIZONTAL==0)
	{
		LCD_WR_REG(0x2a);//列地址设置
		LCD_WR_DATA(x1);
		LCD_WR_DATA(x2);
		LCD_WR_REG(0x2b);//行地址设置
		LCD_WR_DATA(y1+20);
		LCD_WR_DATA(y2+20);
		LCD_WR_REG(0x2c);//储存器写
	}
	else if(USE_HORIZONTAL==1)
	{
		LCD_WR_REG(0x2a);//列地址设置
		LCD_WR_DATA(x1);
		LCD_WR_DATA(x2);
		LCD_WR_REG(0x2b);//行地址设置
		LCD_WR_DATA(y1+20);
		LCD_WR_DATA(y2+20);
		LCD_WR_REG(0x2c);//储存器写
	}
	else if(USE_HORIZONTAL==2)
	{
		LCD_WR_REG(0x2a);//列地址设置
		LCD_WR_DATA(x1+20);
		LCD_WR_DATA(x2+20);
		LCD_WR_REG(0x2b);//行地址设置
		LCD_WR_DATA(y1);
		LCD_WR_DATA(y2);
		LCD_WR_REG(0x2c);//储存器写
	}
	else
	{
		LCD_WR_REG(0x2a);//列地址设置
		LCD_WR_DATA(x1+20);
		LCD_WR_DATA(x2+20);
		LCD_WR_REG(0x2b);//行地址设置
		LCD_WR_DATA(y1);
		LCD_WR_DATA(y2);
		LCD_WR_REG(0x2c);//储存器写
	}
}


/*--------------------------
函数:LCD初始化

--------------------------*/
void ZJY_LCD_Init(void)
{
	LCD_GPIO_Init();//初始化GPIO
	
	LCD_RES_Set();
	HAL_Delay(10);	
	LCD_RES_Clr();//复位
	HAL_Delay(10);
	LCD_RES_Set();
	HAL_Delay(120);
	LCD_BLK_Set();//打开背光

	//设置显存扫描模式、数据格式等
	LCD_WR_REG(0x36);
	if(USE_HORIZONTAL==0)LCD_WR_DATA8(0x00);
	else if(USE_HORIZONTAL==1)LCD_WR_DATA8(0xC0);
	else if(USE_HORIZONTAL==2)LCD_WR_DATA8(0x70);
	else LCD_WR_DATA8(0xA0); 

	//RGB-5-6-5
	LCD_WR_REG( 0x3A);     
	LCD_WR_DATA8( 0x05);   

	//porch设置
	LCD_WR_REG( 0xB2);     
	LCD_WR_DATA8( 0x0B);   
	LCD_WR_DATA8( 0x0B);   
	LCD_WR_DATA8( 0x00);   
	LCD_WR_DATA8( 0x33);   
	LCD_WR_DATA8( 0x33);   

	//VGH 设置
	LCD_WR_REG( 0xB7);     
	LCD_WR_DATA8( 0x11);   

	//VCOM设置
	LCD_WR_REG( 0xBB);     
	LCD_WR_DATA8( 0x2F);   

	//LCM设置
	LCD_WR_REG( 0xC0);     
	LCD_WR_DATA8( 0x2C);   

	//VDV and VRH 设置
	LCD_WR_REG( 0xC2);     
	LCD_WR_DATA8( 0x01);   

	//VRH设置
	LCD_WR_REG( 0xC3);     
	LCD_WR_DATA8( 0x0D);   

	//VDV设置
	LCD_WR_REG( 0xC4);     
	LCD_WR_DATA8( 0x20);   //VDV, 0x20:0v

	//普通模式下的显存速率设置 
	LCD_WR_REG( 0xC6);     
	LCD_WR_DATA8( 0x1D);   //0x13:60Hz   

	//电源控制
//	LCD_WR_REG( 0xD0);     
//	LCD_WR_DATA8( 0xA7);   
//	LCD_WR_DATA8( 0xA1); 
  
	LCD_WR_REG( 0xD0);     
	LCD_WR_DATA8( 0xA4);   
	LCD_WR_DATA8( 0xA1); 
	
	LCD_WR_REG( 0xD6);     
	LCD_WR_DATA8( 0xA1);   //sleep in后,gate输出为GND

	//电压设置
	LCD_WR_REG( 0xE0);     
	LCD_WR_DATA8( 0xF0);   
	LCD_WR_DATA8( 0x06);   
	LCD_WR_DATA8( 0x0B);   
	LCD_WR_DATA8( 0x0A);   
	LCD_WR_DATA8( 0x09);   
	LCD_WR_DATA8( 0x26);   
	LCD_WR_DATA8( 0x29);   
	LCD_WR_DATA8( 0x33);   
	LCD_WR_DATA8( 0x41);   
	LCD_WR_DATA8( 0x18);   
	LCD_WR_DATA8( 0x16);   
	LCD_WR_DATA8( 0x15);   
	LCD_WR_DATA8( 0x29);   
	LCD_WR_DATA8( 0x2D);   

	//电压设置
	LCD_WR_REG( 0xE1);     
	LCD_WR_DATA8( 0xF0);   
	LCD_WR_DATA8( 0x04);   
	LCD_WR_DATA8( 0x08);   
	LCD_WR_DATA8( 0x08);   
	LCD_WR_DATA8( 0x07);   
	LCD_WR_DATA8( 0x03);   
	LCD_WR_DATA8( 0x28);   
	LCD_WR_DATA8( 0x32);   
	LCD_WR_DATA8( 0x40);   
	LCD_WR_DATA8( 0x3B);   
	LCD_WR_DATA8( 0x19);   
	LCD_WR_DATA8( 0x18);   
	LCD_WR_DATA8( 0x2A);   
	LCD_WR_DATA8( 0x2E);   

	LCD_WR_REG( 0xE4);     
	LCD_WR_DATA8( 0x25);   
	LCD_WR_DATA8( 0x00);   
	LCD_WR_DATA8( 0x00);   //当gate没有用完时,bit4(TMG)设为0

	LCD_WR_REG( 0x35);     //Tearing Effect Line On
	LCD_WR_DATA8( 0x00); 

	LCD_WR_REG( 0x44);     //Set Tear Scanline
	LCD_WR_DATA8( 0x00);   
	LCD_WR_DATA8( 0x20); 
	
	//显示打开
	LCD_WR_REG( 0x21);   	 //Display Inversion On
	LCD_WR_REG( 0x11);     //Sleep out
	HAL_Delay(120);      
	LCD_WR_REG( 0x29);  	 //Display On
} 




 lcd_init.h 实现的一些接口IO重命名,方便后续开发。

#ifndef ZJY_LCDINIT_H
#define ZJY_LCDINIT_H
#include "stm32f1xx_hal.h"
#include "stdio.h"


#define SPIx_SPI_GPIO_PORT  	GPIOA 
#define SPIx_SCK_PIN 			  	GPIO_PIN_5
#define SPIx_MOSI_PIN 			  GPIO_PIN_7
#define SPIx_CS_PIN 			  	GPIO_PIN_4

#define LCD_DC_GPIO_PORT			GPIOA
#define LCD_DC_PIN						GPIO_PIN_6

#define LCD_RESET_GPIO_PORT		GPIOC
#define LCD_RESET_PIN					GPIO_PIN_4

#define LCD_BLK_GPIO_PORT			GPIOC
#define LCD_BLK_PIN						GPIO_PIN_5

#define LCD_TE_GPIO_PORT			GPIOB
#define LCD_TE_PIN						GPIO_PIN_1


#define LCD_SCLK_Clr()   HAL_GPIO_WritePin( SPIx_SPI_GPIO_PORT , SPIx_SCK_PIN, GPIO_PIN_RESET 	)//SCLK
#define LCD_SCLK_Set()   HAL_GPIO_WritePin( SPIx_SPI_GPIO_PORT , SPIx_SCK_PIN, GPIO_PIN_SET )
#define LCD_MOSI_Clr()   HAL_GPIO_WritePin( SPIx_SPI_GPIO_PORT , SPIx_MOSI_PIN, GPIO_PIN_RESET  )//MOSI
#define LCD_MOSI_Set()   HAL_GPIO_WritePin( SPIx_SPI_GPIO_PORT , SPIx_MOSI_PIN, GPIO_PIN_SET )
#define LCD_CS_Clr()   	 HAL_GPIO_WritePin( SPIx_SPI_GPIO_PORT , SPIx_CS_PIN, GPIO_PIN_RESET    )//CS
#define LCD_CS_Set()     HAL_GPIO_WritePin( SPIx_SPI_GPIO_PORT , SPIx_CS_PIN, GPIO_PIN_SET )



#define LCD_RES_Clr()  HAL_GPIO_WritePin( LCD_RESET_GPIO_PORT , LCD_RESET_PIN	, GPIO_PIN_RESET )//RES
#define LCD_RES_Set()  HAL_GPIO_WritePin( LCD_RESET_GPIO_PORT , LCD_RESET_PIN	, GPIO_PIN_SET )

#define LCD_BLK_Clr()  HAL_GPIO_WritePin( LCD_BLK_GPIO_PORT , LCD_BLK_PIN		, GPIO_PIN_RESET )//BLK
#define LCD_BLK_Set()  HAL_GPIO_WritePin( LCD_BLK_GPIO_PORT , LCD_BLK_PIN		, GPIO_PIN_SET )

//#define LCD_DC_Clr()   HAL_GPIO_WritePin( LCD_DC_GPIO_PORT , LCD_DC_PIN, GPIO_PIN_RESET )//DC
//#define LCD_DC_Set()   HAL_GPIO_WritePin( LCD_DC_GPIO_PORT , LCD_DC_PIN, GPIO_PIN_SET )

#define USE_HORIZONTAL 0  //设置横屏或者竖屏显示 0或1 :竖屏  2或3 :横屏

#if USE_HORIZONTAL==0 || USE_HORIZONTAL==1
#define LCD_W 240
#define LCD_H 280

#else
#define LCD_W 280
#define LCD_H 240
#endif

void LCD_GPIO_Init(void);						//初始化GPIO
void LCD_Writ_Bus(uint8_t dat);			//模拟SPI时序
void LCD_WR_DATA8(uint8_t dat);			//写入一个字节
void LCD_WR_DATA(uint16_t dat);			//写入两个字节
void LCD_WR_REG(uint8_t dat);				//写入一个指令
void LCD_Address_Set(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2);//设置坐标函数
void ZJY_LCD_Init(void);								//LCD初始化





#endif


        以上基本完成了中景园LCD屏的开发和代码实现,后续我们就可以在main.c文件中简单调用提供的划线、显示文字、显示图片功能函数,对屏幕进行简单的测试。这样就给我们后续移植LVGL打下了坚实的基础。

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值