首页 测试文本

清翔零基础教你学51单片机_个人学习笔记(17)_LCD1602与指针(理论+实践)

说明

本人使用的是清翔的51单片机开发板,如果型号相同最方便,但是如果型号不同也可以参考,因为芯片都是一样的,只是外设不同而已,使用时只需要对照自己的开发板原理图稍微修改下引脚即可。

|

本次笔记对应视频教程的第46,47集 LCD1602与指针(理论+实践)

如果笔记之中有任何错误,请在评论区指出,谢谢

一、LCD1602

1.1 实物图

1602表示每行可以显示16个字符,总共可以显示2行

1.2 简单介绍


以下内容来源于AI自动生成,仅供参考

LCD1602,也被称为1602液晶显示器或16x2字符液晶显示器,是一种常见的字符型液晶显示器模块。它由两行,每行可以显示16个字符(共32个字符)组成。

LCD1602模块通常由以下几个主要部分组成:

  1. LCD面板:是一个矩形的玻璃面板,上面有液晶材料和字符形状的透明电极。液晶材料的结构通过施加电场来改变光的透过程度,从而显示字符。

  2. 控制器芯片:是内置在LCD模块中的芯片,主要负责驱动液晶显示,控制显示内容和与外部设备通信。常见的控制器芯片有HD44780、KS0066等,这些芯片提供了通用的命令和功能接口。

  3. 背光光源:LCD1602通常具有背光功能,使得屏幕能在低光照条件下清晰可见。背光通常由白色LED或EL(电致发光)灯提供。

  4. 连接引脚:LCD1602模块通常有16个引脚,用于连接到外部电路。这些引脚包括数据线(通常是4位或8位)、使能(EN)、读写选择(RW)、数据/命令选择(RS)、以及背光控制(通常是正或负电源引脚)等。

LCD1602使用时,通常需要通过外部电路将其连接到微控制器或其他设备上。具体的连接方式和通信协议可以根据具体的控制器芯片和开发平台而有所差异。

一般来说,使用LCD1602显示内容需要以下步骤:

  1. 初始化:通过发送初始化命令,设置显示模式、显示光标等参数。

  2. 编写字符或字符串:将要显示的字符或字符串存储在适当的内存位置中,准备发送到LCD模块。

  3. 发送命令或数据:通过向LCD模块发送命令或数据,控制显示内容和操作。

  4. 控制光标:可以通过命令控制光标的位置和显示状态,如移动光标、显示/隐藏光标等。

  5. 清屏:可以通过命令清空LCD屏幕上的内容,重新开始显示新的内容。


1.3 参数说明

以下内容来自数据手册,中文,而且内容很少只有5页,便于理清大概用法

RS,RW,E是控制引脚,D0~D7是数据引脚,A,K是背光,VL,也就是实物上的V0是连接了一个电位器调节显示对比度的。

数据手册给出的8051系列推荐连接电路如下

1.4 开发板原理图连接

D0~D7,也就是数码管的两个锁存器所连接的P0端口

1.5 基本操作时序

1.6 状态字说明

也就是说每次操作前都要读状态,判断位7是否为0,不为0表示液晶处于忙碌状态,无法接收数据。

1.7  RAM映射

虽然每行第16个之后的内容不会显示出来,但是LCD1602有一个移动命令, 如果整屏左移就可以把原来显示不到的数据显示出来

1.8 指令说明

显示模式设置的00111000就是0x38,下面可能会说到38H指的就是显示模式设置

1.9 时序图

 

二、编程

2.1 创建工程

复制上一份工程文件夹,修改名称为“17.LCD1602”,进入项目文件夹,打开工程文件,删除main.c函数的内容。

2.2 main.c

显示命令是ASCII 码,发送对应的ASCII码就会显示对应的字符

void main()
{
    uchar i;
    LCD1602WCByte(0x38);    // 初始化16*2
    LCD1602WCByte(0x0c);    // 打开显示,不显示指针
    LCD1602WCByte(0x01);    // 清屏
    LCD1602WCByte(0x06);    // 光标自动+1,不整屏移动
    LCD1602cursor(1, 1);    // 设置指针1行1列
    for (i = 0; i < 16; i++)
        LCD1602WDByte(48);
    LCD1602cursor(2, 1);    // 设置2行1列
    for (i = 0; i < 16; i++)
        LCD1602WDByte(48);
    while(1);
}

/**********************************************************************************/
/*************************  LCD1602  *********************************************/
/**********************************************************************************/

// 判断是否忙信号
void LCD1602ReadBusy()
{
    uchar busy;
    P0 = 0xff;
    RS = 0;
    RW = 1;
    do
    {
        LCD1602EN = 1;      // 使能
        busy = P0;          // 获取数值
        LCD1602EN = 0;
    } while (busy & 0x80);
}

// 写1字节命令
void LCD1602WCByte(uchar cmd)
{
    LCD1602ReadBusy();
    RS = 0;
    RW = 0;
    P0 = cmd;
    LCD1602EN = 1;
    LCD1602EN = 0;
}

// 写数据
void LCD1602WDByte(uchar dat)
{
    LCD1602ReadBusy();
    RS = 1;
    RW = 0;
    P0 = dat;
    LCD1602EN = 1;
    LCD1602EN = 0;
}

/**
 * @brief 设置光标位置
 * @param row 设置行,范围1~2
 * @param column 设置列,范围1~16
 */
