LCD12864 of Yiwen society displays Chinese, English and reverse display

1. Basic principles

In fact, driving the LCD is to write data to the LCD display memory. The place where 1 is written is displayed, and the place where 0 is written is not displayed. The reverse display is just the opposite; Since the video memory is distributed in 128 columns and 64 rows, it is also called 12864 liquid crystal.

2. Basic characteristics

Working voltage 3.3V, backlight voltage 3.0VMA communication mode;
8-bit parallel (6800 and 8080 timing), 4-wire serial communication 12864;
Memory of dot matrix display (DDRAM is 13265);
Display contrast, internal register adjustment (software adjustment contrast);
Duty ratio 1 / 64, bias ratio 1 / 9;
Operating temperature - 20 to + 70 degrees.

3. Video memory mapping


It can be seen that the column is defined as 0-127, and the row address range is defined as (0-7) pages in units of 8 pixels, a total of 64.

4. Pin description


It can be seen that the high and low level of pin 29 determines whether to use parallel port or serial port.

5. Serial mode drive timing


As can be seen from the figure:
Data or command transmission when CSB is pulled low;
Transmit data when RS is high, and transmit instructions when RS is low;
SCL is the clock;
SDA is data.

6. Serial write process


First, pull down CSB;
Select write data or instruction by setting the level of RS;
SCL is pulled down, bit7 is transmitted, SCL is pulled up, and so on. One byte is transmitted from bit7 to bit0;
Finally, pull up the CSB.

7. Write data flow


It can be seen that before writing data, the write address should be set first. Here are column address (0-127 columns) and page address (0-7 pages). At the same time, it should be noted that the column address will be added automatically.

8. Instruction description

9. Principle design

10. Program driver

This paper uses GD32 to drive LCD.

10.1 definition and initialization of io port

#define LCD_SCL_PORT         GPIOB
#define LCD_SCL_PIN          GPIO_PIN_6

#define LCD_SDA_PORT         GPIOB
#define LCD_SDA_PIN          GPIO_PIN_7

#define LCD_CSB_PORT         GPIOB 
#define LCD_CSB_PIN          GPIO_PIN_11

#define LCD_RST_PORT         GPIOC
#define LCD_RST_PIN          GPIO_PIN_11

#define LCD_A0_PORT          GPIOC
#define LCD_A0_PIN           GPIO_PIN_13

#define LCD_BKLED_PORT       GPIOA
#define LCD_BKLED_PIN        GPIO_PIN_6

#define LCD_CMD  		     1
#define LCD_DATA             0
						
#define PORT(port)       	 LCD_##port##_PORT
#define PIN(pin)         	 LCD_##pin##_PIN
						
#define LCD_PIN_OUT(pin,level) { if(level)                               \
							     { gpio_bit_set(PORT(pin),PIN(pin));}    \
							     else                                    \
							     { gpio_bit_reset(PORT(pin),PIN(pin));}  \
                               }
void LcdIoInit(void)
{
	rcu_periph_clock_enable(RCU_GPIOA);
	rcu_periph_clock_enable(RCU_GPIOB);
	rcu_periph_clock_enable(RCU_GPIOC);
	
	gpio_init(LCD_SCL_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,  LCD_SCL_PIN);
	gpio_init(LCD_SDA_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,  LCD_SDA_PIN);
	
	gpio_init(LCD_CSB_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,  LCD_CSB_PIN);
	gpio_init(LCD_RST_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,  LCD_RST_PIN);
	gpio_init(LCD_A0_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,  LCD_A0_PIN);
	
	gpio_init(LCD_BKLED_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,  LCD_BKLED_PIN);
	
	LCD_PIN_OUT(BKLED,1);
}

10.2 LCD write

/*
ismcd:High indicates data and low indicates instruction
*/
static void LcdWrite(uint8_t iscmd ,uint8_t data)
{
	uint8_t  i;
	
	LCD_PIN_OUT(CSB,0);
	if(iscmd)
	{
		LCD_PIN_OUT(A0,0);
	}
	else
	{
		LCD_PIN_OUT(A0,1);
	}
	for(i=0;i<8;i++)
	{
		LCD_PIN_OUT(SCL,0);
		 DelayUs(10); 
		if(data&0x80)
		{
			LCD_PIN_OUT(SDA,1);
		}
		else
		{
			LCD_PIN_OUT(SDA,0);
		}
		LCD_PIN_OUT(SCL,1);
		DelayUs(10);
		data=data<<1;
	}
	
	LCD_PIN_OUT(CSB,1);
}

10.3 LCD setting address

void LcdAddress(uint8_t  page,uint8_t column) 
{
	LcdWrite(LCD_CMD,0xb0+page); 
	LcdWrite(LCD_CMD,((column>>4)&0x0f)+0x10); //Set the upper 4 bits of the column address 
	LcdWrite(LCD_CMD,((column>>0)&0x0f)+0x00); //Set the lower 4 bits of the column address
}

10.4 LCD clear screen

Screen clearing is to write 0 to the video memory, that is, it is not displayed.

/*Full screen clearing*/ 
void LcdClearScreen(void) 
{
	uint8_t  i,j; 
	
	for(i=0;i<8;i++) 
	{
		LcdAddress(i,0); 
		for(j=0;j<128;j++) 
		{
			LcdWrite(LCD_DATA,0x00); 
		}
	}
}

10.5 LCD display frame

