MCU_AT24C02存储芯片

转自:

https://blog.csdn.net/morixinguan/article/details/50705428

 

/*******************************************************************************************************************

*Author:JYW

*Time:2019_02_20

*Describe:学而有益故转以习之

***************************************************************************************************/

AT24C02是一个2K位串行CMOS E2PROM, 内部含有256个8位字节,CATALYST公司的先进CMOS技术实质上减少了器件的功耗。AT24C02有一个8字节页写缓冲器。该器件通过IIC总线接口进行操作,有一个专门的写保护功能。

了解了什么是AT24C02之后,我们具体要如何来操作它呢?

操作它之前,我们先来了解一下I2C总线,什么是I2C总线?

I2C总线(I2C bus,Inter-IC bus)是一个双向的两线连续总线,提供集成电路(ICs)之间的通信线路。I2C总线是一种串行扩展技术,最早由Philips公司推出,广泛应用于电视,录像机和音频设备。I2C总线的意思是“完成集成电路或功能单元之间信息交换的规范或协议”。Philips公司推出的I2C总线采用一条数据线(SDA),加一条时钟线(SCL)来完成数据的传输及外围器件的扩展;对各个节点的寻址是软寻址方式,节省了片选线,标准的寻址字节SLAM为7位,可以寻址127个单元。

I2c总线的模拟方法:

SDA:数据线

SCL:时钟线

- SCL是高电平,而SDA是由低电平变为高电平,建立SDA保持的时间要>4.7us

-- 在SCL的时钟信号在高电平期间SDL信号产生一个下降沿。
起始之后的SDL和SCL都为0,同样保持时间也要>4.7us

 

SCL高电平期间,SDA线由低电平向高电平的变化表示终止信号
- 当SCL高电平的时候,SDA要产生一个上升沿,SDA产生上跳沿之前是低电平,
建立从低电平到高电平这个期间,时间间隔要大于4us

 

如何发送一个字节:

1、首先发数据每次都是发一个字节,一个字节有8位的数据,所以我们需要定义一个8位的代表数据的变量,最可靠的就是unsigned char
   发数据的时候是一位一位的发,所以需要有一个循环来发,发送数据发8位要从最高位开始,所以要将数据线偏移到最高的位置也就是
   要右移7位,可以这么理解,看下图:

   刚开始,dat表示:10000000  ,dat表示1 
   现在要将dat偏移到最高位,那么dat要干掉所有的0,也就是要右移7位
   10000000 >> 7  =  1;

   接着再循环将dat重新一位一位的往左移,也就是从高位移到地位 1 << 7 = 10000000 for(dat = 0 ; dat < 8 ; dat++);

如何接受一个字节:
1、接受和发送其实是一样的,区别在于发送是写数据,而接受是读数据

 

/*--------------------------------------------------------------------------
I2C.H
这个头文件主要是模拟I2C总线的发送和接收还有AT24C02的使用,
因为51单片机本身不带有I2C的总线的功能。
      
      本文件分为以下6个接口:
      1、I2C总线的起始信号
      2、I2C总线的结束信号
      3、I2C总线发送数据
      4、I2C总线接收数据
      5、AT24C02写数据
      6、AT24C02读数据
日期:2015年9月27日
开发者:杨源鑫
备注:
      用户在使用该程序模块的时候只需调用最后两个函数即可,也就是AT24C02
      的函数。
--------------------------------------------------------------------------*/
 
#ifndef __I2C_H
#define __I2C_H
#include <reg51.h>
#include "i2c.h"
 
sbit SCL=P2^1;       //时钟线
sbit SDA=P2^0;       //地址线
 
 
/**
 * 函数: void At24c02Write(unsigned char addr,unsigned char dat);
 * 函数功能:AT24C02写数据.
 * 使用方法:用户想要往里写数据的话就调用本函数,传入地址和数据即可
 **/
 
void At24c02Write(unsigned char addr,unsigned char dat);
 
/**
 * 函数: unsigned char At24c02Read(unsigned char addr);
 * 函数功能:AT24C02读数据.
 * 使用方法:用户想要读数据的话就调用本函数,传入地址即可
 **/
 
unsigned char At24c02Read(unsigned char addr);
 
/**
 * 函数: void I2C_Start_signal(void);
 * 函数功能:I2C总线的起始信号
 **/
 
void I2C_Start_signal(void);
 
/**
 * 函数: void I2C_Stop_signal(void);
 * 函数功能:I2C总线的结束信号
 **/
 
void I2C_Stop_signal(void);
 
/**
 * 函数: unsigned char I2C_SendByte(unsigned char dat, unsigned char ack);
 * 函数功能:I2C总线的写数据
 **/
 
unsigned char I2C_SendByte(unsigned char dat, unsigned char ack);
 
/**
 * 函数: unsigned char I2cReadByte();
 * 函数功能:I2C总线的读数据
 **/
