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

【51单片机】AT24C02(江科大、爱上半导体)

一、AT24C02

1.AT24C02介绍

·AT24C02是一种可以实现掉电不丢失的存储器,可用于保存单片机运行时想要永久保存的数据信息
· 存储介质:E2PROM
· 通讯接口:12C总线
· 容量:256字节
在这里插入图片描述

2.引脚即应用电路

在这里插入图片描述
本开发板AT24C02原理图
在这里插入图片描述
12C地址全接地,即全为0

WE接地,没有写使能

SCL接P21 SDA接P20

没有外接上拉电阻是因为单片机的每个10口都接了上拉电阻

AT24C02内部结构框图如图所示
在这里插入图片描述
简单来说,就是通过SCL和SDA接口获得数据,经过一定的逻辑,数据存储到EEPROM(通过X和Y来控制数据的存储位置),并且可以通过一定的逻辑,将数据输出出来

3.I2C总线

1.I2C总线介绍
· 12C总线(Inter IC BUS)是由Philips公司开发的一种通用数据总线
· 两根通信线:SCL(Serial Clock)、SDA (Serial Data)
· 同步、半双工,带数据应答
· 通用的I2C总线,可以使各种设备的通信标准统一,对于厂家来说,使用成熟的方案可以缩短芯片设计周期、提高稳定性,对于应用者来说,使用通用的通信协议可以避免学习各种各样的自定义协议,降低了学习和应用的难度

2.I2C电路规范
·所有I2C设备的SCL连在一起,SDA连在一起
· 设备的SCL和SDA均要配置成开漏输出模式
· SCL和SDA各添加一个上拉电阻,阻值一般为4.7KΩ左右
· 开漏输出和上拉电阻的共同作用实现了“线与”的功能,此设计主要是为了解决多机通信互相干扰的问题
在这里插入图片描述
本单片机所有IO口都是弱上拉模式,如图
在这里插入图片描述开关闭合,则输出0
开关打开,则输出1
高电平驱动能力弱,低电平驱动能力强

开漏模式如图,没有接上拉电阻
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/6a0188c70e664bb5845f48b23fac6e4d.png#pic_center
开关闭合,输出0
开关断开,引脚呈浮空状态(什么都没接),电平不稳定

3.I2C时序结构
一帧标准的写数据帧
在这里插入图片描述
一帧写数据是由时钟线和数据线共同作用的,在同一时间,要么在发送信息,要么在读取信息
在这里插入图片描述
当处于空闲状态时,数据线和时钟线都处于高电平状态
在这里插入图片描述
当开始传递信息时,比如传递第一位起始位。此时必须要在时钟信号为高电平期间,数据信号完成由高到低的跳变,也就是下降沿
在这里插入图片描述

在这里插入图片描述
接下来是7位设备地址码,因为每一个从设备的地址码都是唯一的,为了区别要和哪一个从设备通讯,需要先发送出7位地址码,7位不同的0和1的排列组合,一共表可以表示128种结果
当时钟线为高电平时,数据线上的数据必须保持稳定(时钟线为高时,数据线上的数据始终为高),这样就完成了逻辑1的传输。如果数据线上始终是低电平,则表示逻辑0
在这里插入图片描述

若发送1010000,且24c02的地址为1010000,此时就是单片机和24c02通讯
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

接下来是读写数据位,如果要写数据帧,就给它置0,读数据帧置1
在这里插入图片描述

再下面一位是应答信号,这个信号是由从机发送给主机的,如果从机收到了之前的信息,它会回复0,没有收到或者(主机)读取接收完成回复1
在这里插入图片描述
在这里插入图片描述

下面的8位是设备寄存器的地址,因为是给24C02通讯的,24C02是一个存储器,它可以存储256个字节,而发送的8位寄存器地址正好可以访问这256个字节
在这里插入图片描述
比如写的寄存器地址是0x01(二进制为0000 0001),它就会往0x01里写入数据
在这里插入图片描述
然后单片机需要存储器返回一个应答信号

接下来的8位是给这个存储器的寄存器要写入的数据
比如发送0000 1111,则这8个位就会存储这8位信息
在这里插入图片描述

即使后来断电依旧保存,发送写数据之后,需要再给主机发送应答信号0,告诉主机写入成功

