基于STC12C5A60S2系列1T 8051单片读写掉电保存数据IIC总线器件24C02地址码并显示在液晶显示器LCD1602上应用

news2024/9/23 13:27:43

基于STC12C5A60S2系列1T 8051单片读写掉电保存数据IIC总线器件24C02地址码并显示在液晶显示器LCD1602上应用

  • STC12C5A60S2系列1T 8051单片机管脚图
  • STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置
  • STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍
  • 液晶显示器LCD1602简单介绍
  • 掉电保存数据芯片24C02简单介绍
  • IIC通信简单介绍
    • 通过液晶显示器LCD1602显示24C02地址码

STC12C5A60S2系列1T 8051单片机管脚图

在这里插入图片描述在这里插入图片描述

STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置

在这里插入图片描述

STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍

在这里插入图片描述在这里插入图片描述

液晶显示器LCD1602简单介绍

在这里插入图片描述在这里插入图片描述
DDRAM : 数据显示随机存储器 液晶显示器显示数据是来于数据显示随机存储器
在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述
CGRAM:字符生成随机存储器 用户自定义字符会存储在字符生成存储器
在这里插入图片描述
CGROM:字符库只读存储器 只提供字符 用液晶显示器显示这些字符

总结:不管是CGRAM(字符生成随机存储器)自定义的字符 还是CGROM(字符库只读存储器)原有的字符 写进DDRAM(数据显示随机存储器)内存地址上 才能在液晶显示器屏幕显示出来
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

掉电保存数据芯片24C02简单介绍

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

IIC通信简单介绍

在这里插入图片描述在这里插入图片描述

通过液晶显示器LCD1602显示24C02地址码

在这里插入图片描述在这里插入图片描述

