波特律动
课程中心/51单片机教程/【10】液晶屏LCD1602

【10】液晶屏LCD1602

本课资源下载
共 6 个资源
P10LCD1602

本节课的标准源代码工程/可供参考

V1.0压缩包55 KB
下载
LCD1602A 5V

液晶屏

PDF 文档4.1 MB
预览下载
LCD1602_c
文档资料8.5 KB
预览下载
LCD1602_h
文档资料3.8 KB
预览下载
Delay_c
文档资料516 B
预览下载
Delay_h
文档资料144 B
预览下载

课程笔记


本节目标概括

创建工程 > 编写点灯代码 > 编译HEX文件 > 下载到学习板 > LCD显示

用LCD1602.c完成LCD屏的显示

编译并下载程序到学习板,即可看到程序效果:LCD屏显示数据


LCD1602液晶显示屏

  • LCD ( Liquid Crystal Display 的简称)液晶显示器。能够同时显示16x2,32个字符,是一种专门用来显示字母、数字、符号等的点阵型液晶模块。
  • LCD1602主要用来显示数字、字母、图形以及少量自定义字符。可以显示2行16个字符,拥有16个引脚,其中8位数据总线D0-D7,和RS、R/W、EN三个控制端口,工作电压为5V,并且带有字符对比度调节V0和背光源AK。


驱动库移植

  1. 在本课资源下载处下载LCD1602.c , LCD1602.h和 Delay.c , Delay.h 文件(LCD1602的驱动库需要用到delay函数)
  2. 如下图,将这四个文件复制在需要移植的工程的根目录
  1. 打开该工程,点击图示的方块图标
  1. 点击添加文件,查找范围为工程的路径,按住ctr键选中两个c文件,点击Add,然后关闭即可看到文件已添加完成

5.在文件中#include"LCD1602.h"即可调用LCD驱动库函数


例程讲解

下面介绍了如何自己实现该例程的功能

lcd1602驱动库功能函数代码介绍:

