找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 16528|回复: 5
打印 上一主题 下一主题
收起左侧

24C08 I2C存储芯片实验及中文资料下载

[复制链接]
跳转到指定楼层
楼主
ID:195394 发表于 2017-5-5 23:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
24C08中文资料下载:
24cxx中文资料.pdf (576.32 KB, 下载次数: 157)


1.  I2C总线概念

I2C(InterIntegrated Circuit Bus)总线是一种双向二线制总线,是Philps公司推出的串行总线标准(为二线制)。总线上扩展的外围器件及外设接口通过总线寻址。它的结构简单,可靠性和抗干扰性能好。目前很多公司都推出了基于I2C总线的外围器件,例如我们学习板上的24c08芯片,就是一个带有I2C总线接口的E2PROM存储器,具有掉电记忆的功能,方便进行数据的长期保存。

2. I2C总线结构

I2C总线结构很简单,只有两条线,包括一条数据线(SDA)和一条串行时钟线(SCL)。具有I2C接口的器件可以通过这两根线接到总线上,进行相互之间的信息传递。连接到总线的器件具有不同的地址,CPU根据不同的地址进行识别,从而实现对硬件系统简单灵活的控制。

一个典型的I2C总线应用系统的组成结构如下图1所示(假设图中的微控制器、LCD驱动、E2PROM、ADC各器件都是具有I2C总线接口的器件):

  
  

我们知道单片机串行通讯的发送和接收一般都各用一条线TXD和RXD,而I2C总线的数据线既可以发送也可以接受,工作方式可以通过软件设置。所以,I2C总线结构的硬件结构非常简洁。当某器件向总线上发送信息时,它就是发送器,而当其从总线上接收信息时,又成为接收器。

3. I2C总线特点

    组成系统结构简单,占用空间小。芯片管脚的数量少,无需片选信号,价格低,允许若干兼容器件共享总线,应用比较广泛,总线的长度可达7.6m,传送速度可达400kbps,标准速率为100kbps,支持多个组件,I2C上所有的设备的SDA,SCL引脚必须外加上拉电阻

4.  I2C总线上的数据传送

下面我们看看I2C总线是如何进行数据传送的。我们知道,在一根数据线上传送数据时必须一位一位的进行,所以我们首先研究位传送。

1) 位传输

I2C总线每传送一位数据必须有一个时钟脉冲。被传送的数据在时钟SCL的高电平期间保持稳定,只有在SCL低电平期间才能够改变,示意图如下图1所示,在标准模式下,高低电平宽度必须不小于4.7us。


                  图1    位传输时序图

那么是不是所有I2C总线中的信号都必须符合上述的有效性呢?只有两个例外,就是开始和停止信号。

开始信号:当SCL为高电平时,SDA发生从高到低的跳变,出现开始信号以后,总线被认为“忙”。

停止信号:当SCL为高电平时,SDA发生从低到高的跳变,停止信号过后,总线被认为“空闲”。

开始和结束信号的时序图如下图所示:


2) 数据传输的字节格式

SDA传送数据是以字节为单位进行的。每个字节必须是8位,但是传输的字节数量不受限制,首先传送的是数据的最高位。每次传送一个字节完毕,必须接收到从机发出的一个应答位,才能开始下一个字节的传输。如果没有接受到应答位,主机则产生一个停止条件结束本次的传送。那么从机应该发出什么信号算是产生了应答呢?这个过程是这样的。当主器件传送一个字节后,在第9个SCL时钟内置高SDA线,而从器件的响应信号将SDA拉低,从而给出一个应答位。了解了I2C传输数据的格式,下面我们来研究双方传送的协议问题。

3) I2C数据传输协议

I2C总线的数据传输协议如下:

(1)、主器件发出开始信号

(2)、主器件发出第一个字节,用来选通相应的从器件。其中前7位为地址码,第8位为方向位(R/W)。方向位为“0”表示发送,方向位为“1”表示接受。