#include <stc12c5a60s2.h>
#include <intrins.h>
#define uchar unsigned char//自定义无符号字符型为uchar
#define uint unsigned int//自定义无符号整数型为uint 
#define LCD1602PinMode1 0x38//自定义液晶显示器LCD1602八位数据接口的两行5*8点阵 
#define LCD1602PinMode2 0x28//自定义液晶显示器LCD1602四位数据接口的两行5*8点阵
#define LCD1602CleanScreen 0x01//自定义液晶显示器LCD1602清屏变量
#define LCD1602CursorRst 0x02//自定义液晶显示器LCD1602光标复位 
#define LCD1602DisplayCursorGlint 0x0f//自定义液晶显示器LCD1602开显示开光标开光标闪烁 
#define LCD1602DisplayCursorNoGlint 0x0e//自定义液晶显示器LCD1602开显示开光标不开光标闪烁  
#define LCD1602DisplayNoCursorNoGlint 0x0c//自定义液晶显示器LCD1602开显示不开光标不开光标闪烁  
#define LCD1602NoDisplayCursorNoGlint 0x08//自定义液晶显示器LCD1602不开显示不开光标不开光标闪烁  
#define LCD1602CursorRightMoveDisplayNoMove 0x06//自定义液晶显示器LCD1602光标右移 显示不移动
#define LCD1602CursorLeftMoveDisplayNoMove 0x04//自定义液晶显示器LCD1602光标左移 显示不移动
#define LCD1602PictureLeftMove 0x07//自定义液晶显示器LCD1602画面左移 AC自增
#define LCD1602PictureRightMove 0x05//自定义液晶显示器LCD1602画面右移 AC自减
#define LCD1602CursorRightMove 0x10//自定义液晶显示器LCD1602光标右移
#define LCD1602CursorLeftMove 0x14//自定义液晶显示器LCD1602光标左移
#define LCD1602DisplayRightMove 0x18//自定义液晶显示器LCD1602显示右移
#define LCD1602DisplayLeftMove 0x1c//自定义液晶显示器LCD1602显示左移
#define LCD1602DisplayData P0//自定义液晶显示器LCD1602显示数据为单片机P0组引脚
sbit LCD1602RS P2^5;//位定义液晶显示器LCD1602数据指令变量为单片机P2.5引脚
sbit LCD1602RW P2^6;//位定义液晶显示器LCD1602读写变量为单片机P2.6引脚 
sbit LCD1602EN P2^6;//位定义液晶显示器LCD1602使能变量为单片机P2.7引脚 
sbit I2CSCL = P1^0;//位定义I2C时钟变量为P1.0端口
sbit I2CSDA = P1^1;//位定义I2C数据变量为P1.1端口
 bit 24C02Address(uchar Address)//24C02地址函数
{
  bit Ack;//声明一位应答变量
  I2CStar();//I2C启动函数
  I2CWriteByte(Address << 1);//I2C写字节函数 单片机通过I2C通信写匹配通信地址给24C02
  Ack = I2CReceiveAck();//I2C接收应答函数接收应答赋给应答变量 即24C02作为从机接收单片机作为主机发送来的地址信息 并做出返回应答
  I2CStop();//I2C停止函数
  return Ack;//返回应答
 }
 void I2CDelay()//I2C延时函数
{
  _nop_();
  _nop_();
  _nop_();
  _nop_();
 }
 void I2CStar()//I2C启动函数
{
  I2CSCL = 1;//空闲时 I2C时钟变量置高电平
  I2CSDA = 1;//空闲时 I2C数据变量置高电平
  I2CDelay();//I2C延时
  I2CSDA = 0;//I2C数据变量置低电平
  I2CDelay();//I2C延时
  I2CSCL = 0;//I2C时钟变量置低电平
 }
 bit I2CWriteByte(uchar Data)//I2C写字节函数
{
  uchar Temp;//声明临时变量
  bit Ack;//声明一位应答变量
  for(Temp = 0x80;Temp = !0;Temp >>= 1)//从某八位二进制数的最高位往最低位每次移出一位二进制数 取变化后的八位二进制数进行下一步从最高位往最低位每次右移出一位二进制数 直到写完某八位二进制数的每一位二进制数
 {
   if((Temp & Data) == 0)//判断临时变量包含的数据与上写入某八位二进制数得出八位二进制数最高位是否为0
   I2CSDA = 0;//I2C数据变量写0
   else//否则
   I2CSDA = 1;//I2C数据变量写1
   I2CDelay();//I2C延时
   I2CSCL = 1;//I2C时钟变量置高电平
   I2CDelay();//I2C延时
   I2CSCL = 0;//I2C时钟变量置低电平
  }
  Ack = I2CReceiveAck();//I2C接收应答函数接收应答赋给应答变量
  return (Ack);//返回应答
 }
 void SendAck(bit Ack)//I2C发送应答函数
{
  I2CSDA = Ack;//应答变量赋给I2C数据变量
  I2CDelay();//I2C延时
  I2CSCL = 1;//I2C时钟变量置高电平
  I2CDelay();//I2C延时
  I2CSCL = 0;//I2C时钟变量置低电平
 }
 bit ReceiveAck()//I2C接收应答函数
{
  bit Ack;//声明一位应答变量
  I2CSDA = 1;//I2C数据变量置高电平
  I2CDelay();//I2C延时
  I2CSCL = 1;//I2C时钟变量置高电平
  Ack = I2CSDA;//I2C数据变量
  I2CDelay();//I2C延时
  I2CSCL = 0;//I2C时钟变量置低电平
  return (Ack);//返回应答
 }
 uchar I2CReadByte()//I2C读字节函数
{
  uchar Data;//声明数据变量
  uchar Temp;//声明临时变量
  I2CSDA = 1;//I2C数据变量置高电平
  for(Temp = 0x80;Temp = !0;Temp >>= 1)//从某八位二进制数的最高位往最低位每次右移出一位二进制数 取变化后的八位二进制数进行下一步从最高位往最低位每次右移出一位二进制数 直到读完某八位二进制数的每一位二进制数
 {
   I2CDelay();//I2C延时
   I2CSCL = 1;//I2C时钟变量置高电平
   if(I2CSDA == 1)//判断I2C数据变量是否置高电平
  {
    Data |= Temp;//临时变量包含的数据或上某八位二进制数读出八位二进制数最高位为1
   }
   else//否则
  {
    Data &= ~Temp;//临时变量包含的数据与上某八位二进制数读出八位二进制数最高位为0
   }
   I2CDelay();//I2C延时
   I2CSCL = 0;//I2C时钟变量置低电平
  }
  return Data;//返回数据变量
 }
 void I2CStop()//I2C停止函数
{
  I2CSCL = 0;//I2C时钟变量置低电平
  I2CSDA = 0;//I2C数据变量置低电平
  I2CDelay();//I2C延时
  I2CSCL = 1;//I2C时钟变量置高电平
  I2CDelay();//I2C延时
  I2CSDA = 1;//I2C数据变量置高电平
  I2CDelay();//I2C延时
 }
 void LCD1602Init()//液晶显示器初始化函数
{
  LCD1602WriteCommand(LCD1602PinMode1);//液晶显示器LCD1602八位数据接口的两行5*8点阵 
  LCD1602WriteCommand(LCD1602DisplayNoCursorNoGlint);//液晶显示器LCD1602开显示不开光标不开光标闪烁
  LCD1602WriteCommand(LCD1602CursorRightMove);//液晶显示器LCD1602光标右移
  LCD1602WriteCommand(LCD1602CleanScreen);//液晶显示器LCD1602清屏
 }
 void LCD1602ReadBusy()//液晶显示器读忙函数
{
  uchar i;//声明一个计数变量
  uchar State;//声明状态变量
  LCD1602DisplayData = 0xff;//液晶显示器LCD1602显示数据变量拉高
  LCD1602RS = 0;//液晶显示器LCD1602写入指令
  LCD1602RW = 1;//读取液晶显示器LCD1602
  do
 {
   LCD1602EN = 1;//液晶显示器LCD1602使能
   State = LCD1602DisplayData;//液晶显示器LCD1602显示数据赋给状态变量
   LCD1602EN = 0;//关液晶显示器LCD1602使能
   i++;
   if(i > 200)//防止液晶显示器LCD1602因损坏陷入do{}while循环中 导致无法执行其他程序
   break;
  }
  while(State & 0x80);//判断状态变量是否为1 为1表示液晶显示器LCD1602在忙 否则不忙
 }
 void LCD1602WriteCommand(uchar Command)//液晶显示器LCD1602写命令函数
{
  LCD1602ReadBusy();//液晶显示器读忙函数
  LCD1602RS = 0;//液晶显示器LCD1602写入指令
  LCD1602RW = 0;//写入液晶显示器LCD1602
  LCD1602DisplayData = Command;//指令变量含有的数据赋给液晶显示器LCD1602显示数据变量
  LCD1602EN = 1;//液晶显示器LCD1602使能
  LCD1602EN = 0;//关液晶显示器LCD1602使能
 } 
 void LCD1602WriteData(uchar Data)//液晶显示器LCD1602写数据函数
{
  LCD1602ReadBusy();//液晶显示器LCD1602读忙函数
  LCD1602RS = 1;//液晶显示器LCD1602写入数据
  LCD1602RW = 0;//写入液晶显示器LCD1602
  LCD1602DisplayData = Data;//数据变量含有的数据赋给液晶显示器LCD1602显示数据变量
  LCD1602EN = 1;//液晶显示器LCD1602使能
  LCD1602EN = 0;//关液晶显示器LCD1602使能
 } 
 void LCD1602SetDisplayPosition(uchar x,uchar y)//液晶显示器LCD1602设置显示位置
{
  if(0 == y)//液晶显示器LCD1602第一行显示
 {
   LCD1602WriteCommand(0x80 | x);//液晶显示器LCD1602第一行第一位开始显示 0x80为液晶显示器LCD1602显示数据储存地址最高位初始值
  }
  else//液晶显示器LCD1602第二行显示
 {
   LCD1602WriteCommand(0x80 | (0x40 + x));//液晶显示器LCD1602第二行第一位开始显示 0x40为液晶显示器LCD1602第二行显示位置初始地址
  }
 }
 void LCD1602ShowString(uchar x;uchar y;uchar *String)//液晶显示器LCD1602显示字符串函数 x变量为液晶显示器LCD1602横向显示 相当于列 y变量为液晶显示器LCD1602纵向显示 相当于行
{
  LCD1602SetDisplayPosition(x,y);//液晶显示器LCD1602设置显示位置
  while(*String != ' \0 ')//判断字符串是否全部显示 
 {
   LCD1602WriteData(*String ++)//液晶显示器LCD1602写入字符串
  }
 }
 /****
 void LCD1602WriteCGRAM()//液晶显示器LCD1602写入自定义字符储存器函数
{
  uchar i;//声明循环变量
  LCD1602WriteCommand(0x40);//0x40为液晶显示器LCD1602自定义字符储存地址最高位初始值
  for(i = 0;i < 8;i++)//循环八次 把写入液晶显示器LCD1602自定义字符储存地址上的自定义字符写出来
 {
   LCD1602WriteData(String[i]);//把写入液晶显示器LCD1602自定义字符储存地址上的自定义字符写出来
  }
  LCD1602WriteCommand(0x80 | 0x05);//0x80为液晶显示器LCD1602显示数据储存地址最高位初始值 0x05为液晶显示器LCD1602显示位置
  LCD1602WriteData(0x00);//液晶显示器LCD1602写自定义字符到CGROM(即字模存储用空间)第一个位置显示出来
 }
 ****/
 /****
 void LCD1602UserDefined(uchar x,uchar y,uchar Position,uchar *String)//液晶显示器LCD1602用户自定义字符函数
{
  uchar i;//声明循环变量
  for(i = 0;i < 8;i++)//循环八次 把自定义字符写入液晶显示器LCD1602自定义字符储存地址并写出来
 {
   LCD1602WriteCommand(0x40 + Position*8 + i);//0x40为液晶显示器LCD1602自定义字符储存地址最高位初始值 循环八次 把自定义字符写入液晶显示器LCD1602自定义字符储存地址
   LCD1602WriteData(*(String+i));//循环八次 把写入液晶显示器LCD1602自定义字符储存地址上的自定义字符写出来
  }
  LCD1602SetDisplayPosition(x,y);//液晶显示器LCD1602设置显示位置
  LCD1602WriteData(0x00 + Position);//液晶显示器LCD1602写自定义字符到CGRAM(即字符生成随机存储器)第一个位置到第八个位置显示出来
 }
 ****/
 void main()//主函数
{
  bit Ack;//声明一位应答变量
  uchar String[8];//声明字符串变量
  LCD1602Init();//液晶显示器初始化函数
  Ack = 24C02Address(0x50);//24C02地址函数 为啥是0x50? 由于24C02是以自身地址码0xa0与单片机通信 只有0x50传入24C02地址函数中的I2CWriteByte(Address << 1)运算后 才能让24C02是以自身地址码0xa0与单片机通信
  String[0] = '0';
  String[1] = 'x';
  String[2] = '5';
  String[3] = '0';
  String[4] = ':';
  String[5] = (uchar)Ack+'0';
  LCD1602ShowString(0,0,String);//液晶显示器LCD1602第一行第一个位置显示字符串
 }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1244460.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大数据-计算框架选型与对比