unsigned char I2cReadByte();
 
/**
 * 函数: void Delay10us();
 * 函数功能:10us延时
 **/
 
void Delay10us();
 
 
#endif   //__I2C_H
#include "i2c.h"
 
/*******************************************************************************
* 函数名         : Start_signal(void)
* 函数功能         : I2C总线起始信号
* 输入           : 无
* 输出              : 无
*******************************************************************************/
 
void I2C_Start_signal(void)
{
     SDA = 1 ;
     Delay10us();
     SCL = 1 ;
     Delay10us();
     SDA = 0 ;
     Delay10us();
     SCL = 0 ;
     Delay10us();
}
 
/*******************************************************************************
* 函数名         : Start_signal(void)
* 函数功能         : I2C总线终止信号
* 输入           : 无
* 输出              : 无
*******************************************************************************/
 
void I2C_Stop_signal(void)
{
    SDA = 0 ;
    Delay10us();
       SCL = 1 ;
    Delay10us();
    Delay10us();
    SDA=1;
    Delay10us();
}
 
/*******************************************************************************
* 函数名         : I2C_SendByte(unsigned char dat, unsigned char ack)
* 函数功能         : I2C总线发送数据
* 输入           : dat,一个字节的数据
* 输出              : 发送成功返回1,发送失败返回0
* 备    注       : 发送完一个字节I2C_SCL=0, 需要应答则应答设置为1,否则为0
*******************************************************************************/
 
unsigned char I2C_SendByte(unsigned char dat, unsigned char ack)
{
 
 
 
    unsigned char a = 0,b = 0;//最大255,一个机器周期为1us,最大延时255us。
Replay:
    b = 0 ;            
    for(a=0; a<8; a++)//要发送8位,从最高位开始
    {
        SDA = dat >> 7;     //起始信号之后I2C_SCL=0,所以可以直接改变I2C_SDA信号
        dat = dat << 1;
        Delay10us();
        SCL = 1;
        Delay10us();//建立时间>4.7us
        SCL = 0;
        Delay10us();//时间大于4us        
    }
 
    SDA = 1;
    Delay10us();
    SCL = 1;
    while(SDA && (ack == 1))//等待应答,也就是等待从设备把I2C_SDA拉低
    {
        b++;
        if(b > 200)     //如果超过200us没有应答发送失败,或者为非应答,表示接收结束
        {
            SCL = 0;
            Delay10us();
        //    return 0;
            goto Replay ;   //如果超过200us没有应答则发送失败,或者为非应答,这时候系统启动重发机制
                            //使用goto语句返回到上面接着发
        }
    }
 
    SCL = 0;
    Delay10us();
     return 1;        
}
 
/*******************************************************************************
* 函数名         : I2cReadByte()
* 函数功能         : I2C总线接收数据
* 输入           : 无
* 输出              : dat,数据
*******************************************************************************/
 
unsigned char I2cReadByte()
{
    unsigned char a=0,dat=0;
    SDA=1;            
    Delay10us();
    for(a=0;a<8;a++)//接收8个字节
    {
        SCL=1;
        Delay10us();
        dat<<=1;
        dat|=SDA;
        Delay10us();
        SCL=0;
        Delay10us();
    }
    return dat;    
}
 
/*******************************************************************************
* 函数名         : Delay10us()
* 函数功能         : 延时
* 输入           : 无
* 输出              : 无
*******************************************************************************/
 
void Delay10us()
{
   unsigned char a,b;
    for(b=1;b>0;b--)
        for(a=2;a>0;a--);
}
 
/*******************************************************************************
* 函 数 名         : void At24c02Write(unsigned char addr,unsigned char dat)
* 函数功能           : 往24c02的一个地址写入一个数据
* 输    入         : 地址和数据
* 输    出         : 无
*******************************************************************************/
 
void At24c02Write(unsigned char addr,unsigned char dat)
{
       I2C_Start_signal();
    I2C_SendByte(0xa0, 1);//发送写器件地址
    I2C_SendByte(addr, 1);//发送要写入内存地址
    I2C_SendByte(dat, 0);    //发送数据
    I2C_Stop_signal();
 
}
 
/*******************************************************************************
* 函 数 名         : unsigned char At24c02Read(unsigned char addr)
* 函数功能           : 读取24c02的一个地址的一个数据
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
 
unsigned char At24c02Read(unsigned char addr)
{
    unsigned char num;
    I2C_Start_signal();
    I2C_SendByte(0xa0, 1); //发送写器件地址       1010   0000
    I2C_SendByte(addr, 1); //发送要读取的地址
    I2C_Start_signal();
    I2C_SendByte(0xa1, 1); //发送读器件地址
    num=I2cReadByte(); //读取数据
    I2C_Stop_signal();
    return num;    
}

 

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值