最后再写入停止位,它和起始位相反,是当时钟信号为高时,数据信号需要由低到高的跳变
在这里插入图片描述
这样一个标准的写数据帧就完成了
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

以下是一个标准的读数据帧
在这里插入图片描述
首先写入设备地址,然后是写数据。接下来写的是寄存器的地址,在收到从机的应答信号之后,主机需要再发送一个起始信号。然后需要再发送一遍设备的地址,然后才能发送读数据。接下来存储器就会把寄存器里面的数据发送给单片机,这样就完成了一帧数据的读取

二、AT24C02数据存储

I2C.c

#include <REGX52.H>sbit I2C_SCL=P2^1;
sbit I2C_SDA=P2^0;/*** @brief  I2C开始* @param  无* @retval 无*/
void I2C_Start(void)
{I2C_SDA=1;I2C_SCL=1;I2C_SDA=0;I2C_SCL=0;
}/*** @brief  I2C停止* @param  无* @retval 无*/
void I2C_Stop(void)
{I2C_SDA=0;I2C_SCL=1;I2C_SDA=1;
}/*** @brief  I2C发送一个字节* @param  Byte 要发送的字节* @retval 无*/
void I2C_SendByte(unsigned char Byte)
{unsigned char i;for(i=0;i<8;i++){I2C_SDA=Byte&(0x80>>i);I2C_SCL=1;I2C_SCL=0;}
}/*** @brief  I2C接收一个字节* @param  无* @retval 接收到的一个字节数据*/
unsigned char I2C_ReceiveByte(void)
{unsigned char i,Byte=0x00;I2C_SDA=1;for(i=0;i<8;i++){I2C_SCL=1;if(I2C_SDA){Byte|=(0x80>>i);}I2C_SCL=0;}return Byte;
}/*** @brief  I2C发送应答* @param  AckBit 应答位,0为应答,1为非应答* @retval 无*/
void I2C_SendAck(unsigned char AckBit)
{I2C_SDA=AckBit;I2C_SCL=1;I2C_SCL=0;
}/*** @brief  I2C接收应答位* @param  无* @retval 接收到的应答位,0为应答,1为非应答*/
unsigned char I2C_ReceiveAck(void)
{unsigned char AckBit;I2C_SDA=1;I2C_SCL=1;AckBit=I2C_SDA;I2C_SCL=0;return AckBit;
}

I2C.h

#ifndef __I2C_H__
#define __I2C_H__void I2C_Start(void);
void I2C_Stop(void);
void I2C_SendByte(unsigned char Byte);
unsigned char I2C_ReceiveByte(void);
void I2C_SendAck(unsigned char AckBit);
unsigned char I2C_ReceiveAck(void);#endif

AT24C02.c

#include <REGX52.H>
#include "I2C.h"#define AT24C02_ADDRESS		0xA0/*** @brief  AT24C02写入一个字节* @param  WordAddress 要写入字节的地址* @param  Data 要写入的数据* @retval 无*/
void AT24C02_WriteByte(unsigned char WordAddress,Data)
{I2C_Start();I2C_SendByte(AT24C02_ADDRESS);I2C_ReceiveAck();I2C_SendByte(WordAddress);I2C_ReceiveAck();I2C_SendByte(Data);I2C_ReceiveAck();I2C_Stop();
}/*** @brief  AT24C02读取一个字节* @param  WordAddress 要读出字节的地址* @retval 读出的数据*/
unsigned char AT24C02_ReadByte(unsigned char WordAddress)
{unsigned char Data;I2C_Start();I2C_SendByte(AT24C02_ADDRESS);I2C_ReceiveAck();I2C_SendByte(WordAddress);I2C_ReceiveAck();I2C_Start();I2C_SendByte(AT24C02_ADDRESS|0x01);I2C_ReceiveAck();Data=I2C_ReceiveByte();I2C_SendAck(1);I2C_Stop();return Data;
}

AT24C02.h

#ifndef __AT24C02_H__
#define __AT24C02_H__void AT24C02_WriteByte(unsigned char WordAddress,Data);
unsigned char AT24C02_ReadByte(unsigned char WordAddress);#endif

main.c

