【蓝桥杯单片机】七、EEPROM-AT24C02

本文详细介绍了AT24C02串行EEPROM的使用,包括基本介绍、写操作(单字节写入与页面写入)和读操作(立即地址读取、随机地址读取、顺序地址读取)。并提供了一个实际应用示例,展示如何将开机次数存储并显示在AT24C02中。
摘要由CSDN通过智能技术生成

1、AT24C02的基本介绍

24C01/02/04/08/16是低工作电压的1K/2K/4K/8K/16K 位串行电可擦除只读存储器,内部组织为128/256/512/1024/2048 个字节,每个字节8位,该芯片被广泛应用于低电压及低功耗的工商业领域。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、AT24C02的操作介绍

2.1、写操作

2.1.1、写一个字节

AT24C02存储器写操作需要在给出开始态器件地址确认之后,紧跟着给出一个8位数据地址。一经收到该地址,EEPROM就通过 SDA发出确认信号并随时钟输入8位数据。在收到8位数据之后,EEPROM 将向SDA确认,数据传送设备必须用停止状态来终止写操作,这时,EEPROM进入一个内计时固定存储器写入周期在该写周期时,所有输入被禁止,EEPROM直到写完后才应答,写字节时序如图所示。
中文版:
在这里插入图片描述
英文版:在这里插入图片描述

2.1.2、写页面

1KB/2KB EEPROM能进行8字节页面写入,4KB、8KB和16KB设备能进行16字节页面写入。
激发写页面与激发写字节相同,只是数据传送设备无须在第一个字节随时钟输入之后,发出一个停止状态。在 EEPROM确认收到第一个数据之后,数据传送设备能再传送7个(1KB、2KB)或15个(4KB、8KB、16KB)数据每一个数据收到之后,EEPROM都将通过SDA回送一个确认信号,最后数据传送设备必须通过停止状态终止页面写序列

英文版:
在这里插入图片描述
中文版
在这里插入图片描述

2.2、读操作

除了器件地址码中读/写选择位置1,读操作与写操作是一样的。读操作有三种:立即地址读取随机地址读取顺序读取

2.2.1、立即地址读取

内部数据字地址指针保持在读写操作中最后访问的地址按“1”递增只要芯片保持上电,该地址在两个操作之间一直有效,如果最后一个操作是在地址n处读取,则立即地址是n+1;如果最后操作是在地址n处写入,则立即地址也是n+1。
在这里插入图片描述

2.2.1、随机地址读取

随机读取需要一个空字节写序列来载入数据地址一旦器件地址码数据码地址码时钟输入,并被EEPROM确认,数据传送设备就必须产生另一个开始条件。读/写选择位处于高电平时,通过送出一个器件地址,数据传送设备激发出一个立即寻址读取,EEPROM确认器件地址,并随时钟串行输出数据。器件读数据不通过确认(使SDA总线处于高电平)应答,而通过产生一个停止条件应答。
在这里插入图片描述

2.3.1、顺序地址读取

顺序读取由立即地址读取或随机地址读取激发,在读数据器件收到一数据码之后,通过确认应答,只要EEPROM收到确认之后,便会继续增加数据码地址及串行输出数据码。当达到存储器地址极限时,数据码地址将重复滚动,顺序读取将继续。当读数据器件不通过确认(使SDA总线处于高电平)应答,而通过产生一个停止条件应答时,顺序读取操作被终止。
在这里插入图片描述

AT2402的操作练习

将开机次数存储在 AT24CO2中,范围0~100,并通过数码管显示出来。
mian.c

#include "STC15F2K60S2.h"
#include "iic.h"
#include "intrins.h"

typedef unsigned char uchar;
typedef unsigned int uint;