计算框架选型与对比 一、大数据平台二、计算框架分类1.批处理架构2.实时流处理架构3.流批一体处理架构 三、计算框架关键指标1.处理模式2.可伸缩性3.消息传递3.1 至少一次&#xff08;at least once&#xff09;3.2 至多一次&#xff08;ai most once&#xff09;3.3 恰好一次&…

交叉编译安装时报错 ./install.sh: 15: ./install.sh: Bad substitution

报错信息截图如下&#xff1a; 解决方法 vim install.sh #!/bin/sh -e 修改为 !/bin/bash -e重新执行 sudo ./install.sh 成功运行

Leetcode算法系列| 1. 两数之和(四种解法)

目录 1.题目2.题解解法一&#xff1a;暴力枚举解法二&#xff1a;哈希表解法解法三&#xff1a;双指针(有序状态)解法四&#xff1a;二分查找(有序状态) 1.题目 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数…

Endnote软件添加期刊引用格式

在下述网址中&#xff0c;找到你想要添加的期刊&#xff0c;下载引用格式文件&#xff08;后缀为.ens格式&#xff09; https://endnote.com/downloads/styles/?wpv_post_searchInformationfusion&wpv_aux_current_post_id12829&wpv_view_count12764-TCPID12829 下载…

C语言——从键盘输人一个表示年份的整数,判断该年份是否为闰年,并显示判断结果。

