当前位置: 首页 > news >正文

学习STC51单片机27(芯片为STC89C52RCRC)

每日一言

        你读过的书、走过的路、流过的汗,终将成就独一无二的你。

 

硬件:LCD1602液晶显示

非标协议外设  

概述

LCD1602(Liquid Crystal Display)是一种工业字符型液晶,能够同时显示 16×02 即 32 字符(16列两行)

那我们会发现明明就是屏幕上面只有32个位置来存放字符啊,那为什么要8位呢,明明5位就好啦(2的5次方等于32),因为其实这个他是可以移位的,就是其实不止我们看到的屏幕那么大的地方可以存放数据,后面还有看解释:

  • 容量:80 字节(地址范围 0x00~0x4F),但仅前 32 字节对应屏幕可见位置。
  • 映射关系

屏幕位置

地址范围

实际显示区域

第一行

0x00~0x27

0x00~0x0F(前 16 字节)

第二行

0x40~0x67

0x40~0x4F(前 16 字节)

LCD1602 的 8 位数据线(D0~D7)中,每一位都独立代表 1 个二进制数据位,共同组成 8 位数据(即 1 字节),用于传输指令或显示内容

反正就用8位数据线(代表8位数据)(当然也有4位的,4位就是每次每次传输的字节是8位的一半)

我们的接线

因为写入显示地址是要求最高位D7恒定位高电平

所以要在05这个位置写入字符的话,那其实这个位置的地址为0x85(0x80+0x05)也就是0x80+5  1000 0101

看时序图

写操作(我们的地址和内容其实都是写的操作,写到LCD1602里面)

RS为1的时候为内容

RS为0的时候是地址/指令

这个8位数据线就很像SBUF的作用,因为这个LCD1602是没有SBUF的所以我们要等于是做了一个这样的功能,用这个8位数据线,每一条数据线代表一个位,

BF为忙标志位  1代表忙  0代表不忙

LCD1602 的状态寄存器(用于读取忙标志 BF)和数据寄存器(用于写入显示数据)是两个独立的寄存器,它们的最高位功能不同,不会相互影响。

BF 的自动变化

当 LCD 执行内部操作(如清屏、初始化)时,硬件自动将 BF 置 1,表示忙碌。

操作完成后,硬件自动将 BF 置 0,表示空闲。

MCU 只需循环读取 BF,无需手动修改它。

精髓所在!!!

LCD1602 的初始化操作与忙信号检测是紧密关联的逻辑流程。初始化过程中需要执行清屏、显示模式设置等指令,这些操作需要一定时间完成,在此期间 LCD 处于 “忙碌” 状态(忙信号有效)。而忙信号检测的作用正是确认 LCD 是否已完成初始化及相关操作 —— 只有当检测到忙信号变为 “不忙” 时,才能确保后续的数据写入或指令发送能被正确执行。简而言之,初始化操作会触发 LCD 的忙碌状态,而忙信号检测则是判断初始化是否完成的关键依据,二者通过 “操作耗时→状态检测→后续执行” 的逻辑链条实现联动,以保证 LCD 显示控制的准确性和稳定性。

案例1:LCD实现显示一个字符C

代码解释

前期工作:我们先将RS RW 还有E 还有8位数据位都先做好工作

这边我们 将8位数据位用P0组来表示,因为刚好我的P0组够用这个8根数据线

然后我们用宏定义 #define dataBuffer P0 这样来表示 ,因为我们的数据就是存放在这个dataBuffer里面的,然后这个P0组所有的数据都汇聚到这边,所以dataBuffer 就好像是一个SBUF的作用 ,也是后面的写操作要将指令写到这个dataBuffer里面做铺垫

要将写内容和写指令的代码写出来,这边我们将它们封装成了两个函数data_Write_cmd 和data_Write_data

data_Write_cmd 将指令写到LCD1602的函数

这个函数我们通过手册知道写指令的操作需要将RS置为低电平,因为我们需要选择指令寄存器,RW呗是要一直为低电平因为RW为低电平就是写的操作

后面就要看时序图,和参数了

我们根据时序图写E和数据的写入,和变化

数据在E变高电平之前就进行了数据的写入,那么dataBuffer = cmd这个指令就要在E = 1之前写出来,后面就是我们根据参数,来给时间,那么这边他的单位是ns,我们单片机给一个_nop_()就够了,1个nop代表1us,

所以我们根据他的最低时间来穿插nop()函数

这个函数我们通过手册知道写内容的操作需要将RS置为高电平,因为我们需要选择数据寄存器,RW呗是要一直为低电平因为RW为低电平就是写的操作