void LcdDispBK(void) 
{
	uint8_t  i;
	
	//Upper frame 
	LcdAddress(0,0); 
	for (i=0;i<128;i++) 
	{
		LcdWrite(LCD_DATA,0x01); 
	}
	//Lower frame 
	LcdAddress(7,0); 
	for (i=0;i<128;i++) 
	{
		LcdWrite(LCD_DATA,0x80); 
	}
	
	//Left frame 
	for(i=0;i<8;i++) 
	{
		LcdAddress(i,0); 
		LcdWrite(LCD_DATA,0xff); 
	}
	//Right frame 
	for(i=0;i<8;i++) 
	{
		LcdAddress(i,127); 
		LcdWrite(LCD_DATA,0xff); 
	}
}

10.6 LCD displays 8 * 16 string

void LcdDispStr8x16(uint8_t reverse,uint8_t page,uint8_t column,uint8_t *str) 
{
	uint16_t i=0,j;			
	uint8_t zk[16];

	while(str[i]>0x00) 
	{
		if((str[i]>=0x20)&&(str[i]<=0x7e)) 
		{
			extern uint8_t  GT20L16S1YGetAsciiData( uint8_t ASCIICode, uint32_t BaseAdd, uint8_t* S1YDZ_Data );

			GT20L16S1YGetAsciiData( str[i], 0x3b7c0, zk);
			
			LcdAddress(page,column); //Upper half
			for(j=0;j<8;j++) 
			{
				if (reverse==1) 
				{
					LcdWrite(LCD_DATA,zk[j]);
				}
				else 
				{
					LcdWrite(LCD_DATA,~(zk[j])); 
				}
			}
			LcdAddress(page+1,column);//Lower half
			
			for(j=0;j<8;j++) 
			{
				if (reverse==1) 
				{
					LcdWrite(LCD_DATA,zk[j+8]);
				}
				else 
				{
					LcdWrite(LCD_DATA,~(zk[j+8])); 
				}
			}
			i++; 
			column+=8;
		}
	}
}

Used in this article GT20L16S1Y Font, so lattice data is read directly from the font.

10.7 LCD display 16 * 16 Chinese characters

void LcdDispStr16x16(uint8_t reverse,uint8_t page,uint8_t column,uint8_t *str) 
{
	uint16_t i=0,j;
	uint8_t zk[32];

	while(str[i]>0x00) 
	{
		extern  void GT20L16S1YGetGb2312Data( uint8_t MSB, uint8_t LSB, uint8_t* S1YDZ_Data );

		GT20L16S1YGetGb2312Data( str[i], str[i+1], zk );
		
		LcdAddress(page,column); //Upper half
		for(j=0;j<16;j++) 
		{
			if (reverse==1) 
			{
				LcdWrite(LCD_DATA,zk[j]);
			}
			else 
			{
				LcdWrite(LCD_DATA,~(zk[j])); 
			}
		}
		LcdAddress(page+1,column);//Lower half
		
		for(j=0;j<16;j++) 
		{
			if (reverse==1) 
			{
				LcdWrite(LCD_DATA,zk[j+16]);
			}
			else 
			{
				LcdWrite(LCD_DATA,~(zk[j+16])); 
			}
		}
		i++,i++; 
		column+=16;
	}
}

Used in this article GT20L16S1Y Font, so lattice data is read directly from the font.

10.8 LCD initialization

void LcdInit(void)
{
	LcdIoInit();
	
	LCD_PIN_OUT(RST,0);
	DelayUs(20); 
	LCD_PIN_OUT(RST,1);     /*Reset complete*/ 
	DelayUs(20); 
	LcdWrite(LCD_CMD,0xe2); /*Soft reset*/ 
	DelayUs(50); 
	LcdWrite(LCD_CMD,0x2c); /*Boost step 1*/ 
	DelayUs(50); 
	LcdWrite(LCD_CMD,0x2e); /*Boost step 2*/ 
	DelayUs(50); 
	LcdWrite(LCD_CMD,0x2f); /*Boost step 3*/ 
	DelayUs(50); 
	
	LcdWrite(LCD_CMD,0x24); /*Coarse contrast adjustment, settable range 0x20 ~ 0x27*/ 
	LcdWrite(LCD_CMD,0x81); /*Fine tune contrast*/ 
	
	LcdWrite(LCD_CMD,0x1b); /*0x1a,Fine tune the contrast value, and the range can be set from 0x00 to 0x3f 1f*/ 
	LcdWrite(LCD_CMD,0xa3); /*Bias ratio (bias), 0xa2:1 / 9 0xa3:1 = 1 / 7    */ 
	
	LcdWrite(LCD_CMD,0xc8); /*Line scanning order: top to bottom*/ 
	LcdWrite(LCD_CMD,0xa0); /*Column scan order: left to right*/ 
	LcdWrite(LCD_CMD,0x40); /*Start line: the first line starts*/ 
	
	LcdWrite(LCD_CMD,0xaf); /*On display*/ 
	LcdClearScreen();
	LcdDispBK();

	LcdDispStr8x16(0,2,20,(uint8_t*)"display,test") ;
	LcdDispStr16x16(1,5,50,(uint8_t*)"Hello"); 
}

Note: if the display is not clear, it can be adjusted by bias ratio and contrast.

11. Display test


The figure shows Chinese, English and border, and also realizes anti display.

Keywords: Single-Chip Microcomputer stm32 gd32

Added by usamaalam on Sun, 02 Jan 2022 01:33:03 +0200