基于STC12C5A60S2系列1T 8051单片机的数码管显示IIC总线器件AT24C02记录单片机上电次数应用

news2024/11/22 15:53:21

基于STC12C5A60S2系列1T 8051单片机的数码管显示IIC总线器件AT24C02记录单片机上电次数应用

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

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

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

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

在这里插入图片描述

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

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

液晶显示器LCD1602简单介绍

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

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

IIC通信简单介绍

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

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

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

通过数码管显示掉电保存数据芯片AT24C02内存地址上记录单片机上电次数

main.c

#include "STC12C5A60S2.h"  
#include "AT24C02.h" 
#include "AT24C02OfI2C.h"
#include "Timer0.h"
//#include "Key.h"
#include "Digitron.h"
#define uchar unsigned char//自定义无符号字符型为uchar
#define uint unsigned int//自定义无符号整数型为uint
sbit LED = P1^5;//位定义LED灯为单片机P1.2脚
//uchar StringCach[3];//定义字符串缓存数组变量
//uchar PowerOnCountFlag = 0;//定义开机计数标志位变量为0 
uint PowerOnCount = 0;//定义开机计数变量
 void main()//主函数
{
   
//	PowerOnCount = PowerOnCountArray[0];// 
	Timer0Init();//定时器0的16位定时模式1用12分频定时2ms初始化函数 晶振为12MHz
	DigitronBootDisplay();//数码管开机显示函数
  /****
  //uchar Data;//声明数据变量
  uint BootTime;//声明开机次数变量
  uchar String[10];//声明字符串数组变量
  uchar StringCach[3];//声明字符串缓存数组变量 StringCache[0]存放开始计数标志位变量 StringCache[1]存放第一个计数变量 StringCache[2]存放第二个计数变量
  //Timer0Init();//定时器0的16位定时模式1用12分频定时2ms初始化函数 晶振为12MHz
  LCD1602Init();//液晶显示器初始化函数
  ****/
  /****
  Data = ReadByteFrom24C02(0x50,0x20);//单片机作为主机通过I2C通信从24C02内存地址0x20上读取一个字节 
  LCD1602SetDisplayPosition(0,0);//液晶显示器LCD1602第一行第一个位置显示字符串
  LCD1602WriteData(Data/100 + '0');//液晶显示器LCD1602写数据函数 显示百位数据 为什么数据分解后+'0'? 因为液晶显示器LCD1602要显示数据型字符串 而单片机运算字符串的字符是字符对应的ASCII码 如:字符'0'的ASCII码十进制数是48 字符'1'的ASCII码十进制数是49 字符'2'的ASCII码十进制数是50 .... 字符'9'的ASCII码十进制数是57 而编译器对于'0'会自动视为是'0'的ASCII码 即ASCII码十进制数48 举例:拿Data = 251来分解 则有:Data/100=2 Data/10%10=5 data%10=1 要把数据型251转化成字符串为"251" 可拆开看成'2' '5' '1' 它们对应的ASCII码十进制数分别为50 53 49 而Data/100=2+'0'=2+48=50 Data/10%10=5+'0'=5+48=53 data%10=1+'0'=1+48=49 算出50 53 49这三个ASCII码十进制数分别对上字符'2' '5' '1'的ASCII码十进制数为50 53 49 这就是为什么数据分解后+'0'的原因
  LCD1602WriteData(Data/10%10 + '0');//液晶显示器LCD1602写数据函数 显示十位数据
  LCD1602WriteData(Data%10 + '0');//液晶显示器LCD1602写数据函数 显示个位数据
  NumberTransformedToHexString(Data,String);//无符号字符型数据转化为十六进制数的字符串函数 无符号字符型数据要转化为十六进制数的字符串 可以把无符号字符型数据拆成高四位与低四位来分别转化成表示十六进制数的字符串两位数字符
  LCD1602ShowString(5,0,String);//液晶显示器LCD1602第一行第六个位置显示字符串
  Data++;//数据变量自加
  WriteByteTo24C02(0x50,0x20,Data);//写字节给24C02函数 单片机作为主机通过I2C通信在24C02内存地址0x20上写一个字节 
  LCD1602SetDisplayPosition(0,1);//液晶显示器LCD1602第二行第一个位置显示字符串
  LCD1602WriteData(Data/100 + '0');//液晶显示器LCD1602写数据函数 显示百位数据 为什么数据分解后+'0'? 解释同上
  LCD1602WriteData(Data/10%10 + '0');//液晶显示器LCD1602写数据函数 显示十位数据
  LCD1602WriteData(Data%10 + '0');//液晶显示器LCD1602写数据函数 显示个位数据
  NumberTransformedToHexString(Data,String);//无符号字符型数据转化为十六进制数的字符串函数 无符号字符型数据要转化为十六进制数的字符串 可以把无符号字符型数据拆成高四位与低四位来分别转化成表示十六进制数的字符串两位数字符
  LCD1602ShowString(5,1,String);//液晶显示器LCD1602第二行第六个位置显示字符串
  ****/
  /****
  ReadMultiByteFrom24C02(0x50,0x00,StringCach,10);//单片机作为主机通过I2C通信从24C02内存地址0x00上连续读取十个字节 
  StringCacheTransformedToHexString(StringCach,10,String);//字符串缓存数组中的无符号字符型数据转化为十六进制数的字符串函数
  LCD1602ShowString(1,0,String);//液晶显示器LCD1602第一行第二个位置显示字符串
  for(i = 0;i < sizeof(StringCach);i++)
 {
   StringCache[i] = StringCache[i] + 1;//字符串缓存数组中的数据变量自加
  }
  //WriteMultiByteTo24C02(0x50,0x00,StringCach,10);//单片机作为主机通过I2C通信从24C02内存地址0x00上连续写入10个字节
  PageWriteByteTo24C02(0x50,0x00,StringCach,10);//单片机作为主机通过I2C通信从24C02内存地址0x00上按八个字节为一页连续写入十个字节
  ****/
  /****
  ReadMultiByteFrom24C02(24C02Address,24C02RecordeAddress,StringCach,3)//单片机作为主机通过I2C通信从24C02内存地址0x00上读取三个字节
  if(StringCach[0] != BootCountFlag)//判断是否开过机
 {
   StringCach[0] = BootCountFlag;//没开过机就把开机计数标志位变量包含的数据赋给字符串缓存数组中第一个数据变量
   StringCach[1] = 1;//字符串缓存数组中第二个数据变量缓存第一次开机计数
   StringCach[2] = 0;//字符串缓存数组中第二个数据变量清0
  }
  else//开过机
 {
   StringCach[1]++;//字符串缓存数组中第二个数据变量缓存开机计数
   if(StringCach[1] >= BootMultipleCount)//判断字符串缓存数组中第二个数据变量缓存开机计数变量是否大于开机倍数计数变量
  {
    StringCach[1] = 0;//字符串缓存数组中第二个数据变量清0
    StringCach[2]++;//字符串缓存数组中第三个数据变量在字符串缓存数组中第二个数据变量缓存开机计数超过开机倍数计数变量后进行递进缓存开机计数
    if(StringCach[2] >= BootMultipleCount)//判断字符串缓存数组中第三个数据变量是否大于开机倍数计数变量
   {
     StringCach[1] = 0;//字符串缓存数组中第二个数据变量清0
     StringCach[2] = 0;//字符串缓存数组中第三个数据变量清0
    }
   }
  }
  WriteMultiByteTo24C02(24C02Address,24C02RecordeAddress,StringCache,3)//单片机作为主机通过I2C通信从24C02内存地址0x00上写入三个字节
  BootTime = StringCach[2] * BootMultipleCount + StringCach[1];//开机计数运算公式
  IntegerTransformedToHexString(BootTime,String);//整数转化为十六进制数的字符串函数
  LCD1602ShowString(0,0,String);//液晶显示器LCD1602第一行第一个位置显示字符串 
  while(1);//主循环
  ****/
  /****
  while(1)//主循环
 {
   if(TimerCountFlag == 1)//判断2ms定时计数标志位变量是否置1
  {
    LCD1602WriteCommand(LCD1602DisplayLeftMove);//液晶显示器LCD1602写命令函数 每2ms向左移屏
    TimerCountFlag = 0;//定时计数标志位变量清0
   }
  }
  ****/
   RestoreAT24C02Data(AT24C02Address,AT24C02RecordeAddress);//恢复AT24C02数据函数 相当于读取AT24C02数据
//  ReadByteFromAT24C02(AT24C02Address,AT24C02RecordeAddress);//读AT24C02字节函数
	PowerOnCount++;//开机计数变量自加
   while(1)//主循环
 {
   
//   if(BackupFlag == 1)//判断备份标志位变量是否等于1
//  {
   
//    BackupFlag = 0;//备份标志位变量清0
//		PowerOnCount++;
//    if(CumulativeTime > 10)//这里作为提示试验 先让累积时间变量取10秒 看情况来设置数值
//   {
   
//     CumulativeTime = 10;//保存累积时间
//     LedTimeCount = 5000;//定义LED时间计数变量
//    }
//    else
//   {
   
//     BackupAT24C02Data(AT24C02Address,AT24C02RecordeAddress);//备份AT24C02函数 相当于写入数据给AT24C02
//     LedTimeCount = 0;//LED时间计数变量清0
//    }
//   }
//   if(LedTimeCount != 0)//判断LED时间计数变量是否不等于0
//  {
   
//    LedTimeCount--;//LED时间计数变量自减
//    LED = ~ LED;//LED取反
//   }
	 BackupAT24C02Data(AT24C02Address,AT24C02RecordeAddress);//备份AT24C02函数 相当于写入数据给AT24C02
//	 WriteMultiByteToAT24C02(AT24C02Address,AT24C02RecordeAddress,StringCach,3);//写多个字节给AT24C02函数
//   WriteByteToAT24C02(AT24C02Address,AT24C02RecordeAddress,PowerOnCount);//写字节给AT24C02函数 
//}	
  }	 
//   DigitronDisplayDataSplit();//数码管显示数据分解函数
//  }
 } 

