济南市建设网官网,宁波seo推广定制,建设银行环县支行网站,在线做头像一、AT24C02
1.AT24C02介绍
AT24C02是一种可以实现掉电不丢失的存储器,可用于保存单片机运行时想要永久保存的数据信息 存储介质:E2PROM 通讯接口:12C总线 容量:256字节
2.引脚即应用电路 本开发板AT24C02原理图 12C地址全接地,即全为0
WE接地,没有写使能
SCL接P21 S…一、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 高电平驱动能力弱,低电平驱动能力强
开漏模式如图,没有接上拉电阻 开关闭合,输出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.Hsbit I2C_SCLP2^1;
sbit I2C_SDAP2^0;/*** brief I2C开始* param 无* retval 无*/
void I2C_Start(void)
{I2C_SDA1;I2C_SCL1;I2C_SDA0;I2C_SCL0;
}/*** brief I2C停止* param 无* retval 无*/
void I2C_Stop(void)
{I2C_SDA0;I2C_SCL1;I2C_SDA1;
}/*** brief I2C发送一个字节* param Byte 要发送的字节* retval 无*/
void I2C_SendByte(unsigned char Byte)
{unsigned char i;for(i0;i8;i){I2C_SDAByte(0x80i);I2C_SCL1;I2C_SCL0;}
}/*** brief I2C接收一个字节* param 无* retval 接收到的一个字节数据*/
unsigned char I2C_ReceiveByte(void)
{unsigned char i,Byte0x00;I2C_SDA1;for(i0;i8;i){I2C_SCL1;if(I2C_SDA){Byte|(0x80i);}I2C_SCL0;}return Byte;
}/*** brief I2C发送应答* param AckBit 应答位0为应答1为非应答* retval 无*/
void I2C_SendAck(unsigned char AckBit)
{I2C_SDAAckBit;I2C_SCL1;I2C_SCL0;
}/*** brief I2C接收应答位* param 无* retval 接收到的应答位0为应答1为非应答*/
unsigned char I2C_ReceiveAck(void)
{unsigned char AckBit;I2C_SDA1;I2C_SCL1;AckBitI2C_SDA;I2C_SCL0;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);#endifAT24C02.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();DataI2C_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);#endifmain.c
#include REGX52.H
#include LCD1602.h
#include Key.h
#include AT24C02.h
#include Delay.hunsigned char KeyNum;
unsigned int Num;void main()
{LCD_Init();LCD_ShowNum(1,1,Num,5);while(1){KeyNumKey();if(KeyNum1) //K1按键Num自增{Num;LCD_ShowNum(1,1,Num,5);}if(KeyNum2) //K2按键Num自减{Num--;LCD_ShowNum(1,1,Num,5);}if(KeyNum3) //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(KeyNum4) //K4按键从AT24C02读取数据{NumAT24C02_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, );}}
}三、定时器扫描按键数码管