I have a 1602 LCD, ks0066 driver chip, with LED backlight. I wrote a driver with reference to some information on the website. After writing it, I found that it is basically the same as the code circulating on the Internet.
/*========================================
1602lcd module driver
==========================================
Description: 1. Crystal: 11.0592MHz
2.1602 driver: ks0066
******************************************/
#include
#include
#define lcm_rs P2_7 //Register selection
#define lcm_rw P2_6 //Read/write control
#define lcm_e P2_5 //Read/write enable
#define lcm_blk P2_4 //backlight led 1.off 0.on
#define lcm_data P0
// Function declaration
void delay5ms(void);
void delay400ms(void);
void lcm_write_command(unsigned char wc_lcm,busy_c);
/**********************************
//Function name: void lcm_ini(void)
// Pass parameters: None
//Return value: None
//Function: LCM initialization
//Function description:
*************************************/
void lcm_ini(void)
{
lcm_data = 0;
lcm_write_command(0x38,0); //16*2 display, 5*7 dot matrix, 8-bit data interface, no busy detection
delay5ms();
lcm_write_command(0x38,0);
delay5ms();
lcm_write_command(0x38,0); //Three-time display mode, no busy detection
delay5ms();
lcm_write_command(0x38,1); //16*2 display, 5*7 dot matrix, 8-bit data interface, need to detect busy
lcm_write_command(0x80,1); //Turn off the display
lcm_write_command(0x01,1); //clear display
lcm_write_command(0x06,1); //Pointer and cursor +1, no scrolling
lcm_write_command(0x0c,1); //Turn on display, don't display cursor
}
/**********************************
//Function name: unsigned char lcm_read_status(void)
// Pass parameters: None
//Return value: unsigned char
//Function: Read lcm status, wait for lcm to be idle
//Function description: DB7=1, busy
*************************************/
unsigned char lcm_read_status(void)
{
lcm_data=0xff;
lcm_rs=0;
lcm_rw=1;
lcm_e=0;
lcm_e=0;
lcm_e=1;
while(lcm_data & 0x80);
return lcm_data;
}
/**********************************
//Function name: void lcm_write_data(unsigned char wd_lcm)
// Pass parameter: unsigned char wd_lcm
//Return value: None
//Function: lcm write data
//Function description:
*************************************/
void lcm_write_data(unsigned char wd_lcm)
{
lcm_read_status(); //Judge the lcm busy flag
lcm_data = wd_lcm;
lcm_rs = 1;
lcm_rw = 0;
lcm_e = 0;
lcm_e = 0;
lcm_e = 1;
}
/**********************************
//Function name: void lcm_write_command(unsigned char wc_lcm, busy_c)
// Pass parameters: unsigned char wc_lcm, busy_c
//Return value: None
//Function: lcm write command
//Function description: busy_c=0, no need to detect busy signal
*************************************/
void lcm_write_command(unsigned char wc_lcm, busy_c)
{
if (busy_c)
lcm_read_status();
lcm_data = wc_lcm;
lcm_rs=0;
lcm_rw = 0;
lcm_e = 0;
lcm_e = 0;
lcm_e = 1;
}
/**********************************
//Function name: void disp_one_char(unsigned char x, unsigned char y, unsigned char disp_data)
// Pass parameters: unsigned char x, unsigned char y, unsigned char disp_data
//Return value: None
//Function: Display a character at the specified position
//Function description:
*************************************/
void disp_one_char(unsigned char x, unsigned char y, unsigned disp_data)
{
y = y&0x01;
x = x&0x0f; //Limit to 2 lines, 15 characters per line
if (y)
x =x + 0x40; //Calculate RAM address
x = x + 0x80;
lcm_write_command(x,0);
lcm_write_data(disp_data);
}
/**********************************
//Function name: void disp_one_char(unsigned char x, unsigned char y, unsigned char *disp_data)
// Pass parameters: unsigned char x, unsigned char y, unsigned char *disp_data
//Return value: None
//Function: Display a string of characters at the specified position
//Function description:
*************************************/
void disp_list_char(unsigned char x, unsigned char y, unsigned char *disp_data)
{
unsigned char char_length,j;
char_length = strlen(disp_data);
y = y&0x1;
x = x&0x0f;
for (j=0;j { disp_one_char( x,y,disp_data[j]); //Display a character x++; } } /********************************** //Function name: void delay5ms(void) // Pass parameters: None //Return value: None //Function: Delay 5MS //Function description: *************************************/ void delay5ms(void) { unsigned int TempCyc = 5552; while(TempCyc--); } /********************************** //Function name: void delay400ms(void) // Pass parameters: None //Return value: None //Function: L delay 400MS //Function description: LCM power-on delay *************************************/ void delay400ms(void) { unsigned char TempCycA = 5; unsigned int TempCycB; while(TempCycA--) { TempCycB=7269; while(TempCycB--); }; } /*****d****************************** //Function name: void main(void) // Pass parameters: None //Return value: None //Function: main function //Function description: ************************************/ void main(void) { delay400ms(); lcm_ini(); disp_list_char(1,0,"Welcome"); disp_list_char(1,0,"www.dzkjcn.com") while(1); } The above program simply displays two lines of characters without scrolling or backlight. C51 program for 4-line LCD 1602 ---------------------------------- | LCM-----51 | LCM-----51 | ---------------------------------- |RS-----P2.1 | DB4-----P1.4 | |RW-----P2.0 | DB5-----P1.5 | |E-----P2.2 | DB6-----P1.6 | |VLCD connects 1K resistor to GND| DB7-----P1.7 | -------------------------------------------------- - [Note: AT89S51 uses 12M crystal oscillator] ================================================== ===========*/ void writelcd(bit command,unsigned char ddata) { ReadStatusLCM(); //Detection busy LCM_Data = (ddata&0xf0)|(P1&0x0f); LCM_RW = 0; if(command==0) LCM_RS = 0; else LCM_RS=1; LCM_E = 1; LCM_E = 0; LCM_E = 0; LCM_Data = ((ddata<<4)&0xf0)|(P1&0x0f); if(command==0) LCM_RS = 0; else LCM_RS=1; LCM_E = 1; LCM_E = 0; LCM_E = 0; } //Read status unsigned char ReadStatusLCM(void) { P1_7=1; LCM_RS = 0; LCM_RW = 1; LCM_E = 0; LCM_E = 0; LCM_E = 1; while(P1_7&0x01);//Detect busy signal return(P1_7); } void LCMInit(void) //LCM initialization { LCM_Data=0xff; writelcd(0,0x28); //Three-time display mode setting, do not detect busy signal Delay5Ms(); writelcd(0,0x28); Delay5Ms(); writelcd(0,0x28); Delay5Ms(); writelcd(0,0x28); //Display mode setting, start to require each busy signal detection writelcd(0,0x0c); //Display on and cursor setting writelcd(0,0x01); //display clear screen writelcd(0,0x06); //Display cursor movement settings } //Display a character at the specified position void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData) { Y &= 0x1; X &= 0xF; //Limit X to not be greater than 15, Y to not be greater than 1 if (Y) X |= 0x40; //When the second line is to be displayed, the address code + 0x40; X |= 0x80; //Calculate the instruction code writelcd(0,X); writelcd(1,DData); } //Display a string of characters at the specified position ***Original characters will not be displayed if they encounter a space 0x20*** void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData) { unsigned char ListLength,j; ListLength = strlen(DData); Y &= 0x1; X &= 0xF; //Limit X to not be greater than 15, Y to not be greater than 1 if (X <= 0xF) //X coordinate should be less than 0xF { for(j=0;j { DisplayOneChar(X, Y, DData[j]); //Display a single character X++; } } } //5ms delay void Delay5Ms(void) { unsigned int TempCyc = 5552; while(TempCyc--); } //400ms delay void Delay400Ms(void) { unsigned char TempCycA = 5; unsigned int TempCycB; while(TempCycA--) { TempCycB=7269; while(TempCycB--); }; } /////LCM_end///////
Previous article:Example of using the command line to compile C51 source code and generate a HEX file
Next article:C51 program for HT1621 driving segment LCD
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Ranking of installed capacity of smart driving suppliers from January to September 2024: Rise of independent manufacturers and strong growth of LiDAR market
- Industry first! Xiaopeng announces P7 car chip crowdfunding is completed: upgraded to Snapdragon 8295, fluency doubled
- P22-009_Butterfly E3106 Cord Board Solution
- Keysight Technologies Helps Samsung Electronics Successfully Validate FiRa® 2.0 Safe Distance Measurement Test Case
- Innovation is not limited to Meizhi, Welling will appear at the 2024 China Home Appliance Technology Conference
- Innovation is not limited to Meizhi, Welling will appear at the 2024 China Home Appliance Technology Conference
- Huawei's Strategic Department Director Gai Gang: The cumulative installed base of open source Euler operating system exceeds 10 million sets
- Download from the Internet--ARM Getting Started Notes
- Learn ARM development(22)
- Learn ARM development(21)
- EEWORLD University Hall ---- Pattern Recognition National University of Defense Technology Cai Xuanping
- ST32F103x Read the sensor value on X-NUCLEO-IKS01A3 via I2C
- Need help designing a CAN communication solution between two MCUs!
- 【NUCLEO-WL55JC2 Review 1】 Overview of STM32WL Chip
- Friends who are familiar with MP2307DN, please take a look!
- General welding specifications for MINI manufacturers
- Why constant current source simulation does not produce constant current
- [National Technology N32G457 Review] 1. Unboxing + Lighting
- The second article is a simple comparison between GD32VF103C START and ST official routines
- [GD32L233C-START Review] Part 3 PWM driving breathing light