AT24C02.c

#include "AT24C02.h" 
#include "Timer0.h"
#include "AT24C02OfI2C.h" 
#include "Digitron.h"
#define uchar unsigned char//自定义无符号字符型为uchar
#define uint unsigned int//自定义无符号整数型为uint
uchar StringCach[3];//定义字符串缓存数组变量
extern uint PowerOnCount;//引用外部开机计数变量 
// uchar ReadByteFromAT24C02(uchar IcAddress,uchar Address)//读AT24C02字节函数
//{
   
//  uchar Data;//声明数据变量
//  I2CStar();//I2C启动函数
//  I2CWriteByte(IcAddress << 1);//I2C写字节函数 单片机通过I2C通信写匹配通信地址给AT24C02
//  I2CWriteByte(Address);//I2C写字节函数 单片机通过I2C通信写AT24C02的地址
//  I2CStar();//I2C启动函数
//  I2CWriteByte((IcAddress << 1) | 0x01);//I2C写字节函数 单片机通过I2C通信写入读AT24C02
//  Data = I2CReadByte();//I2C读字节函数含有的数据赋给数据变量
//  SendAck(1);//I2C发送应答函数 单片机作为主机通过I2C通信只读AT24C02内存地址上的一个字节 
//  I2CStop();//I2C停止函数
//  return Data;//返回数据变量含有的数据
// }

  void ReadMultiByteFromAT24C02(uchar IcAddress,uchar Address,uchar *StringCach,uchar StringLength)//读AT24C02多字节函数
{
   
  
  //I2CStar();//I2C启动函数
  //I2CWriteByte(IcAddress << 1);//I2C写字节函数 单片机通过I2C通信写匹配通信地址给AT24C02
   do 
  {
   
    I2CStar();//I2C启动函数
    if(!(I2CWriteByte(IcAddress << 1)))//I2C写字节函数 单片机通过I2C通信写匹配通信地址给AT24C02
   {
   
     break;
    }
    I2CStop();//I2C停止函数
   }while(1);
  I2CWriteByte(Address);//I2C写字节函数 单片机通过I2C通信写AT24C02的地址
  I2CStar();//I2C启动函数
  I2CWriteByte((IcAddress << 1

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

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

相关文章

Vmware虚拟机远程SSH连接失效解决方法及分析过程

问题描述 系统为CentOS7 64位 一向能够正常连接 在某次使用FinalShell进行远程SSH连接时 突然无法连接 对问题原因猜测及尝试 1.dns解析失效 发现显示DNS无法解析,可以得知是使用了主机名登录,而主机名无法登录. 遂查看host文件.host文件因不知名原因被清空,重新恢复后该问…

每天五分钟计算机视觉:如何基于滑动窗口技术完成目标的检测?

汽车检测算法 现在我们想要构建一个汽车检测算法,我们希望输入到算法中一张图片,算法就可以帮助我们检测出这张图片中是否有汽车。 数据集 首先创建一个标签训练集,x是样本,y是标签。我们的训练集最好是被剪切过的图片,剪掉汽车以外的部分,使汽车居于中间位置,就是整张…

学习transformer模型-broadcast广播的简明介绍

broadcast的定义和目的&#xff1a; 广播发生在将较小的张量“拉伸”以具有与较大张量兼容的形状&#xff0c;以便执行操作时。 广播是一种有效执行张量操作而不创建重复数据的方式。 广播的处理过程&#xff1a; 1&#xff0c; 确定最右边的维度是否兼容 每…

视觉信息处理与FPGA实现第八次作业——verilog实现对比度调节

一、查看灰度图的数据格式 1.1 安装HxD HxD下载链接&#xff1a;https://download.csdn.net/download/weixin_44357071/89045331 解压直接打开exe就能使用。 将需要查看二进制数据的图片拖到软件框里就能读取 1.2 找到bmp图像的图片点阵数据起始地址&#xff0c;原理和例子…

【数据结构】非线性结构---二叉树

1、树 1.1 树的相关概念 节点的度&#xff1a;一个节点含有的子树的个数称为该节点的度&#xff1b; 如上图&#xff1a;A的为6 叶节点或终端节点&#xff1a;度为0的节点称为叶节点&#xff1b; 如上图&#xff1a;B、C、H、I...等节点为叶节点 非终端节点或分支节点&#…

中断服务程序模板

通常定时器初始化过程如下: ①对 TMOD赋值,以确定TO和T1的工作方式。 ②计算初值,并将初值写入THO、TLO或TH1、TL1。 ③中断方式时&#xff0c;则对IE赋值&#xff0c;开放中断。 ④使TRO或TR1置位&#xff0c;启动定时器/计数器定时或计数。 代码 利用定时器0工作方式1&…

数据结构(六)——图的应用

6.4 图的应用 6.4.1 最小生成树 对于⼀个带权连通⽆向图G (V, E)&#xff0c;⽣成树不同&#xff0c;每棵树的权&#xff08;即树中所有边上的权值之和&#xff09;也可能不同。设R为G的所有⽣成树的集合&#xff0c;若T为R中边的权值之和最小的生成树&#xff0c;则T称为G的…

算法打卡day23

今日任务&#xff1a; 1&#xff09;39. 组合总和 2&#xff09;40.组合总和II 3&#xff09;131.分割回文串 39. 组合总和 题目链接&#xff1a;39. 组合总和 - 力扣&#xff08;LeetCode&#xff09; 给定一个无重复元素的数组 candidates 和一个目标数 target &#xff0c;…

人工智能之深度学习笔记——每天五分钟快速掌握深度学习理论

本专栏会对深度学习以及深度学习搭建技巧做一个详尽的介绍&#xff0c;相信大家阅读完本专栏之后&#xff0c;深度学习已经不是一个遥不可及的名词&#xff0c;我们会知道它究竟是什么&#xff0c;本专栏尽可能地简单详细地介绍每一个深度学习知识&#xff0c;帮助每天只用很少…

Day78:服务攻防-数据库安全RedisCouchDBH2database未授权访问CVE漏洞

目录 前置知识 数据库应用-Redis-未授权访问&CVE漏洞 未授权访问&#xff1a;CNVD-2015-07557 未授权访问-CNVD-2019-21763 未授权访问-沙箱绕过RCE-CVE-2022-0543 数据库应用-Couchdb-未授权越权&CVE漏洞 Couchdb 垂直权限绕过&#xff08;CVE-2017-12635&…

数据结构-链表的基本操作

前言&#xff1a; 在dotcpp上碰到了一道题&#xff0c;链接放这了&#xff0c;这道题就是让你自己构建一遍链表的创建&#xff0c;插入节点&#xff0c;删除节点&#xff0c;获取节点&#xff0c;输出链表&#xff0c;题目给了几张代码图&#xff0c;不过不用管那些图&#xf…

k8s 经常操作指令

发现有个技巧&#xff1a;get、describe、edit ...操作指令后&#xff0c;都对应的相应的资源类型/资源 编辑deployment&#xff0c;查看其中部署的容器 kubectl edit deploy -n namespace pod名前缀&#xff08;不带hash&#xff09; 注&#xff1a; 带hash的具体pod&…

如何让光猫4个网口都有网络

一般情况光猫只有LAN1口有网络&#xff0c;LAN2、LAN3和LAN4口都是预留给电视用的&#xff0c;那么如何让这3个网口也有网络呢&#xff1f; 使用场景&#xff1a; 光猫在弱电箱内&#xff0c;弱电箱中有三根网线&#xff08;网线1、网线2和网线3&#xff09;分别接入到了三个房…

IP地址与子网掩码

1 IP地址 1.1 IPv4与IPv6 1.2 IPv4地址详解 IPv4地址分4段&#xff0c;每段8位&#xff0c;共32位二进制数组成。 1.2.1 地址分类 这32位又被分为网络号和主机号两部分&#xff0c;根据网络号占用位数的不同&#xff0c;又可分为以下几类&#xff1a; A类地址&#xff1a;…

蓝桥杯(更新中)

递归与递推 递归 1.指数型枚举 解析&#xff1a;从 1 ∼ n 这 n 个整数中随机选取任意多个&#xff0c;输出所有可能的选择方案。 思路&#xff1a;枚举每一位对应的数字选与不选&#xff0c;例如&#xff1a;第一位对应的数字为1&#xff0c;有一种方案是选1&#xff0c;另…

解决报错——使用sqlite的扩展Spatialite

正文 笔者想使用sqlite3的扩展Spatiate 代码如下。 import sqlite3 conn sqlite3.connect(database.db) conn.enable_load_extension(True) conn.load_extension("mod_spatialite") 结果如下。 找不到指定模块。 笔者在网上到处搜索&#xff0c;终于解决了。&a…

电磁兼容(EMC):静电放电(ESD)抗扰度试验深度解读(一)

目录 1 .导言 2.适用产品范围 3.标准目的 4.试验等级 4.1 空气放电的最高电压为何定在15kV 1 .导言 电磁兼容设计的知识储备之一便是EMC相关标准&#xff0c;标准中的测试系统标准更是基础中的基础&#xff0c;深度理解&#xff0c;对产品的EMC设计有很好的帮助。以下对最…

算法题->盛最多水的容器C语言和JAVA双指针解法

盛最多水的容器C语言和JAVA双指针解法 题目描述: 力扣链接:https://leetcode.cn/problems/container-with-most-water/description/ 题意: 根据数组中的值(高)和下标差值(宽),求能容纳最多的体积V. 例子: 输出49的求解过程,根据木桶效应,存储水的高度由短木板决定,故 V 短…

EfficientVMamba实战:使用EfficientVMamba实现图像分类任务(一)

文章目录 摘要安装包安装timm 数据增强Cutout和MixupEMA项目结构编译安装Vim环境环境安装过程安装库文件 计算mean和std生成数据集 摘要 论文&#xff1a;https://arxiv.org/pdf/2401.09417v1.pdf 作者研究了轻量级模型设计的新方法&#xff0c;通过引入视觉状态空间模型&…

Linux中JMeter的使用

Linux中JMeter的使用 Linux版本JMeter安装 # 1、下载、安装JMeter 如果有安装包直接上传即可 wget -c https://archive.apache.org/dist/jmeter/binaries/apache-jmeter-5.4.1.tgz # 解压 tar -zxvf apache-jmeter-5.4.1.tgz -C /usr/local/sjdwz_test cd /usr/local/sjdwz_t…