51 MCU Development Series II_1602 Character LCD Display

Publisher:创意航海Latest update time:2016-12-12 Source: eefocus Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

After getting started with the 51 single-chip microcomputer and having a certain understanding of the running lights, you can start learning the display peripheral drivers, because learning often requires direct verification and tracking of results, and display peripherals can provide feedback on the code running status in a very intuitive way. Therefore, the author first analyzes and explains the use of 1602 character LCDs.

1. 1602 Character LCD Overview

The 1602 character LCD can display 32 characters in 16 columns and 2 rows at the same time. Different dot matrix character graphics are stored inside, including Arabic numerals, uppercase and lowercase English letters, common symbols, etc. Each dot matrix character graphic has a fixed code, which is consistent with the ASCII code we use. For example, the code for the uppercase English letter 'A' is 0x41. You only need to write the data 0x41 at the address location to display to display the character 'A'. It can be used for some simple information interaction designs.

2. Hardware Schematic


1602 requires three control lines, connected to the 5th to 7th control lines of the microcontroller P2 port, and uses an 8-bit parallel port to connect to the P0 port.

3. Driver Writing

We use the IO port of 51 to simulate the M6800 bus of 1602. In 1602.c, we implement the module function of 1602. The content is as follows:

 

#include "reg52.h"

#include "1602.h"

#include

 

// Delay nCount * 50 microseconds (12M)

// For STC 1T 51 MCU, delay nCount*50/12 microseconds

voidDelay_50us(unsigned int nCount)

{

      while(nCount--) {

           _nop_();_nop_();_nop_();_nop_();_nop_();

           _nop_();_nop_();_nop_();_nop_();_nop_();

           _nop_();_nop_();_nop_();_nop_();_nop_();

           _nop_();_nop_();_nop_();_nop_();_nop_();

           _nop_();_nop_();_nop_();_nop_();_nop_();

           _nop_();_nop_();_nop_();_nop_();_nop_();

           _nop_();_nop_();_nop_();_nop_();_nop_();

           _nop_();_nop_();_nop_();_nop_();_nop_();

           _nop_();_nop_();_nop_();_nop_();_nop_();

           _nop_();_nop_();_nop_();_nop_();_nop_();

      }

}

 

static voidDelay_5us()

{

      _nop_();_nop_();_nop_();_nop_();_nop_();

 

// Proteus needs to increase the following delay to simulate

// _nop_();_nop_();_nop_();_nop_();_nop_();

// _nop_();_nop_();_nop_();_nop_();_nop_();

}

 

static voidLCD_WriteData(unsigned char Dat)

{   

      LCD_RS_SET(); // pull up RS

      LCD_DATA(Dat); // Output 8-bit data

      Delay_5us(); // Data hold time, about 100ns (data sheet)

      LCD_EN_SET(); // Pull up the EN enable signal

      Delay_5us(); // Pulse hold time, about 450ns (data sheet)

      LCD_EN_CLEAR(); // Clear EN enable signal

}

 

static voidLCD_WriteCommand(unsigned char Dat)

{   

      LCD_RS_CLEAR(); // pull RS low

      LCD_DATA(Dat);

      Delay_5us();

      LCD_EN_SET();

      Delay_5us();

      LCD_EN_CLEAR();

}

 

unsigned charLCD_DisplayString(unsigned char Address, char *pString)

{

      unsigned char i;

      unsigned char MaxAddress;

      if (pString == (void *)0) {

           return 1; // Parameter error, pointer is null

      }

      if (Address >= Line1Addr &&Address < Line1Addr+16) {

           MaxAddress = Line1Addr+16; // The address is in the first line of 1602

      } else if (Address >= Line2Addr&& Address < Line2Addr+16) {

           MaxAddress = Line2Addr+16; // The address is in the second line of 1602

      } else {

           return 2; // LCD displays address error

      }

      LCD_WriteCommand(Address); // Write display address

      Delay_50us(1); // Command processing time is about 40us

      // The string ends or reaches the last address of the display line, ending writing the display

      for (i=0; Address+i

           if (pString[i] == 0) {

                break;

           }

           LCD_WriteData(pString[i]);

           Delay_50us(1);

      }

      return 0;

}

 

void LCD_Init()

{

      LCD_RW_CLEAR();

      LCD_EN_CLEAR();

      // 8-bit bus, double-line display of 5x7 dot matrix characters

      LCD_WriteCommand(0x38);    

      // Each command processing time is about 40us (data sheet)

      Delay_50us(1);

      // 1602 is displayed, but the cursor is not displayed

      LCD_WriteCommand(0x0C);

      Delay_50us(1);

      //Move the cursor right

      LCD_WriteCommand(0x06);

      Delay_50us(1);

      // Clear the screen. The processing time of the clear screen command is 1.6ms.         

      LCD_WriteCommand(0x01);

      Delay_50us(40);

}

 

We implement the module interface configuration and some hardware register access macros in the module header file 1602.h to facilitate porting and modifying the interface configuration. The module header file also introduces the module interface function, void LCD_Init() is used to initialize 1602, and unsigned char LCD_DisplayString (unsigned char Address, char*pString) is used to display string information at the specified location. Its content is as follows:

 

#ifndef __1602_H__

#define __1602_H__

 

#ifdef __cplusplus

extern "C" {

#endif

 

sbit LCD_RS = P2^5;

sbit LCD_RW = P2^6;

sbit LCD_EN = P2^7;

#define Line1Addr 0x80 // The first address of the first line of 1602

#define Line2Addr 0xc0 // The first address of the second line of 1602

 

#define LCD_EN_SET() {LCD_EN = 1;}

#define LCD_EN_CLEAR() {LCD_EN = 0;}

#define LCD_RW_SET() {LCD_RW = 1;}

#define LCD_RW_CLEAR() {LCD_RW = 0;}

#define LCD_RS_SET() {LCD_RS = 1;}

#define LCD_RS_CLEAR() {LCD_RS = 0;}

#define LCD_DATA(Dat) {P0 = (Dat);} // Port P0 outputs 8-bit data

 

void LCD_Init(void);

unsigned charLCD_DisplayString(unsigned char Address, char *pString);

void Delay_100us(unsigned intnCount);

 

#ifdef __cplusplus

}

#endif

 

#endif /*__1602_H__*/

 

The external module calls the 1602 driver function by introducing the 1602 module header file 1602.h. The simple test call is implemented as follows:

 

#include "reg52.h"

#include "1602.h"

 

void main()

{

      //String to be displayed 1

      codechar String1[] = {

           "huang20083200056"

      };

      //String 2 to be displayed

      codechar String2[] = {

           "QQ:1048272975"

      };

      // Initialize 1602

      LCD_Init();

      //Start displaying string 1 at the first address of the first line

      LCD_DisplayString(Line1Addr,String1);

      //Start displaying string 2 at the second address in the second line

      LCD_DisplayString(Line2Addr+1,String2);

      while(1);         

}


Reference address:51 MCU Development Series II_1602 Character LCD Display

Previous article:51 MCU Development Series 3_Digital Tube Dynamic Scanning Display
Next article:51 MCU Development Series 1-51 MCU Development Environment Construction and Entry Assembly Code

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号