(3)、从机产生应答信号,进入下一个传送周期,如果从器件没有给出应答信号,此时主器件产生一个结束信号使得传送结束,传送数据无效。

(4)、接下来主、从器件正式进行数据的传送,这时在I2C总线上每次传送的数据字节数不限,但每一个字节必须为8位(传送的时候先送高位,再送低位)。当一个字节传送完毕时,再发送一个应答位(第9位),如上一条所述,这样每次传送一个字节都需要9个时钟脉冲。数据的传送过程如下图所示:


                       图2 I2C总线数据传输协议

4) 24c08芯片相关介绍

AT24c08是带有I2C总线接口的E2PROM存储器,具有掉电记忆的功能,并且可以象普通RAM一样用程序改写。它的容量是1024个字节,有A2、A1、A0三位地址,可见I2C总线上可以连接8片AT24c08,它的寻址字节是1010 A2A1A0 R/W。板上面24c08的电路连接如图所示:


              图3 24C08的硬件接线图

我们对引脚的功能作一个简单的解释:

         VCC,GND:  电源、地引脚

         A2A1A0:    地址引脚

         SCLK、SDA: 通信引脚

         WP:        写保护引脚

从上面的电路连接知:A2A1A0=000,可见如果要对24c08进行写操作,寻址字节是1010 000 0;如果对24c08进行读操作,寻址字节是1010 000 1。用单片机的P3.4脚作为串行时钟线,用P3.5脚作串行数据线。

         写过程:

(1)、主机首先发出开始信号

(2)、发出写24c08的寻址字节1010000 0,即0A0H

(3)、发数据写入24c08的地址,本例中为01H

(4)、往24c08中写入数据,这里是3个字节,分别为48h,0ebh,52h。

(5)、写完毕发出停止信号

         读过程:

(1)、主机发出start信号

(2)、发写24c08的寻址字节1010000 0

(大家可能要问:我们是读数据,为什么要发写信号呢?这是因为你首先要送出一个信号,说明从24c08中的哪个地址读取数据。)

(3)、发要读取的数据在24c08中的地址,即01h

(4)、主机发start信号

(5)、发读24c08的寻址字节1010000 1

(5)、从24 C02中读取数据

(6)、读取完毕发出停止信号

5.实例演练

1)  实验目的

从地址0x00 开始连续写入16个数据(LED流水灯显示码),然后再从地址0x00 开始读出所写入的16个数据,由P0口的LED灯显示出来(先从右到左流,再从左到右流)。

2) 实验电路


3) 实验步骤

将JPLED P0跳线的跳线帽插好

不要插1602LCD 以免干扰P0口LED灯

4) 流程图


5) C语言源程序

通电后 数码管从00开始计数 每过1秒加1 直到99 计数。过程中你可以关闭电源,然后再开启电源,可以看到数值并没有从00开始计数,而是从你关闭电源前的数值开始,这证明我们通过24C08设计的断电记忆功能的计时器设计成功。按键K1键 可以使数值清零 清零后从00开始计数。

//24c08地址为0xa0

#include <reg52.h>

#define uchar unsigned char

