AT24C02

AT24C02介绍

AT24C01/02/04/08/16…是一个 1K/2K/4K/8K/16K 位串行 CMOS,内部含有128/256/512/1024/2048 个 8 位字节,AT24C01 有一个 8 字节页写缓冲器,AT24C02/04/08/16 有一个 16 字节页写缓冲器。该器件通过 I2C 总线接口进行操作,它有一个专门的写保护功能。51开发板上使用的是 AT24C02(EEPROM)芯片,此芯片具有 I2C 通信接口,芯片内保存的数据在掉电情况下都不丢失,所以通常用于存放一些比较重要的数据等。AT24C02 芯片管脚及外观图如下图所示:
在这里插入图片描述

芯片管脚使用说明

引脚号引脚名称功能说明
1A0 地址输入。A2、A1和A0是器件地址输入引脚。
24C02/32/64使用A2、A1和A0输入引脚作为硬件地址,总线上可同时级联8个24C02/32/64器件。
24C08使用A2输入引脚作为硬件地址,总线上可同时级联2个24C08器件,AO和A1为空脚,可接地。
24C04使用A2和A1输入引脚作为硬件地址,总线上可同时级联4个24C04器件,A0为空脚,可接地。
24C16未使用器件地址引脚,总线上最多只可连接一个16K器件,A2、A1和A0为空脚,可接地。
2A1
3A2
5SDA串行地址和数据输入/输出。SDA是双向串行数据传输引脚,极开路,需外接上拉电阻到Vcc(典型值10kQ)。
6SCl串行时钟输入。SCL同步数据传输,上升沿数据写入,下降沿数据读出。
7WP写保护。WP引脚提供硬件数据保护。当WP接地时,允许数据正常读写操作:当WVP接Vcc时,写保护,只读。
4GND
9VCC正电源

AT24C02 器件地址为 7 位,高 4 位固定为 1010,低 3 位由 A0/A1/A2 信号线的电平决定。 因为传输地址或数据是以字节为单位传送的,当传送地址时,器件地址占 7 位,还有最后一位(最低位 R/W)用来选择读写方向,它与地址无关。其格式如下
在这里插入图片描述
51开发板已经将芯片的 A0/A1/A2 连接到 GND,所以器件地址为1010000,即 0x50(未计算最低位)。如果要对芯片进行写操作时,R/W 即为 0,写器件地址即为 0XA0;如果要对芯片进行读操作时,R/W 即为 1,此时读器件地址为 0XA1。开发板上也将 WP 引脚直接接在 GND 上,此时芯片允许数据正常读写。
在这里插入图片描述
芯片的 SCL 和 SDA 管脚是连接在单片机的 P2.1 和 P2.0 上,为了让 IIC 总线默认为高电平,通常会在 IIC总线上接上拉电阻,在图中并没有看到 SCL 和 SDA 管脚有上拉电阻,这是因为51开发板单片机 IO 都外接了 10K 上拉电阻,当单片机 IO 口连接到芯片的 SCL 和 SDA脚时即相当于它们外接上拉电阻,所以此处可以省去。

实验

下面是使用IIC控制AT24C02代码,按键P3_1、P3_0、P3_2、P3_3来控制输入的内容。
当案件P3_2按下值会自增1,当案件P3_3按下值会归零。P3_1按下会将数据写到AT24C02中,当P3_0按下会读出AT24C02的值。public是一个延时函数,这个不再展示

main.c

#include <REGX52.H>
#include "public.h"
#include "at24c02.h"
#include "key.h"
#include "smg.h"

void main()
{
    u8 key=0;
    u8 val=0;
    u8 dis[3];
    while(1)
    {
        key=key_scan(0);
        if(key==KEY1_PRESS) at24c02_write_byte(0,val);
        else if(key==KEY2_PRESS) val=at24c02_read_byte(0);
        else if(key==KEY3_PRESS) val++;
        else if(key==KEY4_PRESS) val=0;
        dis[0]=val/100;
        dis[1]=val%100/10;
        dis[2]=val%100%10;
        smg_display(dis,6);
    }
}

IIC.c

#include "IIC.h"

void IIC_Start()
{
    IIC_SDA=1;
    delay_10us(1);
    IIC_SCL=1;
    delay_10us(1);
    IIC_SDA=0;
    delay_10us(1);
    IIC_SCL=0;
    delay_10us(1);
}

void IIC_Stop()
{
    IIC_SDA=0;
    delay_10us(1);
    IIC_SCL=1;
    delay_10us(1);
    IIC_SDA=1;
    delay_10us(1);
}

void IIC_Ack()
{
    IIC_SCL=0;
    IIC_SDA=0;
    delay_10us(1);
    IIC_SCL=1;
    delay_10us(1);
    IIC_SCL=0;
}