写内容和写指令,都是写的操作,所以时序图是一样的,只是RS不同,也就是寄存器不同需要选择对应的寄存器,所以改一下RS为高电平就好了

随后我们根据手册知道,还需要进行LCD初始化(这个是初始化的代码,和命令和意图)

又随后我们还需要进行忙信号的检测

那么忙信号,就是我们进行初始化,的那些操作所需要耗费的时间,在进行初始化的时候,忙信号就会为1,初始化结束的时候,不忙就会为0 ..

我们来写忙信号封装的函数

通过手册得知,这边说明一下

重点看这个

        LCD1602 的指令寄存器(用于读取忙标志 BF指令寄存器,读的操作 所以是RS = 0; RW = 1;

那么我们肯定知道我们去读取忙信号是读的操作

检测BF的话其实就是检测bit7为1,那么就是先检测bit7是否为1,为1的时候说明还在初始化(还忙),那么我们就让他卡在循环那,不断检测,直到bit7为0,说明忙信号为0(不忙了),不忙了我们才让他出不断检测忙信号的循环。说明这样的话我们需要将检测忙信号做一个while循环就像这样:

        什么意思呢?就是刚开始就是忙的嘛所以我们先设置tmp和dataBuffer=0x80,为什么都设置0x80呢?           1、让强制进入检测忙信号的循环     2、因为我们检测忙信号,只是检测最高位bit7的位置是否是1,所以dataBuffer设置为0x80,然后这个dataBuffer他是总线嘛,是传输数据的,当不忙的时候,指令寄存器就会传输数据为0x某某,那么bit7就不会等于1等于0了,那么随之改变的tmp也会改变,那么tmp & 0x80就会等于0了(按位与是有0为0,全1为1),然后就跳出循环了,那么我们的写操作就可以开始进行了(不管是写指令还是写内容都要先开始检测忙信号,不检测的话会导致数据丢失)

所以现在我们确认好根据时序图来写代码

最后main函数里面:

1定义一个位置和定义一个内容

2调用初始化函数,在调用3写指令函数4写内容函数

案例2:LCD实现显示一句话

字符串的话也是一样的,基本上大差不差

在原来代码上面添加这些代码

要说的点在

这个地址哈0x80+6 那么这个就是很多工业的液晶显示的习惯就是  基址+移动

比如想显示在第一行  基址(0x80+0x00)+移动(6) 向右边偏移6个位置,如果不习惯的话也可以直接写成0x86

所以这个0x80+col  是0x80+6的这个写法不用太计较

先写地址,写完地址后写入内容,我们输入一句话(字符数组,在其他语言里叫做字符串)肯定是用指针啊,用指针遍历是我们的经典做法

每一行有每一行的地址的写法,所以我们用switch

http://www.xdnf.cn/news/872353.html

相关文章:

  • 34.1STM32下的can总线实现知识(区分linux)_csdn
  • 洛谷B2147 求 f(x,n)
  • 解决SQL Server SQL语句性能问题(9)——SQL语句改写(1)
  • 2ETLCloud:重新定义AI驱动的数据集成未来
  • 四、OpenCV图像处理- 视频操作
  • ArcGIS计算多个栅格数据的平均栅格
  • Educational Codeforces Round 179 (Rated for Div. 2)(A-E)
  • 看不见的守护者
  • 【机器人编程基础】循环语句for-while
  • 内存管理【Linux操作系统】
  • IEEE ICBCTIS 2025 会议征稿:探索区块链与信息安全的前沿学术之旅​
  • 操作系统学习(十三)——Linux
  • Elasticsearch 海量数据写入与高效文本检索实践指南
  • 上门服务小程序订单系统框架设计
  • Docker 常用命令详解
  • 洛谷每日1题-------Day40__P1720 月落乌啼算钱(斐波那契数列)
  • 卡西欧模拟器:Windows端功能强大的计算器
  • matlab实现高斯烟羽模型算法
  • AA-CLIP: Enhancing Zero-Shot Anomaly Detection via Anomaly-Aware CLIP
  • Linux操作系统Shell脚本概述与命令实战
  • 英伟达288GB HBM4+50P算力
  • 云数据库选型指南:关系型 vs NoSQL vs NewSQL的企业决策
  • Selenium自动化测试工具安装和使用(PyCharm)
  • Java运行环境配置日志(Log)运行条件,包含鸿蒙HarmonyOS
  • 函数与运算符重载
  • 【freertos-kernel】timer
  • 嵌入式链表操作原理详解
  • 《小明的一站式套餐服务平台:抽象工厂模式》
  • 线夹金具测温在线监测装置:电力设备安全运行的“隐形卫士”
  • GAMES202-高质量实时渲染(Real-Time Physically-based Materials)