【项目】----RTC DS1307 I2C

本文详细介绍了I2C通信协议及其应用,特别关注了24系列EEPROM的使用方法,包括协议简介、EEPROM简介、读写操作流程以及硬件操作说明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

看见一个不错的帖子

Copy过来

1、协议简介(SCL由主机提供)

开始信号(START):在时钟线(SCL)为高电平其间,数据线(SDA)由高变低,时钟线(SCL)置低

停止信号(STOP):在时钟线(SCL)为高电平其间,数据线(SDA)由低变高,时钟线(SCL)置低

收从机应答:将数据线(SDA)置高,时钟线(SCL)变低-->变高-->变低,判断数据线(SDA)的电平:低为有应答,高位无应答

主机发应答(ACK):将数据线(SDA)置低,时钟线(SCL)变低-->变高-->变低,将SDA置高

主机发不应答(NACK):将数据线(SDA)置高,时钟线(SCL)变低-->变高-->变低

注:以上每个步骤操作完都需确保时钟线(SCL)为低电平(STOP除外)

    另外在数据操作过程中,时钟线(SCL)为高电平时间不允许数据线(SDA)有改变,否则会被认为是START或STOP

在时钟线(SCL)的上升沿读数据(每8bit为一组,高位在前)

在时钟线(SCL)的下降沿写数据(每8bit为一组,高位在前)

2、24系列EEPROM简介

24CXX中XX的单位是kbit,如24C08,其存储容量为8k bit

工作电压(VCC):

   24CXX:    4.5V-5.5V

   24CXX-W: 2.5V-5.5V

   24CXX-R: 1.8V-5.5V

输入电平定义(VIH,VIL):

   VIH:0.7VCC-VCC+1

   VIL:-0.45V-0.3VCC

地址脚:

   24C01/24C02 三个地址脚(E0,E1,E2)都有效,24C04只有E2,E1有效,24C08只有E2有效,24C16三个地址脚都无效,如下图所示,所谓地址脚无 效是指不需要接入电路中(NC ,not connected),其对应的地址位要用来表示要操作的字节的高位地址。

  24C32/24C64三个地址脚都有效;

  24C128/24C256/24C512的地址脚E1和E0有效,其余为NC;

  24C1024的地址脚E1有效,其余为NC

器件地址:

   当总线上连接多个I2C器件时,需要对器件进行寻址。器件地址如下表所示,其中E2,E1,E0是指三个引脚的状态,取决于是接地还是接高电平,R/W为1则为读操作,为0则为写操作。A8,A9,A10,A16指的是所要操作的字节地址的高位,后面会提到。

   芯片              bit7  bit6  bit5  bit4  bit3  bit2  bit1   bit0

   24C01/02            1     0     1     0     E2    E1   E0    R/W

   24C04               1     0     1     0     E2    E1   A8    R/W

   24C08               1     0     1     0     E2    A9   A8    R/W

   24C16               1     0     1     0     A10   A9   A8    R/W

   24C32/64            1     0     1     0     E2    E1   E0    R/W

   24C128/256/512      1     0     1     0     0     E1   E0    R/W

   24C1024             1     0     1     0     0     E1   A16   R/W

字节地址:

   在对芯片内的某一字节或一连续地址进行读写操作时,需要制定其地址或首字节的地址,不同芯片地址有不同的表示方式,如下表所示,其中有些芯片的地址位的高位存储在器件地址中。

  芯片                地址位数                 地址范围

  24C01               bit7-bit0                0x00-0x7F

  24C02               bit7-bit0                0x00-0xFF

  24C04               A8,bit7-bit0             0x00-0x1FF

  24C08               A9,A8,bit7-bit0          0x00-0x3FF

  24C16               A10,A9,A8,bit7-bit0      0x00-0x7FF

  24C32               bit15-bit8,bit7-bit0    0x00-0xFFF

  24C64               bit15-bit8,bit7-bit0    0x00-0x1FFF

  24C128              bit15-bit8,bit7-bit0    0x00-0x3FFF

  24C256              bit15-bit8,bit7-bit0    0x00-0x7FFF

  24C512              bit15-bit8,bit7-bit0    0x00-0xFFFF

  24C1024             A16,bit15-bit8,bit7-bit0 0x00-0x1FFFF

3、读写操作流程(具体可参见这两款芯片的datasheet)

24C02:


随机读1个字节:START-->发送器件地址(写)-->收ACK-->发需读取数据的地址-->收ACK-->START-->
                          发送器件地址(读)-->ACK-->接收数据-->发NACK-->STOP

当前地址读一个字节:START-->发送器件地址(读)-->ACK-->接收数据-->发NACK-->STOP

随机写一个字节:START-->发送器件地址(写)-->收ACK-->发需写数据的地址-->收ACK-->写数据-->
                            收ACK-->STOP

页写:START-->发送器件地址(写)-->收ACK-->发需写数据的地址-->收ACK-->写数据-->收ACK-->
          写数据-->收ACK-->......-->写数据-->收ACK-->STOP
       (注:24C02一次只能页写1~8个字节,且页写首地址必须为页的首地址;

                  另外随机写或页写完都需查询器件是否空闲,才能进行下面的操作)

