IIC通讯的AT24C02学习笔记

引言

最近在学习几种串行通讯协议,感受收获不少,这篇文章是学习IIC总线协议的第一篇文章,之后还会再写一篇关于PCF8591 IIC通讯的ADDA转换芯片的文章.函数

关于IIC总线

IIC 即Inter-Integrated Circuit(集成电路总线),这种总线类型是由飞利浦半导体公司在八十年代初设计出来的一种简单、双向、二线制、同步串行总线,主要是用来链接总体电路(ICS) ,IIC是一种多向控制总线,也就是说多个芯片能够链接到同一总线结构下,同时每一个芯片均可以做为实时数据传输的控制源。主要包括启始、中止、读、写、应答信号。这种方式简化了信号传输总线接口。学习

IIC总线上能够挂多个器件,而每一个器件都有惟一的地址,这样能够标识通讯目标。数据的通讯的方式采用主从方式,主机负责主动联系从机,而从机则被动回应数据。ui

 

 

关于AT24C02

AT24C02是一个2K位串行CMOS E2PROM, 内部含有256个8位字节,CATALYST公司的先进CMOS技术实质上减小了器件的功耗。AT24C02有一个8字节页写缓冲器。该器件经过IIC总线接口进行操做,有一个专门的写保护功能。在单片机上的应用普遍, 能够实现掉电数据不丢失功能。spa

 

 

IIC总线数据有效性的规定

SCL=1期间,SDA必须保持稳定,SCL=0时,SDA才容许改变。设计

 

IIC 总线的几种信号

1.起始和终止信号:

 

 

从时序图能够看出,起始信号为,SCL=1,SDA降低沿;终止信号为SCL=1,SDA为上升沿,保持的时间是有限制的:3d

 

具体的程序实现以下:code

起始信号:SDA=1保持时间大于4。7us,随后SDA=0保持时间大于4usblog

1接口

2内存

3

4

5

6

7

8

9

/*SDA降低沿*/

void start()

{

SDA = 1; //顺序不能反了,先是SDA=1;

SCL = 1;

delay();

SDA = 0;

delay();

}

终止信号:SDA=0保持时间大于4us,随后SDA=1保持时间大于4。7us

1

2

3

4

5

6

7

8

9

/*SDA上升沿*/

void end()

{

    SDA = 0;        //顺序不能反了,先是SDA=0;

    SCL = 1;

    delay();

    SDA = 1;

    delay();

}

2.应答信号:

 

传送的每个字节必须保证是8位长度。数据传送时,先传送最高位(MSB),每个被传送的字节后面都必须跟随一位应答信号(即一帧共有9位)。

如:主机往总线上发送一个字节的数据后,释放总线,从机会把总线拉低(即应答信号),以表示这一字节发送成功

同理主机从总线上读取完一个字节的数据后,主机会把总线拉低,"告诉"从机这一字节的数据接收成功

 

程序实现

应答信号:

1

2

3

4

5

6

7

8

9

void ack()

{

    uchar i = 0;

    SCL = 1;

    delay();

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

    SCL = 0;            //SCL=0,SDA能够改变

    delay();

}

3.AT24C02的器件地址:

根据数据手册和原理图能够看出器件地址为:0x90/0x91其中最后一位是读写方向位,若下一个字节为向总线上发送数据,则为0x90,若下一个字节是从总线上读取数据,则为0x91。

4.往总线上写一字节的数据

程序实现:先写最高位,经过左移运算符,将一字节的数据一位一位的传送到总线上,其中CY存储的是左移后的进位

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

void write_byte(uchar dat)

{

    uchar i;

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

    {

        dat = dat << 1;          //如1011 0011 左移一位为0110 0110

        SCL = 0;            //SDL=0,才能往SDA送数据,或从SDA读数据

        delay();

        SDA = CY;               //上面左移后进位为1

        delay();

        SCL = 1;

        delay();

    }

    SCL = 0;

//      delay();

    SDA = 1;            //释放SDA

    delay();

}

 

5.从总线上读取一个字节的数据

程序实现:带返回值,先读高位,而后经过移位运算符,一位一位读入

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

uchar read_byte()

{

    uchar dat = 0, tmp, i;

    SCL = 0;

    delay();

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

    {

        SCL = 1;        //让SDA保持稳定,准备读取

        delay();

        tmp = SDA;        //读取此时SDA的状态

        dat = dat << 1;

        dat = dat | tmp;

        delay();

        SCL = 0;        //释放SDA总线,为下一次读取作准备

        delay();

    }

    return dat;

}

AT24C02读写操做

1.经过以上几种信号的组合,能够向AT24C02指定单元地址写一字节的数据,能够看出,读写顺序为:起始,写器件地址,应答,写单元地址,应答,写数据,应答,终止。

程序实现:此函数无返回值,有两个形参, 内存单元地址,范围0-255;要写的数据,如0xfe;

1

2

3

4

5

6

7

8

9

10

11

void write_AT24C02(uchar unit_addr, uchar dat)

{

    start();

    write_byte(AT24C02_ADDR + 0);    //下一个字节为写,因此是+0

    ack();

    write_byte(unit_addr);

    ack();

    write_byte(dat);

    ack();

    end();

}

  

 2.从AT24C02任意单元地址读取数据,能够看出读写顺序为:起始,写器件地址+0(下一个字节为写),应答,写单元地址,应答,起始,写器件地址+1(下一个字节为读取),读取数据,终止。

 

具体程序实现:此函数有返回值,一个形参;单元地址,范围:0-255;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

uchar read_AT24C02(uchar unit_addr)

{

    uchar dat;

    /*先写数据*/

    start();

    write_byte(AT24C02_ADDR + 0);      //下一个字节为写

    ack();

    write_byte(unit_addr);

    ack();

    start();

    write_byte(AT24C02_ADDR + 1);       //下一个字节为读

    ack();

    dat = read_byte();

    end();

    return dat;

}

延时函数:

1

2

3

4

void delay()        //短暂5us延时

{

    ;;

}

  

IIC初始化:

复制代码

void I2C_init()                //初始化
{
    SDA = 1;   
    delay();
    SCL = 1;   
    delay();
}

复制代码

 

具体应用

有了以上几个函数,咱们就能够写主函数了, 功能是向内存单元211,写入数据0xae,而后在从内存单元211中读取出来,送给P1口led显示.注意:写完后要延时一会才能读取,不然不能成功读取.

1

2

3

4

5

6

7

void main()

{

    write_AT24C02(211, 0xae);

    delay_10ms();                       //写完后,必须延时必定的时间才能够读取,不然不行

    P1 = read_AT24C02(211);

    while(1);

}

总结

经过IIC 总线通讯协议的学习,能够看出,IIC总线用IO口模拟操做起来仍是很简单的,使用起来仍是比较方便的,并且还能够多个IIC器件挂接在一条总线上,只须要SDA和SCL两根线便可,固然也有缺点,因为是只有一根数据线,因此不能全双工传输,传输速度也有必定的限制.

 

相关文章
相关标签/搜索