第十五届蓝桥杯单片机组——AT24C02(附带可直接运行的代码)
简单介绍一下AT24C02,并根据数据手册和蓝桥杯官方给的IIC驱动代码编写代码,文中给出示例代码
·
文章目录
一、AT24C02介绍
- 存储容量:AT24C02的存储空间是2K位(256字节)。由于它是一个8位I/O的串行接口类型的EEPROM,所以可以为你的设备提供额外的存储。
- I2C接口:AT24C02使用I2C(Inter-integrated Circuit)接口,这是一种同步串行总线,它可以配置一个主设备和多个从设备,以便在一个设备和另一个设备之间进行高效的数据传输。
- 软件写保护:AT24C02提供了一个软件写保护机制,该机制可以使应用程序禁止特定内存区域的写操作,以防止误擦写。
二、根据手册写代码
2.1 IIC设备地址
设备地址长度为7bits,其中前4位是固定的,后面三位由硬件电路设计决定。
在进行数据读写的时候,还需要加上一位表示读(0)还是写(1)
硬件设计部分,直接将A2、A1、A0接地,也就是0 0 0:
2.2 写数据
比赛的时候看情况写一个就可以了,如果题目只要求写一个字节,那就单字节,如果多字节那就写多字节。我一般都是单字节,因为多字节也可以由多次调用单字节实现。看个人习惯。
2.2.1 单字节写入
❗❗❗注意写入周期时间:在对AT24C02进行数据写入后,需要给它一定的时间来完成数据存储,这个时间通常是5ms。
void AT24C02_WRITE(unsigned char WRITE_ADDRESS,unsigned char date)
{
IIC_Start();
IIC_SendByte(AT24C02_ADDRESS);
IIC_WaitAck();
IIC_SendByte(WRITE_ADDRESS);
IIC_WaitAck();
IIC_SendByte(date);
IIC_WaitAck();
IIC_Stop();
Delay5ms(); //在对AT24C02进行数据写入后,需要给它一定的时间来完成数据存储,这个时间通常是5ms。
}
❗❗❗再次提醒:在对AT24C02进行数据写入后,需要给它一定的时间来完成数据存储,这个时间通常是5ms
2.2.2 多字节写入
void AT24C02_WRITE(unsigned char WRITE_ADDRESS,unsigned char* date,unsigned char length)
{
unsigned char i;
IIC_Start();
IIC_SendByte(AT24C02_ADDRESS);
IIC_WaitAck();
IIC_SendByte(WRITE_ADDRESS);
IIC_WaitAck();
for(i=0;i<length;i++)
{
IIC_SendByte(*date++); // 其实就是重复单字节写入中的这三行代码
IIC_WaitAck();
}
IIC_Stop();
Delay5ms(); //在对AT24C02进行数据写入后,需要给它一定的时间来完成数据存储,这个时间通常是5ms。
}
❗❗❗Warning:延时5ms,不需要每个字节后延时5ms!!!
2.3 读数据
2.3.1 单字节读取
unsigned char AT24C02_READ(unsigned char READ_ADDRESS)
{
unsigned char date=0x00;
IIC_Start();
IIC_SendByte(AT24C02_ADDRESS);
IIC_WaitAck();
IIC_SendByte(READ_ADDRESS);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(AT24C02_ADDRESS|0x01);
IIC_WaitAck();
date=IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return date;
}
2.3.2 多字节读取
void AT24C02_READ(unsigned char READ_ADDRESS,unsigned char* dat,unsigned char length)
{
unsigned char date=0x00;
unsigned char i;
IIC_Start();
IIC_SendByte(AT24C02_ADDRESS);
IIC_WaitAck();
IIC_SendByte(READ_ADDRESS);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(AT24C02_ADDRESS|0x01);
IIC_WaitAck();
for(i=0;i<length;i++)
{
date=IIC_RecByte();
if(i!=length-1){
IIC_SendAck(0); // 还没读取完数据,发送0,读完了发送1
}
else{
IIC_SendAck(1); // 还没读取完数据,发送0,读完了发送1
}
dat=date;
dat++;
}
IIC_Stop();
}
2.4 容易踩的坑
2.4.1 写数据后没有延时5ms就再次写数据或读数据造成数据异常
2.4.2 读取数据不需要延时
2.4.3 没有读取完数据应答信号应该发0,读完后发1
三、示例代码
#include <stc15.h>
#include <iic.h>
#define AT24C02_ADDRESS 0xa0
unsigned char code dat[]={0xc0, 0xf9, 0xa4, 0xb0, 0x99,
0x92, 0x82, 0xf8, 0x80, 0x90,
0x88,0x80,0xc6,0xc0,0x86,0x8e,
0xbf,0x7f};
void Delay(unsigned int t)
{
while(t--);
}
void selectHC573(unsigned char num)
{
switch(num)
{
case 4:
P2=(P2 & 0x1f) | 0x80;
break;
case 5:
P2=(P2 & 0x1f) | 0xa0;
break;
case 6:
P2=(P2 & 0x1f) | 0xc0;
break;
case 7:
P2=(P2 & 0x1f) | 0xe0;
break;
case 0:
P2=(P2 & 0x1f) | 0x00;
break;
}
}
void system_Init()
{
selectHC573(5);
P0=0x00;
selectHC573(0);
}
void display_SMG_Bit(unsigned char dat, unsigned pos)
{
/*消影法2*/
P0=0xff;
selectHC573(7);
selectHC573(0);
P0=0x01<<(pos-1);
selectHC573(6);
selectHC573(0);
P0=dat;
selectHC573(7);
selectHC573(0);
}
void display_D_SMG(int dat1)
{
display_SMG_Bit(dat[2],1);
Delay(300);
display_SMG_Bit(dat[0],2);
Delay(300);
display_SMG_Bit(dat[2],3);
Delay(300);
display_SMG_Bit(dat[3],4);
Delay(300);
display_SMG_Bit(dat[16],5);
Delay(300);
display_SMG_Bit(dat[16],6);
Delay(300);
display_SMG_Bit(dat[dat1 / 10],7);
Delay(300);
display_SMG_Bit(dat[dat1 % 10],8);
Delay(300);
}
void AT24C02_WRITE(unsigned char WRITE_ADDRESS,unsigned char date)
{
IIC_Start();
IIC_SendByte(AT24C02_ADDRESS);
IIC_WaitAck();
IIC_SendByte(WRITE_ADDRESS);
IIC_WaitAck();
IIC_SendByte(date);
IIC_WaitAck();
IIC_Stop();
Delay5ms();
}
unsigned char AT24C02_READ(unsigned char READ_ADDRESS)
{
unsigned char date=0x00;
IIC_Start();
IIC_SendByte(AT24C02_ADDRESS);
IIC_WaitAck();
IIC_SendByte(READ_ADDRESS);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(AT24C02_ADDRESS|0x01);
IIC_WaitAck();
date=IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return date;
}
void main()
{
unsigned char dat1=0x00,dat2=0x00;
system_Init();
// AT24C02_WRITE(1,18);
// Delay(5000);
AT24C02_WRITE(9,17);
Delay(5000); // 在对AT24C02进行数据写入后,需要给它一定的时间来完成数据存储,这个时间通常是5ms。
dat1=AT24C02_READ(1);
dat2=AT24C02_READ(9);
/*我写这行代码就是为了验证没有写过的存储区默认数据是什么,
结果除于16是因为当数据全为1时,dat2值为31,这会导致数码管
不能正常显示。最终的结果表明了默认的数据全为1,31/16=15*/
while(1){
display_D_SMG(dat2);
}
}
更多推荐
所有评论(0)