lcd1602.c
C语言
1/**
2 * @brief LCD1602 初始化
3 * @note 按数据手册推荐的 8 位初始化流程执行,确保上电后进入已知状态
4 */
5void LCD_Init(void)
6{
7
8 LATCH_HOLD_ALL();
9
10 LCD_RS = 0; /* 先置为命令模式 */
11 LCD_EN = 0; /* 使能脚拉低 */
12
13 /* Follow the recommended 8-bit initialization flow. */
14 delay(LCD_POWER_ON_WAIT_MS);
15 LCD_WriteCommand(LCD_CMD_FUNCTION_SET);
16 delay(LCD_INIT_RETRY_WAIT_MS);
17 LCD_WriteCommand(LCD_CMD_FUNCTION_SET);
18 delay_100us(LCD_INIT_RETRY_WAIT_100US);
19 LCD_WriteCommand(LCD_CMD_FUNCTION_SET);
20
21 LCD_WriteCommand(LCD_CMD_FUNCTION_SET);
22 LCD_WriteCommand(LCD_CMD_DISPLAY_OFF);
23 LCD_WriteCommand(LCD_CMD_CLEAR);
24 LCD_WriteCommand(LCD_CMD_ENTRY_MODE);
25 LCD_WriteCommand(LCD_CMD_DISPLAY_CTRL);
26}
27
28/**
29 * @brief 显示一个字符
30 */
31void LCD_ShowChar(unsigned char Line, unsigned char Column, char Char)
32{
33 LCD_SetCursor(Line, Column);
34 LCD_WriteData(Char);
35}
36
37/**
38 * @brief 显示字符串
39 * @note 遇到 '\0' 结束;不处理换行,超出屏宽由 LCD 自身行为决定
40 */
41void LCD_ShowString(unsigned char Line, unsigned char Column, char *String)
42{
43 unsigned char i;
44
45 LCD_SetCursor(Line, Column);
46 for (i = 0; String[i] != '\0'; i++)
47 {
48 LCD_WriteData(String[i]);
49 }
50}
51/**
52 * @brief 显示有符号十进制数
53 * @param Length 数字部分的显示位数;为 0 时按实际位数显示
54 * @note 符号位固定占 1 个字符,显示在数字前面
55 */
56void LCD_ShowSignedNum(unsigned char Line, unsigned char Column, int Number, unsigned char Length)
57{
58 unsigned char i;
59 unsigned int idata AbsNumber;
60 unsigned char Digit;
61 unsigned char effLen;
62 unsigned char clearCnt;
63
64 effLen = Length;
65 clearCnt = 0;
66
67 LCD_SetCursor(Line, Column);
68
69 if (Number >= 0)
70 {
71 LCD_WriteData(SIGN_PLUS);
72 AbsNumber = Number;
73 }
74 else
75 {
76 LCD_WriteData(SIGN_MINUS);
77 AbsNumber = -Number;
78 }
79
80 if (Length == 0)
81 {
82 effLen = LCD_DecDigits(AbsNumber);
83 }
84
85 for (i = effLen; i > 0; i--)
86 {
87 Digit = AbsNumber / LCD_Power(DECIMAL_BASE, i - 1) % DECIMAL_BASE;
88 LCD_WriteData(Digit + DIGIT_CHAR_OFFSET);
89 }
90
91 if (Length == 0)
92 {
93 clearCnt = (DECIMAL_MAX_DIGITS > effLen) ? (DECIMAL_MAX_DIGITS - effLen) : 0;
94 if (clearCnt)
95 {
96 LCD_ClearChars(Line, Column + 1 + effLen, clearCnt);
97 }
98 }
99}
100/**
101 * @brief 显示 long 型十进制数
102 * @note 先转成字符数组再逆序输出,避免多次调用 LCD_Power
103 */
104void LCD_ShowLongNum(unsigned char Line, unsigned char Column, long Number)
105{
106 unsigned char i;
107 unsigned char TempIndex;
108 unsigned char DisplayLen;
109 unsigned char pdata Temp[10];
110 unsigned long pdata Value;
111
112 TempIndex = 0;
113 DisplayLen = 0;
114
115 LCD_SetCursor(Line, Column);
116
117 if (Number < 0)
118 {
119 LCD_WriteData(SIGN_MINUS);
120 DisplayLen++;
121 Value = 0UL - (unsigned long)Number;
122 }
123 else
124 {
125 Value = (unsigned long)Number;
126 }
127
128 if (Value == 0)
129 {
130 LCD_WriteData(DIGIT_CHAR_OFFSET);
131 DisplayLen++;
132 }
133 else
134 {
135 while (Value > 0)
136 {
137 Temp[TempIndex++] = Value % DECIMAL_BASE + DIGIT_CHAR_OFFSET;
138 Value /= DECIMAL_BASE;
139 }
140
141 for (i = TempIndex; i > 0; i--)
142 {
143 LCD_WriteData(Temp[i - 1]);
144 DisplayLen++;
145 }
146 }
147
148 if (LONG_MAX_CHARS > DisplayLen)
149 {
150 LCD_ClearChars(Line, Column + DisplayLen, LONG_MAX_CHARS - DisplayLen);
151 }
152}
153/**
154 * @brief 显示无符号十六进制数
155 * @param Length 显示位数;为 0 时按实际位数显示
156 */
157void LCD_ShowHexNum(unsigned char Line, unsigned char Column, unsigned int Number, unsigned char Length)
158{
159 unsigned char i;
160 unsigned char Digit;
161 unsigned char effLen;
162 unsigned char clearCnt;
163
164 effLen = Length;
165 clearCnt = 0;
166
167 LCD_SetCursor(Line, Column);
168
169 if (Length == 0)
170 {
171 effLen = LCD_HexDigits(Number);
172 }
173
174 for (i = effLen; i > 0; i--)
175 {
176 Digit = Number / LCD_Power(HEX_BASE, i - 1) % HEX_BASE;
177
178 if (Digit < HEX_DIGIT_THRESHOLD)
179 {
180 LCD_WriteData(Digit + DIGIT_CHAR_OFFSET);
181 }
182 else
183 {
184 LCD_WriteData(Digit + HEX_LETTER_OFFSET);
185 }
186 }
187
188 if (Length == 0)
189 {
190 clearCnt = (HEX_MAX_DIGITS > effLen) ? (HEX_MAX_DIGITS - effLen) : 0;
191 if (clearCnt)
192 {
193 LCD_ClearChars(Line, Column + effLen, clearCnt);
194 }
195 }
196}
197/**
198 * @brief 显示无符号二进制数
199 * @param Length 显示位数;为 0 时按实际位数显示
200 */
201void LCD_ShowBinNum(unsigned char Line, unsigned char Column, unsigned int Number, unsigned char Length)
202{
203 unsigned char i;
204 unsigned char Digit;
205 unsigned char effLen;
206 unsigned char clearCnt;
207
208 effLen = Length;
209 clearCnt = 0;
210
211 LCD_SetCursor(Line, Column);
212
213 if (Length == 0)
214 {
215 effLen = LCD_BinDigits(Number);
216 }
217
218 for (i = effLen; i > 0; i--)
219 {
220 Digit = Number / LCD_Power(BINARY_BASE, i - 1) % BINARY_BASE;
221 LCD_WriteData(Digit + DIGIT_CHAR_OFFSET);
222 }
223
224 if (Length == 0)
225 {
226 clearCnt = (BINARY_MAX_DIGITS > effLen) ? (BINARY_MAX_DIGITS - effLen) : 0;
227 if (clearCnt)
228 {
229 LCD_ClearChars(Line, Column + effLen, clearCnt);
230 }
231 }
232}