#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h> int main() {int year 0;printf("请输入年份&#xff1a;");scanf("%d",&year);if((year%4 0) && (year%100!0) || (year%400 0)){printf("%d是闰年\n",year);}else{p…

人工标签不准确的一种解决方案:PCA降维可视化筛选正样本

背景 在实际的业务场景里&#xff0c;用会话文本构建模型&#xff08;机器学习/深度学习&#xff09;来做意图分类之类的任务时&#xff0c;经常会出现人工打标不够准确的问题&#xff0c;标签都不准确的话模型当然无法学习到有效信息了。这个问题真的非常头疼…除了与业务沟通…

【CCF-PTA】第03届Scratch第03题 -- 参观食品厂

参观食品厂 【题目描述】 光明小学定期组织学生参与社会实践&#xff0c;最近的活动主题是参观自动化食品厂。小明看到生产线可以自动筛选罐头重量是否合格&#xff0c;感到十分好奇。回来后&#xff0c;小明准备写一个模拟程序&#xff0c;输入10盒罐头的重量&#xff0c;程…

openGauss学习笔记-131 openGauss 数据库运维-启停openGauss

文章目录 openGauss学习笔记-131 openGauss 数据库运维-启停openGauss131.1 启动openGauss131.2 停止openGauss131.3 示例131.3.1 启动openGauss131.3.2 停止openGauss 131.4 错误排查 openGauss学习笔记-131 openGauss 数据库运维-启停openGauss 131.1 启动openGauss 以操作系…

前端 vue 面试题(二)

