CH549EVT development board test - driving LCD5110 display
[Copy link]
After several days of testing, the code to drive the LCD5110 display was finally successfully transplanted. The following is a picture of the testing process:
This is what it looks like:
During the transplantation process, the function definition of the font file took a lot of time. Since I hadn't touched C51 for some time, I tried to use the ARM definition method to store the font data in EEPROM. I repeatedly used static and const to define the font file, but the compilation always failed, prompting that the data was too large. With the advice of Qinheng's technicians, I changed to use code to define it, and the compilation passed smoothly. The following is the driver code for LCD5110:
#include ".\Public\CH549.H"
#include ".\Public\DEBUG.H"
#include ".\mydrive\lcd_5110.h"
#include ".\mydrive\ascii5x8.h" //5x8ASCII character set
#include ".\mydrive\charcode.h" //12x16(14) Chinese character subset
#include ".\mydrive\asciicode.h" //5x8(8)ASCII subset
/************************************************
* Function name: Delay
* Function function: Delay in milliseconds
* Input parameter: xms: number of milliseconds
* Output parameter: None
* Remarks:
**********************************************/
void Delay(UINT8 xms)
{
UINT8 x,y;
for(x=xms;x>0;x--)
for(y=10;y>0;y--); //for(y=110;y>0;y--)
}
/************************************************
* Function name: LCD_write_byte
* Function: Simulate SPI interface timing to write data/command LCD
* Input parameter: data: the data to be written;
* dc: write data 1/command 0 selection
* Output parameter: None
* Remarks: Pin D/C (LCD_DC) is used to select whether to write command (D/C=0) or data (D/C=1)
*********************************************/
void LCD_write_byte(UINT8 dat,UINT8 dc)
{
UINT8 i;
LCD_CLK = 0; //Pull down the clock CLK first
LCD_CE = 0; //Select 5110
LCD_DC = dc; //dc=0 data, dc=1 command
for(i=0; i<8; i++) //Send 8 bits
{
if (dat & 0x80){
LCD_DIN = 1;
}
else{
LCD_DIN = 0;
}
LCD_CLK = 1;
Delay(1);
dat = dat << 1; //Shift, prepare to send the next bit
LCD_CLK = 0; //Send synchronous clock
}
LCD_CE = 1; //Turn off 5110
}
/************************************************
* Function name: LCD_set_XY
* Function: Set LCD coordinate function
* Input parameter: X: 0-83;
* Y: 0-5
* Output parameter: None
* Remarks:
**********************************************/
void LCD_set_XY(UINT8 X,UINT8 Y)
{
LCD_write_byte(0x40 | Y,0); //column?
LCD_write_byte(0x80 | X,0); //row?
}
/************************************************
* Function name: LCD_clear
* Function: 5110 clear screen (fill the screen with blank space)
* Input parameter: None
* Output parameter: None
* Remarks:
******************************************/
void LCD_clear(void)
{
UINT8 i,j;
LCD_set_XY(0,0); //Locate the upper left corner
for (i=0; i<6; i++)
{
for (j=0; j<84; j++)
{
LCD_write_byte(0x00,1);
}
}
}
/************************************************
* Function name: LCD_init
* Function function: 5110 initialization
* Input parameter: None
* Output parameter: None
* Remarks: A RES low level pulse is required to reset after the power is turned on. After VDD becomes high level,
* at most 100ms, RST input low level (<0.3VDD)
*************************************************/
void LCD_init(void)
{
// LCD_Config(); //Configure LCD connection
LCD_RST = 0; //Reset LCD5110
Delay(2);
LCD_RST = 1;
LCD_CE = 0; // Turn off LCD
Delay(2);
LCD_CE = 0; // Turn off LCD
LCD_write_byte(0x21,0); //Use extended LCD commands to set LCD mode
LCD_write_byte(0xc8,0); //Set LCD bias voltage
LCD_write_byte(0x06,0); //Temperature correction (temperature coefficient 2)
LCD_write_byte(0x13,0); //1:48
LCD_write_byte(0x20,0); //Use basic commands, V=0, horizontal addressing
LCD_write_byte(0x0c,0); //Set display mode, normal display
LCD_clear(); //Clear screen
LCD_CE = 0; // Turn off LCD
}
/************************************************
* Function name: LCD_write_ASCII
* Function: Display string 5*7(8)
* Input parameters: x, y, cid: display ASCII characters
* Output parameters: None Number (row number) 32~127
* Remarks: The ASCII code table array ASC_5[95][8] is used for addressing
**************************************************/
void LCD_write_ASCII(UINT8 X,UINT8 Y,UINT8 *stru)
{
UINT8 i;
// j = cid - 32;
LCD_set_XY(X,Y); // Positioning (upper left corner)
while (1)
{
for ( i=0; i<5; i++) // Output a 5*7 character
{
LCD_write_byte(ASC_5[*stru-32],1);
}
stru++;
LCD_write_byte(0x00,1); // Insert a blank column
if(*stru == '\0') break; // At the end of each string, there will be a '\0'
}
}
/************************************************
* Function name: LCD_write_ASCII
* Function: Display a single character 5*7(8)
* Input parameters: x, y, cid: display ASCII characters
* Output parameters: None Number (row number) 32~127
* Remarks: The ASCII code table array ASC_5[95][8] is used for addressing
**************************************************/
void LCD_write_ASC_SIN(UINT8 X,UINT8 Y,UINT8 cid)
{
UINT8 i;
LCD_set_XY(X,Y); // Positioning (upper left corner)
for ( i=0; i<5; i++) // Output a 5*7 character
{
LCD_write_byte(ASC_5[cid-32],1);
}
}
/************************************************
* Function name: LCD_write_ASC7x12
* Function: Display custom characters 7*12(16)
* Input parameters: x, y, cid: displayed characters 0 1 2 3 4 5 6 7 8 9 = m s
* Output parameters: None Number (row number) 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
, 12 * Remarks: The ASCII code table array ASC_7[13][14] is used for addressing
**************************************************/
void LCD_write_ASC7x12(UINT8 X, UINT8 Y, UINT8 cid)
{
UINT8 i;
LCD_set_XY(X, Y); // Position {upper left corner)
for (i=0; i<7; i++) // Display the upper half of the character (7 columns)
{
LCD_write_byte(ASC_7[cid],1);
}
LCD_set_XY(X,Y+1); //Display the lower half of the character
for (i=7; i<14; i++)
{
LCD_write_byte(ASC_7[cid],1);
}
}
/************************************************
* Function name: LCD_write_CHAR
* Function: Display custom characters 12*14(16)
* Input parameters: x, y, cid: displayed characters Electronic spot welding machine connection interval milliseconds
* Output parameters: None Number (row number) 0,1,2,3,4,5,6,7,8,9,10
* Remarks: CHAR array CHAR_12[11][24] to address
*****************************************************/
void LCD_write_char(UINT8 x,UINT8 y,UINT8 cid)
{
UINT8 i;
LCD_set_XY(x,y); //Positioning (upper left corner)
for (i=0; i<12; i++) //Write the upper half of the character (12 columns)
{
LCD_write_byte(CHAR_12[cid],1);
}
LCD_set_XY(x,y+1); //Write the lower half of the character
for (i=12; i<24; i++)
{
LCD_write_byte(CHAR_12[cid],1);
}
}
/****************************************************
* Function name: LCD_write_string
* Function: Display Chinese character string
* Input parameters: x, y, *stru: displayed string
* Output parameters: None
* Remarks: Find the row number in the font library from the two-dimensional array cid_12 according to the Chinese character internal code, and then call and display them one by one
**************************************************/
void LCD_write_string(UINT8 x,UINT8 y,UINT8 *stru)
{
UINT8 j,n;
while(1)
{
// for (j = 0; j < 38; j++) //Search for the row number of the Chinese character corresponding to the character library
j = 0;
while(1)
{
n = 0; //Search failed, replace with the first character
if((stru[0] == cid_12[j][0]) && (stru[1] == cid_12[j][1]))
{
n = j; //Find the row number, end and jump out
break;
}
j++;
if(*cid_12 == '\0') break;
}
LCD_write_char(x, y, n);
x += 12;
stru += 2;
if(*stru == '\0') break; //At the end of each string, there will be a '\0'
LCD_write_byte(0x00,1); //Insert a blank column
}
}
/************************************************
* Function name: LCD_write_value
* Function: Display variable characters 5*7(8) or 7*12(16)
* Input parameters: x, y, L, val: coordinates, length, decimals, leading zero (1 is displayed, 0 is not displayed), variable
* Output parameters: None Number (row number)
* Remarks: The ASCII code table array ASC_5[95][8] is used for addressing
**************************************************/
void LCD_write_value(UINT8 X, UINT8 Y, UINT8 L, UINT8 D, UINT8 Z, UINT16 val)
{
UINT8 i, j, f = 0; // Column loop, word loop, display flag
UINT16 t, cid; // Current remainder, current number
UINT32 n; // Current multiple
t = val;
n = 1;
if(Z == 1)
f = 16; //space = 0, "0" = 16
for (j = 0; j < L; j++)
n = n * 10;
LCD_set_XY(X,Y); //positioning (upper left corner)
for (j = L; j > 0; j--) //Character loop starts
{
n = j < 2 ? 1: n / 10; //Calculate the current multiple
cid = t / n; //Current digit
t = t - (cid * n);
if ((cid > 0)|(j-1 == D)) //Display character 0
f = 16;
for ( i=0; i<5; i++) //Write a 5*7 character
{
LCD_write_byte(ASC_5[cid + f],1);
}
if ( D > 0 & D == (j - 1))
{
for ( i=0; i<5; i++) //Write decimal point
{
LCD_write_byte(ASC_5[14],1);
}
}
else
if(j>1) LCD_write_byte(0x00,1);//Insert a blank column
}
}
|