在主函数main()执行以下代码:

C语言
1#include <stc89c5xrc.h>
2#include "LCD1602.h"
3#include "Delay.h"
4
5// =========== 现象 ===========
6// 注意⚠️ 第一次插上LCD1602时需要拧电位器调下对比度,要不可能完全看不出显示痕迹
7// 现象:LCD1602上循环显示不同内容
8
9void main()
10{
11 unsigned char i = 0;
12 LCD_Init();
13 while (1)
14 {
15 // 显示字符串
16 LCD_ClearLine(1);
17 LCD_ShowString(1, 1, "THIS IS LINE 1");
18 LCD_ClearLine(2);
19 LCD_ShowString(2, 1, "THIS IS LINE 2");
20 delay(2000);
21
22 // 显示有符号数字
23 LCD_ClearLine(1);
24 LCD_ShowString(1, 1, "Signed Num");
25 LCD_ClearLine(2);
26 LCD_ShowSignedNum(2, 1, -32767, 0);
27 delay(2000);
28
29 // 显示无符号数字
30 LCD_ClearLine(1);
31 LCD_ShowString(1, 1, "Unsigned Num");
32 LCD_ClearLine(2);
33 LCD_ShowNum(2, 1, 233, 0);
34 delay(2000);
35
36 // 显示Hex数字(16进制)
37 LCD_ClearLine(1);
38 LCD_ShowString(1, 1, "Hex Num");
39 LCD_ClearLine(2);
40 LCD_ShowHexNum(2, 1, 0x4CF9, 0);
41 delay(2000);
42
43 // 显示Bin数字(二进制)
44 LCD_ClearLine(1);
45 LCD_ShowString(1, 1, "Bin Num");
46 LCD_ClearLine(2);
47 LCD_ShowBinNum(2, 1, 0x0055, 8);
48 delay(2000);
49
50 // 显示固定长度的变化数字
51 LCD_ClearLine(1);
52 LCD_ShowString(1, 1, "Real Time Num");
53 for (i = 0; i < 25; i++)
54 {
55 LCD_ClearLine(2);
56 LCD_ShowNum(2, 1, i * 25, 4);
57 delay(200);
58 }
59 delay(2000);
60
61 // 演示结束
62 LCD_ClearLine(1);
63 LCD_ShowString(1, 1, "DEMO FINISHED");
64 LCD_ClearLine(2);
65 delay(2000);
66 }
67}

注意一定先移植好头文件,并且使用LCD_Init();初始化函数后才可以编写代码