unsigned char codetable[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

unsigned char sec=0; //定义计数值,每过1秒,sec加1   

unsigned int count; //定时中断次数     

bit  write=0; //写24C08的标志;

sbit gewei=P2^7; //个位选通定义         

sbit shiwei=P2^6; //十位选通定义     

/////////24C08读写驱动程序////////////////////

sbit scl=P3^4; // 24c08 SCL            

sbit sda=P3^5; // 24c08 SDA      

sbit K5=P1^4; //清0按键      


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

void delay()  //delay 5us

{ ;; }


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

void delay1(uchar x)

{

       uchar a,b;

       for(a=x;a>0;a--)

       for(b=100;b>0;b--);

}

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

void start()  //开始信号

{      

       sda=1;

       delay();

       scl=1;

       delay();

       sda=0;

       delay();

}


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

void stop()   //停止信号

{

       sda=0;

       delay();

       scl=1;

       delay();

       sda=1;

       delay();

}

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

void respons() //应答

{

       uchar i;

       scl=1;

       delay();

       while((sda==1)&&(i<250))i++;

       scl=0;

       delay();

}


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

void init_24c08() //初始化24C02

{

       sda=1;

       delay();

       scl=1;

       delay();

}

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

void write_byte(uchar date)

{

       uchari,temp;

       temp=date;

       for(i=0;i<8;i++)

       {

              temp=temp<<1;

              scl=0;

           delay();

              sda=CY;

              delay();

              scl=1;

              delay();

       //     scl=0;

     // delay();

       }

       scl=0;

       delay();

       sda=1;

       delay();

}

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

uchar read_byte()

{

       uchar i,k;

       scl=0;

       delay();

       sda=1;

       delay();

       for(i=0;i<8;i++)

       {

              scl=1;

              delay();  

              k=(k<<1)|sda;

              scl=0;

              delay();  

       }

       return k;

}


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


void write_24c08(uchar address,uchar shuju) //给指定地址中写入数据

{

       start();

       write_byte(0xa0);    //  最低位为0写,1读

       respons();

       write_byte(address);

       respons();

       write_byte(shuju);

       respons();

       stop();

}


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

uchar read_24c08(uchar address) //从24c08指定地址中读出数据

{

       uchardate;

       start();

       write_byte(0xa0);

       respons();

       write_byte(address);

       respons();


       start();

       write_byte(0xa1);

       respons();

       date=read_byte();

       stop();

       returndate;

}


/////////////24C02读写驱动程序完/////////////////////



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

void LEDshow() //LED显示函数   

{

      

   P0=table[sec/10];

    shiwei=0;

       delay1(40);

       shiwei=1;


       P0=table[sec%10];

    gewei=0;

       delay1(40);

       gewei=1;

}


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

void main(void)

{


       TMOD=0x01;//定时器工作在方式1

       ET0=1;

    EA=1;

       init_24c08();//初始化24C08

       sec=read_24c08(2);//读出保存的数据赋于sec

       TH0=(65536-50000)/256;//对TH0 TL0赋值

       TL0=(65536-50000)%256;//使定时器0.05秒中断一次

       TR0=1; //开始计时

              while(1)

              {

                  LEDshow();

                     if(write==1)//判断计时器是否计时一秒      

                     {

                     write=0;//清零

                     write_24c08(2,sec);//在24c08的地址2中写入数据sec   

                     }


                if(K5==0){

                   delay1(10);

                     if(K5==0){

                      sec=0;

                     }

         }

              }

}



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


void t0(void) interrupt 1 using 0 //定时中断服务函数   

{

       TH0=(65536-50000)/256;//对TH0 TL0赋值   

       TL0=(65536-50000)%256;//重装计数初值  

       count++;//每过50ms tcnt加一     

       if(count==20)//计满20次(1秒)时      

       {

              count=0;//重新再计

              sec++;

              write=1;//1秒写一次24C08

              if(sec==100)//定时100秒,在从零开始计时

              {sec=0;}

       }

}



6  拓展训练

   1)用24C08与1602LCD设计电子密码锁

   2)12864LCD显示24C08保存的开机画面。即运行时,单片机程序从24C08中读取该画面并显示在12864LCD液晶显示屏上。


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:255272 发表于 2018-4-26 16:05 | 只看该作者
看了很多资料了,希望自己能学会
回复

使用道具 举报

板凳
ID:255272 发表于 2018-4-26 16:06 | 只看该作者
每次开始学习新知识都会不知所措,不知道什么事重点,从何处下手
回复

使用道具 举报

地板
ID:417093 发表于 2018-10-31 09:04 | 只看该作者
配图在哪里可以看到呢?
回复

使用道具 举报

5#
ID:765667 发表于 2020-5-31 13:12 | 只看该作者
了解了解
回复

使用道具 举报

6#
ID:466997 发表于 2022-5-19 14:23 | 只看该作者
值 得学习,MARKING!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表