void IIC_Nack()
{
    IIC_SCL=0;
    IIC_SDA=1;
    delay_10us(1);
    IIC_SCL=1;
    delay_10us(1);
    IIC_SCL=0;
}
u8 IIC_Wait_Ack()
{
    u8 time=100;
    IIC_SCL=1;
    delay_10us(1);
    while(IIC_SDA)
    {
        time--;
        if(time==1)
        {
            IIC_Stop();
            return 1;
        }
    }  
    IIC_SCL=0;
    return 0;
}

void IIC_Write_Byte(u8 dat)
{
    u8 i=0;
    IIC_SCL=0;
    for(i=0;i<8;i++)
    {
        if((dat & 0x80)>0) IIC_SDA=1;
        else IIC_SDA=0;
        dat<<=1;
        delay_10us(1);
        IIC_SCL=1;
        delay_10us(1);
        IIC_SCL=0;
        delay_10us(1);
    }
}


u8 IIC_Read_Byte(u8 ack)
{
    u8 i=0,dat=0;
    for(i=0;i<8;i++)
    {
        IIC_SCL=0;
        delay_10us(1);
        IIC_SCL=1;
        dat<<=1;
        if(IIC_SDA) dat++;
        delay_10us(1);
    }
    if(!ack) IIC_Nack();
    else IIC_Ack();
    return dat;
}

IIC.h

#ifndef __IIC_H_
#define __IIC_H_

#include "public.h"

sbit IIC_SDA=P2^0;
sbit IIC_SCL=P2^1;

void IIC_Start();
void IIC_Stop();
void IIC_Ack();
void IIC_Nack();
u8 IIC_Wait_Ack();
void IIC_Write_Byte(u8 dat);
u8 IIC_Read_Byte(u8 ack);

#endif

at24c02.c

#include "at24c02.h"
#include "IIC.h"

void at24c02_write_byte(u8 addr ,u8 dat)
{
    IIC_Start();
    IIC_Write_Byte(0xA0);
    IIC_Wait_Ack();
    IIC_Write_Byte(addr);
    IIC_Wait_Ack();
    IIC_Write_Byte(dat);
    IIC_Wait_Ack();
    IIC_Stop();
    delay_ms(10);
}

u8 at24c02_read_byte(u8 addr)
{
    u8 res=0;
    IIC_Start();
    IIC_Write_Byte(0xA0);
    IIC_Wait_Ack();
    IIC_Write_Byte(addr);
    IIC_Wait_Ack();
    IIC_Start();
    IIC_Write_Byte(0xA1);
    IIC_Wait_Ack();
    res=IIC_Read_Byte(0);
    IIC_Stop();
    return res;
}

at24c02.h

#ifndef __AT24C02_H_
#define __AT24C02_H_

#include "public.h"

void at24c02_write_byte(u8 addr ,u8 dat);
u8 at24c02_read_byte(u8 addr);


#endif

smg.c

#include "smg.h"

u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
				0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

void smg_display(u8 dat[],u8 pos)
{
	u8 i=0;
	u8 pos_temp=pos-1;

	for(i=pos_temp;i<8;i++)
	{
	   	switch(i)
		{
			case 0: LSC=1;LSB=1;LSA=1;break;
			case 1: LSC=1;LSB=1;LSA=0;break;
			case 2: LSC=1;LSB=0;LSA=1;break;
			case 3: LSC=1;LSB=0;LSA=0;break;
			case 4: LSC=0;LSB=1;LSA=1;break;
			case 5: LSC=0;LSB=1;LSA=0;break;
			case 6: LSC=0;LSB=0;LSA=1;break;
			case 7: LSC=0;LSB=0;LSA=0;break;
		}
		SMG_A_DP_PORT=gsmg_code[dat[i-pos_temp]];
		delay_10us(100);
		SMG_A_DP_PORT=0x00;//ÏûÒô
	}
}

smg.h

#ifndef _smg_H
#define _smg_H

#include <REGX52.H>
#include "public.h"


#define SMG_A_DP_PORT	P0	


sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;


void smg_display(u8 dat[],u8 pos);

#endif

key.c

#include "key.h"


u8 key_scan(u8 mode)
{
	static u8 key=1;

	if(mode)key=1;
	if(key==1&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0))
	{
		delay_10us(1000);
		key=0;
		if(KEY1==0)
			return KEY1_PRESS;
		else if(KEY2==0)
			return KEY2_PRESS;
		else if(KEY3==0)
			return KEY3_PRESS;
		else if(KEY4==0)
			return KEY4_PRESS;	
	}
	else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1)
	{
		key=1;			
	}
	return KEY_UNPRESS;		
}

key.h

#ifndef _key_H
#define _key_H

#include "public.h"

sbit KEY1=P3^1;
sbit KEY2=P3^0;
sbit KEY3=P3^2;
sbit KEY4=P3^3;


#define KEY1_PRESS	1
#define KEY2_PRESS	2
#define KEY3_PRESS	3
#define KEY4_PRESS	4
#define KEY_UNPRESS	0


u8 key_scan(u8 mode);

#endif
  • 15
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值