uchar dsp_code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar dsp_dat[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
uchar dat;

void time0_init()
{
  AUXR |= 0x80;
  TMOD &= F0;
  TL0=0XCD;
  TH0=0XD4;
  TR0=1;
  ET0=1;
  EA=1;
}

void time0_isr() interrupt 1
{
  static uchar dsp_com = 0;
  P0=0,P2=0xc0,P2=0;
  P0=dsp_dat[dsp_com],P2=0xe0,P2=0;
  P0=1<<dsp_com,P2=0xc0,P2=0;
  
  if(++dsp_com==8) dsp_com=0;
  
}

void Delay300ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 13;
	j = 156;
	k = 83;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

int main()
{
  
  uchar i;
  P0=0xff,P2=0x80,P2=0;
  P0=0x00,P2=0xa0,P2=0;
  Delay300ms(); //电源按键延时
  dat = read_dat(0x00);
  if(dat>99) dat=0;
  
  wirte_dat(0x00,++dat);
  //在连续多次写入时需加延时5ms
  time0_init();
  
  while(1)
  {
    if(dat>9) dsp_dat[6]=dsp_code[dat/10];
    else dsp_dat[6]=0xff;
     dsp_dat[7]=dsp_code[dat%10];
  }
   while(1);
}

iic.c

#include "iic.h"

#define DELAY_TIME 5

#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

void IIC_Delay(unsigned char i)
{
    do{_nop_();}
    while(i--);        
}


void IIC_Start(void)
{
    SDA = 1;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 0;
    IIC_Delay(DELAY_TIME);
    SCL = 0;	
}


void IIC_Stop(void)
{
    SDA = 0;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}


//void IIC_SendAck(bit ackbit)
//{
//    SCL = 0;
//    SDA = ackbit;  					
//    IIC_Delay(DELAY_TIME);
//    SCL = 1;
//    IIC_Delay(DELAY_TIME);
//    SCL = 0; 
//    SDA = 1;
//    IIC_Delay(DELAY_TIME);
//}


bit IIC_WaitAck(void)
{
    bit ackbit;
	
    SCL  = 1;
    IIC_Delay(DELAY_TIME);
    ackbit = SDA;
    SCL = 0;
    IIC_Delay(DELAY_TIME);
    return ackbit;
}


void IIC_SendByte(unsigned char byt)
{
    unsigned char i;

    for(i=0; i<8; i++)
    {
        SCL  = 0;
        IIC_Delay(DELAY_TIME);
        if(byt & 0x80) SDA  = 1;
        else SDA  = 0;
        IIC_Delay(DELAY_TIME);
        SCL = 1;
        byt <<= 1;
        IIC_Delay(DELAY_TIME);
    }
    SCL  = 0;  
    
    IIC_WaitAck(); //直接将等待应答函数写到此处
    // 后面写读取函数or 转换函数时就不用一直重复写这个函数
}

unsigned char IIC_RecByte(void)
{
    unsigned char i, da;
    for(i=0; i<8; i++)
    {   
    	SCL = 1;
    IIC_Delay(DELAY_TIME);
    da <<= 1;
    if(SDA) da |= 1;
    SCL = 0;
    IIC_Delay(DELAY_TIME);
    }
    
    IIC_WaitAck(); //直接将等待应答函数写到此处
    // 后面写读取函数or 转换函数时就不用一直重复写这个函数
    return da;    
    
}


//注意∶写设备和读设备地址只相差1
unsigned char read_dat(unsigned char add)
{
  unsigned char dat;
  
  IIC_Start();
  IIC_SendByte(0xa0); // MCU 向AT24c02发送"写设备"命令
  IIC_SendByte(add);
  
  IIC_Start();
  IIC_SendByte(0xa1); //MCU 向 AT24c02发送"读设备"命令
  dat =IIC_RecByte(); //读取 A/D转换值 0-255
  
  IIC_Stop();
  return dat;
  
}


void wirte_dat(unsigned char add,unsigned char dat)
{
  IIC_Start();
  IIC_SendByte(0xa0); // MCU 向AT24c02发送"写设备"命令
  IIC_SendByte(add);
  IIC_SendByte(dat);
  IIC_Stop();
}

iic.h

#ifndef _IIC_H
#define _IIC_H

#include <STC15F2K60S2.H>
#include "intrins.h"

sbit SDA = P2^1;
sbit SCL = P2^0;

void IIC_Start(void); 
void IIC_Stop(void);  
bit IIC_WaitAck(void);  
void IIC_SendAck(bit ackbit); 
void IIC_SendByte(unsigned char byt); 
unsigned char IIC_RecByte(void); 
unsigned char read_dat(unsigned char add); //这个自己加上的
void wirte_dat(unsigned char add,unsigned char dat);

#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值