连续读:START-->发送器件地址(写)-->收ACK-->发需读取数据的地址-->收ACK-->START-->
              发送器件地址(读)-->收ACK-->接收数据-->发ACK-->接收数据-->发ACK-->......-->
             接收数据-->发NACK-->STOP

          (注:连续读不受字节数限制,但地址越界会返回到00地址,并重新累加)

24C512:

随机读1个字节:START-->发送器件地址(写)-->收ACK-->发需读取数据的地址高字节-->收ACK-->

                         发需读取数据的地址低字节-->收ACK-->START-->发送器件地址(读)-->ACK-->接收数据

                         -->发NACK-->STOP

当前地址读一个字节:START-->发送器件地址(读)-->ACK-->接收数据-->发NACK-->STOP

随机写一个字节:START-->发送器件地址(写)-->收ACK-->发需写数据的地址高字节-->收ACK

                           -->发需读取数据的地址低字节-->收ACK-->写数据-->收ACK-->STOP

页写:START-->发送器件地址(写)-->收ACK-->发需写数据的首地址高字节-->收ACK-->发需写数据的地址低字节-->收ACK

          -->写数据-->收ACK-->写数据-->收ACK-->......-->写数据-->收ACK-->STOP
       (注:24C02一次只能页写1~64个字节,且页写首地址必须为页的首地址;

                  另外随机写或页写完都需查询器件是否空闲,才能进行下面的操作)

连续读:START-->发送器件地址(写)-->收ACK-->发需读取数据的首地址高字节-->收ACK

             -->发需读取数据的首地址低字节-->收ACK-->START-->发送器件地址(读)-->收ACK

             -->接收数据-->发ACK-->接收数据-->发ACK-->......-->接收数据-->发NACK-->STOP

          (注:连续读不受字节数限制,但地址越界会返回到00地址,并重新累加)

4、硬件操作说明

51单片机:

         P0口:外面需加10K~100K上拉电阻;

                   对端口置1输出高;

                   对端口置0输出低;

                   读取时先将数据端口置高,再读取。

         其它口:不用加上拉电阻,操作同上

其它带方向选择I/O的单片机:

        不带上拉电阻的I/O:外接10K~100K上拉,将端口锁存器置0;

                                        将端口设置为输入口就可以输出高(由于上拉电阻作用);
                                        将端口设置为输出口就可以输出低;

                                        读取时,先将数据端口设为输入口再读取。

         带上拉电阻的I/O:不用上拉电阻,操作同上

转载于:https://www.cnblogs.com/wangyuezhuiyi/p/3286606.html

#include #include //自定义头文件,KeyScan用于键盘扫描。 #include //用于I2C总线。 #define uchar unsigned char #define uint unsigned int unsigned char b[7]={50,58,9,1,15,6,15},clock1[2]={0,12},clock2[2]={0,0}; //b[7]的元素含义:秒,分,时,星期,日,月,年 clock的元素含义:分,时。 code unsigned char tab[11]={0x03,0xf3,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09,0x00}; //数码管0-9的编码列表,0x00点亮全部管。 code unsigned char tab2[2]={0x6d,0xff}; //ox6d: 表示三横图标。 unsigned char time[7]; //时间设置函数的参数。 void delay(unsigned int cnt); //延时函数声明。 unsigned char getkey1(); //unsigned char getkey2(); //读键盘函数声明。 void tim(void); //中断函数声明。 void KeyDelay(unsigned int KeyJsTime); //键盘扫描延时函数声明。 void display(uchar bit7,uchar bit6,uchar bit5,uchar bit4, uchar bit3,uchar bit2,uchar bit1,uchar bit0); //数码管显示函数。 void ReadTime(unsigned char TIME[7]); //DS1307读时间函数。 void SetTime(unsigned char TIME[7]); //设置时间初值函数。 void SwitchRTC(unsigned char SWITCH); //时间修改的使能函数:SWITCH=1禁止修改时间,SWITCH=0可以修改时间。 uchar dis_num_h; //显示记录数据的组别十位 uchar dis_num_l; //显示记录数据的组别个位 uchar dis_min_h; //要显示的分的十位; uchar dis_min_l; //要显示的分的个位; uchar dis_sec_h; //要显示的秒的十位; uchar dis_sec_l; //要显示的秒的个位; uchar dis_dsec; //要显示的0.1秒; uchar min=0x00; //防止意外,赋初值。分······· uchar sec=0x00; //秒 uchar dsec=0x00; //十分之一秒。 uchar en,i,clocken1=0,clocken2=0; main() { unsigned char quzhi,xianshi,symbol=0x55,set,set1=0x55,ce; unsigned char c[30]; unsigned char num,num1,j,k,stop=1; //注意stop必须先赋初值1。 PLLCON&=0xf8; //设置频率为12.582912MHz TMOD=0x01; //选定定时器及其工作模式。 TH0=0xce; //赋初值:52736,则总共的计数次数为:65536-52736=12800,即12.8毫秒。 TL0=0x00; IE=0x82; //中断控制,10000010,EA=1开总中断,ET0=1:定时器0中断允许。0x82:1000 0010 I2CCON=0xE8; //开启I2C总线通信,具体含义参阅ADuC848英文版说明资料。 SetTime(b); //设定初始时间。 SwitchRTC(1); //调用时间保持函数。 while(1) //设置死循环,实现循环执行。 { ReadTime(time); //调用读时间函数,读取当前的时间,并保留在time数组中。 if(((clock1[0]==time[1])&&(clock1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值