void LCD1602cursor(uchar row, uchar column)
{
    LCD1602WCByte(0x80 | (0x40 * (row - 1) + column - 1));
}

设置光标位置的函数,如果是第1行,那么直接用0x80加上对应的列就行了,如果是第二行,就需要0x80加上列,再加上0x40,因为第二行地址是从0x40开始的,第一行也要加上起始值0x00,不过省略了。还有一种方法是用3元运算,

void LCD1602cursor(uchar row, ucahr column){
    LCD1602WCByte(0x80 | (((row == 1)? 0x00:0x40) + column - 1));
}

如果想更方便以后使用,可以直接这样

2.2.1 初始化函数封装

void LCD1602init()
{
    LCD1602WCByte(0x38);    // 初始化16*2
    LCD1602WCByte(0x0c);    // 打开显示,不显示指针
    LCD1602WCByte(0x01);    // 清屏
    LCD1602WCByte(0x06);    // 光标自动+1,不整屏移动
    LCD1602cursor(1, 1);    // 设置指针1行1列
}

再写好函数声明,这样以后使用就可以直接调用一次LCD1602init函数就可以了。

2.2.2 闪烁光标

如果要想闪烁光标

LCD1602WCByte(0x0f);//打开显示,闪烁光标

整屏移动可以自行尝试

2.2.3 显示单个字符

由于字符(char)类型在内存中就按ASCII码表示,因此,可以直接写字符而不必查表就能显示

void main()
{
    uchar a[] = "a";
    LCD1602init();
    LCD1602WDByte(a[0]);
    while(1);
}

2.2.4 显示多个字符

只需要把显示单个字符的内容循环一下就行了

void main()
{
    uchar a[] = "abcdefghijklmnop";
    uchar i = 0;
    LCD1602init();
    while (a[i] != '\0')
    {
        LCD1602WDByte(a[i]);
        i++;
    }
    while (1);
}

判断字符结束的标志是'\0',因为字符串结尾是 '\0'

2.3 main.h

写一下变量定义和函数声明

/************************************************  LCD1602  *******************/
sbit RS = P3^5;
sbit RW = P3^6;
sbit LCD1602EN = P3^4;

void LCD1602ReadBusy();
void LCD1602WCByte(uchar cmd);
void LCD1602WDByte(uchar dat);
void LCD1602cursor(uchar row, uchar column);

2.4 现象

如果只是做简单应用,那么到这里就可以结束了。如果想学更高级的玩法,请往下看。

三、指针

指针学习建议看江科大的视频,江科大也有51教程,我看了下指针视频讲的还是很不错的。

[C语言] 指针的详解与应用-理论结合实践,真正理解指针!

储存单元的地址就是指针。

利用指针来显示多个字符(1)

void main()
{
    // 循环显示多个字符
    // uchar a[] = "abcdefghijklmnop";
    // uchar i = 0;
    // LCD1602init();
    // while(a[i] != '\0')
    // {
    //     LCD1602WDByte(a[i]);
    //     i++;
    // }

    // 指针循环显示多个字符
    uchar a[] = "abcdefghijklmnop";
    uchar *pa = a;  // 数组名称视为数组首地址
    LCD1602init();
    while (*pa != '\0')
        LCD1602WDByte(*pa++);
    while (1);
}

我个人感觉还是原来的方法起来更简单,直接用i循环。

利用指针来显示多个字符(2)

// 指针移屏显示多个字符
uchar a[] = "abcdefghijklmnop";
uchar *pa;
pa = a;
LCD1602WCByte(0x38);    // 初始化16*2
LCD1602WCByte(0x0f);    // 打开显示,0ch不显示光标 0fh光标闪烁
LCD1602WCByte(0x01);    // 清屏
LCD1602WCByte(0x07);    // 光标自动+1,整屏左移
LCD1602cursor(1, 16);   // 设置指针1行16列
while (*pa != '\0')
{
    LCD1602WDByte(*pa++);
    delay(100);
}

这里因为数组a是指针数组,所以pa = a[0]也表示一个地址,如果这里a不是指针数组了,那么就要写pa = a;

指针我本身也不是很熟,江协科技讲的确实不错,也可以再参考下别人的指针教程。写到这我还是觉得用i循环来的简单。

刚才那个用指针的循环左移效果用i循环也能做到

uchar a[] = "abcdefghijklmnop";
uchar i = 0;

LCD1602WCByte(0x38);    // 初始化16*2
LCD1602WCByte(0x0f);    // 打开显示,0ch不显示光标 0fh光标闪烁
LCD1602WCByte(0x01);    // 清屏
LCD1602WCByte(0x07);    // 光标自动+1,整屏左移

LCD1602cursor(1, 16);   // 设置指针1行16列

while(a[i] != '\0')
{
    LCD1602WDByte(a[i]);
    i++;
    delay(500);
}

本次笔记对应视频教程的第46,47集 LCD1602与指针(理论+实践),到此结束。感觉LCD1602还是很简单的,没有想象的那么难,能自动保持显示的器件,真是省了CPU不少事

|

视频笔记部分差不多了,后面的综合实训都是前面讲过的功能,拼凑起来就成了,至于后面的C语言结构体等知识,看别人的就行了,我C语言也不怎么好。

|

如果笔记之中有任何错误,请在评论区指,谢谢

posted @ 2025-11-08 15:27  BO_S  阅读(26)  评论(0)    收藏  举报
页脚 测试文本