文章目录 如何让vue页面重新渲染组件间通信vue为什么要mutation、 action操作插槽、具名插槽、作用域插槽vue编译使用的是什么库&#xff1f;vue怎么实现treeshakingwebpack实现treeshaking为什么只有es module 能支持 tree shaking mixin 的作用mixin的底层原理nexTick原理vue…

python -opencv 图像锐化

python -opencv 图像锐化 图像锐化其实&#xff0c;是一种增强图片对比度的技术&#xff0c;我们可以通过计算图像的导数&#xff0c;把导数绝对值数值大于零的数值加回原图像&#xff0c;通过这种方法&#xff0c;可以增强图像的对比度。 实现代码如下&#xff1a; import c…

Django之中间件与CSRF_TOKEN

文章目录 一、什么是中间件二、中间件有什么用三、Django自定义中间件中间件中主要方法及作用创建自定义中间件的步骤&#xff1a;process_request与process_response方法process_view方法process_exceptionprocess_template_response&#xff08;不常用&#xff09; 四、CSRF_…

Django DRF序列化器serializer

以下案例由浅到深&#xff0c;逐步深入&#xff0c;通过实例介绍了序列化器的使用方法&#xff0c;和遇到的常见问题的解决方法。 一、序列化器serializers.Serializer 1、urls.py urlpatterns [path("api/<str:version>/depart/",views.DepartView.as_vie…

找论文找论文

这里写目录标题 找到的&#xff0c;待筛选识别检测 OCR综述&#xff0c;经典论文综述OCR识别OCR检测端到端文本识别问题集怎么看一篇论文有没有代码怎么直接找比如某一年的CVPR关于OCR方面的最新论文拿到一篇论文&#xff0c;根据论文名字怎么检索到期刊和发表日期 功能技巧找顶…

geoserver发布tif矢量数据图层

cesium加载上传至geoserver的tif矢量数据_cesium加载tiff-CSDN博客 geoserver安装及跨域问题解决方案&#xff1a;geoserver安装及跨域问题解决方案_geoserver 跨域_1 1王的博客-CSDN博客 将TIF上传至geoserver 启动geoserver服务&#xff0c;并进入geoserver主页。 1. 新建…

内建组件和模块

讨论 Vue.js 中几个非常重要的内建组件和模块&#xff0c;例如 KeepAlive 组件、Teleport 组件、Transition 组件等&#xff0c;它们都需要渲染器级别的底层支持。另外&#xff0c;这些内建组件所带来的能力&#xff0c;对开发者而言非常重要且实用&#xff0c;理解它们的工作原…

windows版本的grafana如何离线安装插件

本文以安装clickhouse的插件为例&#xff0c;记录下如何离线安装插件 1 下载插件 ClickHouse plugin for Grafana | Grafana Labs 2 找到grafana的配置文件 打开编辑&#xff0c;搜索plugin关键字&#xff0c;修改plugin的加载目录 目录不存在&#xff0c;手动创建&#xff0…

TableStructureRec: 表格结构识别推理库来了

目录 引言lineless_table_rec: 无线表格识别库安装使用结果 wired_table_rec&#xff1a;有线表格识别库安装使用结果 写在最后 引言 TableStructureRec 仓库是用来对文档中表格做结构化识别的推理库&#xff0c;包括来自 PaddleOCR 的表格结构识别算法模型、来自阿里读光有线…

创建maven的web项目

&#xff08;一&#xff09;创建maven的web项目 Step1、创建一个普通的maven项目 &#xff08;1&#xff09;新建一个empty project&#xff0c;命名为SSM2。 点击项目名&#xff0c;右键new&#xff0c;选择Module&#xff0c;左侧选择“Maven archetype”&#xff0c;可以给…

gmapping仿真

文章目录 获取源码安装依赖项编译简单场景运行gmapping开启键盘控制通过launch文件来启动gmappingGmapping建图的参数设置地图的保存和加载参考 获取源码 cd ~/catkin_ws/src/ git clone https://gitcode.com/weixin_42990464/wpr_simulation.git git clone https://gitcode.c…

Action!录屏工具免费完整版,录屏软件,打开即可解锁最新完整可用版本,支持GPU加速HDR视频录制和播放

一、软件简介 本次带来的录屏工具已升级为【完整版本】&#xff0c;所有功能全部可用。该录屏工具支持GPU硬件加速&#xff0c;可以智能识别主流硬件设备&#xff0c;支持通过GPU进行HDR视频录制和播放进行。视频录制帧率最高支持360FPS&#xff0c;直播视频帧率最高支持60FPS…