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

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

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

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

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

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

IIC通信简单介绍

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

通过液晶显示器LCD1602显示掉电保存数据芯片24C02内存地址上的数据

javascript 复制代码
#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端口
 uchar Read24C02Byte(uchar IcAddress,uchar Address)//读24C02字节函数
{
  uchar Data;//声明数据变量
  I2CStar();//I2C启动函数
  I2CWriteByte(IcAddress << 1);//I2C写字节函数 单片机通过I2C通信写匹配通信地址给24C02
  I2CWriteByte(Address);//I2C写字节函数 单片机通过I2C通信写24C02的地址
  I2CStar();//I2C启动函数
  I2CWriteByte((IcAddress << 1) | 0x01);//I2C写字节函数 单片机通过I2C通信写入读24C02
  Data = I2CReadByte();//I2C读字节函数含有的数据赋给数据变量
  SendAck(1);//I2C发送应答函数 单片机作为主机通过I2C通信只读24C02内存地址上的一个字节 
  I2CStop();//I2C停止函数
  return Data;//返回数据变量含有的数据
 }
/****
 bit 24C02Address(uchar Address)//24C02地址函数
{
  bit Ack;//声明一位应答变量
  I2CStar();//I2C启动函数
  I2CWriteByte(Address << 1);//I2C写字节函数
  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()//主函数
{
  uchar Data;//声明数据变量
  LCD1602Init();//液晶显示器初始化函数
  Data = Read24C02Byte(0x50,0x00);//单片机作为主机通过I2C通信从24C02内存地址0x00上读取一个字节 
  LCD1602SetDisplayPosition(0,0);//液晶显示器LCD1602第一行第一个位置显示字符串
  LCD1602WriteData(Data/100 + '0');//液晶显示器LCD1602写数据函数 显示百位数据
  LCD1602WriteData(Data/10%10 + '0');//液晶显示器LCD1602写数据函数 显示十位数据
  LCD1602WriteData(Data%10 + '0');//液晶显示器LCD1602写数据函数 显示个位数据
  while(1);//主循环
 }
相关推荐
Willliam_william3 分钟前
Python学习之路(5)— 使用C扩展
c语言·python·学习
TANGLONG2222 小时前
【初阶数据结构与算法】八大排序之非递归系列( 快排(使用栈或队列实现)、归并排序)
java·c语言·数据结构·c++·算法·蓝桥杯·排序算法
第二层皮-合肥2 小时前
硬件设计-时钟振荡器
嵌入式硬件
sunny-ll3 小时前
【C++】explicit关键字详解(explicit关键字是什么? 为什么需要explicit关键字? 如何使用explicit 关键字)
c语言·开发语言·c++·算法·面试
半盏茶香5 小时前
C语言勘破之路-最终篇 —— 预处理(下)
c语言·开发语言·c++·算法
TDengine (老段)7 小时前
TDengine 新功能 VARBINARY 数据类型
大数据·c语言·数据库·时序数据库·tdengine·涛思数据
零壹&硬件8 小时前
D类音频应用EMI管理
单片机·嵌入式硬件·硬件架构·音视频·硬件工程·智能硬件
7yewh11 小时前
嵌入式硬件杂谈(七)IGBT MOS管 三极管应用场景与区别
驱动开发·嵌入式硬件·mcu·物联网·硬件架构·硬件工程·pcb工艺
raysync88811 小时前
半导体企业内外网数据摆渡技术实现方案
单片机·嵌入式硬件
m0_7482359513 小时前
LWIP(stm32+lwip+freertos)
stm32·单片机·嵌入式硬件