#include <REGX52.H>
#include "LCD1602.h"
#include "Key.h"
#include "AT24C02.h"
#include "Delay.h"unsigned char KeyNum;
unsigned int Num;void main()
{LCD_Init();LCD_ShowNum(1,1,Num,5);while(1){KeyNum=Key();if(KeyNum==1)	//K1按键,Num自增{Num++;LCD_ShowNum(1,1,Num,5);}if(KeyNum==2)	//K2按键,Num自减{Num--;LCD_ShowNum(1,1,Num,5);}if(KeyNum==3)	//K3按键,向AT24C02写入数据{AT24C02_WriteByte(0,Num%256);Delay(5);AT24C02_WriteByte(1,Num/256);Delay(5);LCD_ShowString(2,1,"Write OK");Delay(1000);LCD_ShowString(2,1,"        ");}if(KeyNum==4)	//K4按键,从AT24C02读取数据{Num=AT24C02_ReadByte(0);Num|=AT24C02_ReadByte(1)<<8;LCD_ShowNum(1,1,Num,5);LCD_ShowString(2,1,"Read OK ");Delay(1000);LCD_ShowString(2,1,"        ");}}
}

三、定时器扫描按键数码管

相关文章:

  • gem5学习(20):替换策略——Replacement Policies
  • C++11---(1)
  • 函数式编程要点
  • N-144基于微信小程序在线订餐系统
  • 嵌入式培训机构四个月实训课程笔记(完整版)-Linux ARM驱动编程第五天-ARM Linux编程之file_operations详解 (物联技术666)
  • C#既然数组长度不可改变,那么如何动态调整集合类型数组大小,以便添加或删除元素?
  • KingSCADA实现按钮点击效果
  • HCIA-HarmonyOS设备开发认证V2.0-轻量系统内核内存管理-动态内存
  • 在PyTorch中,如何查看深度学习模型的每一层结构?
  • [高并发] - 1.高并发综述
  • 代码随想录算法训练营第三十四天|860.柠檬水找零 406.根据身高重建队列 452. 用最少数量的箭引爆气球
  • 有了NULL,为什么C++还需要nullptr?
  • Educational Codeforces Round 135 (Rated for Div. 2)C. Digital Logarithm(思维)
  • 书生浦语-模型微调
  • 用HTML和CSS打造跨年烟花秀视觉盛宴
  • JavaScript 如何正确处理 Unicode 编码问题!
  • [译] 怎样写一个基础的编译器
  • 【许晓笛】 EOS 智能合约案例解析(3)
  • C++回声服务器_9-epoll边缘触发模式版本服务器
  • HTML5新特性总结
  • Idea+maven+scala构建包并在spark on yarn 运行
  • JavaScript创建对象的四种方式
  • JavaScript函数式编程(一)
  • Js基础知识(四) - js运行原理与机制
  • js算法-归并排序(merge_sort)
  • Linux编程学习笔记 | Linux IO学习[1] - 文件IO
  • mongo索引构建
  • Python3爬取英雄联盟英雄皮肤大图
  • SAP云平台运行环境Cloud Foundry和Neo的区别
  • TypeScript实现数据结构(一)栈,队列,链表
  • Vultr 教程目录
  • WePY 在小程序性能调优上做出的探究
  • windows下如何用phpstorm同步测试服务器
  • 阿里云爬虫风险管理产品商业化,为云端流量保驾护航
  • 初识 beanstalkd
  • 得到一个数组中任意X个元素的所有组合 即C(n,m)
  • 工作中总结前端开发流程--vue项目
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • 技术攻略】php设计模式(一):简介及创建型模式
  • 详解移动APP与web APP的区别
  • 小李飞刀:SQL题目刷起来!
  • 一些关于Rust在2019年的思考
  • ​DB-Engines 12月数据库排名: PostgreSQL有望获得「2020年度数据库」荣誉?
  • ​flutter 代码混淆
  • ​RecSys 2022 | 面向人岗匹配的双向选择偏好建模
  • ​无人机石油管道巡检方案新亮点:灵活准确又高效
  • #pragma multi_compile #pragma shader_feature
  • (007)XHTML文档之标题——h1~h6
  • (c语言)strcpy函数用法
  • (JSP)EL——优化登录界面,获取对象,获取数据
  • (pytorch进阶之路)扩散概率模型
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (八)Flask之app.route装饰器函数的参数
  • (附源码)ssm基于微信小程序的疫苗管理系统 毕业设计 092354
  • (免费领源码)Java#ssm#MySQL 创意商城03663-计算机毕业设计项目选题推荐