您的位置 首页 FPGA

I2C 24LC02 C读写例程(PIC单片机)

1I2C总线特点I2C总线最主要的优点是其简单性和有效性。由于接口直接在组件之上,因此I2C总线占用的空间非常小,减少了电路板的空间和芯…

1 I2C总线特色

I2C总线最主要的长处是其简单性和有用性。因为接口直接在组件之上,因而I2C总线占用的空间十分小,减少了电路板的空间和芯片管脚的数量,降低了互联本钱。总线的长度可高达25英尺,而且能够以10Kbps的最大传输速率支撑40个组件。I2C总线的另一个长处是,它支撑多主控(multimastering), 其间任何能够进行发送和接纳的设备都能够成为主总线。一个主控能够操控信号的传输和时钟频率。当然,在任何时刻点上只能有一个主控。

2 I2C总线作业原理

I2C总线上的数据安稳规矩,SCL为高电平时SDA上的数据保持安稳,SCL为低电平时答应SDA改动。假如SCL处于高电平时,SDA上发生下降沿,则认为是开端位,SDA上的上升沿认为是中止位。通讯速率分为惯例形式(时钟频率100kHz)和快速形式(时钟频率400kHz)。同一总线上能够衔接多个带有I2C接口的器材,每个器材都有一个仅有的地址,既能够是单接纳的器材,也能够是能够接纳发送的器材。

每次数据传输都是以一个开端位开端,而以中止位完毕。传输的字节数没有约束。最高有用位将首要被传输,接纳方收到第8位数据后会宣布应对位。数据传输一般分为两种:主设备发送从设备接纳和从设备发送主设备接纳。这两种形式都需求主机发送开端位和中止位,应对位由接纳方发生。从设备地址一般是1或2个字节,用于区别衔接在同一I2C上的不同器材。

I2C总线在传送数据进程中共有三种类型信号, 它们分别是:开端信号、完毕信号和应对信号。

开端信号:SCL为高电平时,SDA由高电平向低电平跳变,开端传送数据。

完毕信号:SCL为高电平时,SDA由低电平向高电平跳变,完毕传送数据。

应对信号:接纳数据的IC在接纳到8bit数据后,向发送数据的IC宣布特定的低电平脉冲,表明已收到数据。CPU向受控单元宣布一个信号后,等候受控单元宣布一个应对信号,CPU接纳到应对信号后,依据实际情况作出是否持续传递信号的判别。若未收到应对信号,由判别为受控单元呈现毛病。

在I2C总线中只有主发送和主接纳两种操作办法。在体系初始化时,由指令操控CPU送出相关的数据,经接口送到I2C寄存器内。经过初始化这些寄存器,能够完成I2C总线的主形式操控,以及完成I2C总线上的从设备读写。

当主设备和其间的一个从设备交流数据时,主设备首要宣布一个发动Start信号,这个信号被一切的从设备接纳。即从设备预备接纳CPU的信号,然后主设备再宣布它要通讯的从设备地址。接下来,一切的从设备将收到的这个地址和它们自己的地址进行比较。

假如收到的地址和它们自己的地址不同,则什么都不做,仅仅等候主设备宣布中止stop信号;假如收到的地址和它自己的地址相同,它就宣布一个信号给主设备,这个信号称为应对Acknowledge信号。当主设备收到应对信号后,它就开端向从设备发送数据或许从从设备接纳数据。当一切操作都进行完毕时,主设备宣布一个Stop信号,通讯完毕,开释I2C总线;然后一切的从设备都等候下一次Start信号的到来。

3 总线根本操作

I2C规程运用主/从双向通讯。器材发送数据到总线上,则界说为发送器,器材接纳数据则界说为接纳器。主器材和从器材都能够作业于接纳和发送状况。 总线有必要由主器材(一般为微操控器)操控,主器材发生串行时钟(SCL)操控总线的传输方向,并发生开端和中止条件。SDA线上的数据状况仅在SCL为低电平的期间才干改动,SCL为高电平的期间,SDA状况的改动被用来表明开端和中止条件。

3.1 操控字节

在开端条件之后,有必要是器材的操控字节,其间高四位为器材类型辨认符(不同的芯片类型有不同的界说,EEPROM一般应为1010),接着三位为片选,最终一位为读写位,当为1时为读操作,为0时为写操作。

1.写进程

(1)上电后等候一个延时(1ms)。

(2)器材寻址,给一个开端信号(SCL为高电平时SDA给一个下降沿)。发送从器材地址,高5位为10110,然后依据A1/A0(假如和器材的地址相同则那个器材会应对)进行读/写操控(O为读)。

(3)应对,器材在SCL的第9个周期时SDA给出一个低电平,作为应对信号。

(4)开端写有两种形式:字节写形式和页写形式。

·字节形式:给出A15~A8应对,给出A7~A0应对;然后给出DATA和中止信号 (SCL为高电平时,SDA给出一个上升沿),接着要等候一个擦写时刻。

·页写形式:给出地址今后接连给出64个数据。假如多于64个数据,则地址计数器主动翻转。(假如少于64昵,估量是没有问题的,可是需求试验验证。)

(5)判别擦写操作是否完毕的一个办法(应对查询),假如器材还处于擦写状况,则不会应对器材寻址;假如有应对,则阐明擦写完毕。

2.读进程

(1)上电今后等候一个延时(lms)。

(2)器材寻址。

(3)应对。

(4)开端读有三种形式:当即当时地址读、挑选/随机读、接连读。

·当即当时地址读:假如前次读/写的操作地址为N,则现在是N+1。不需求ACK,可是需求Stop信号。

·挑选/随机读:先伪写(用于给出一个地址),然后再次发动,读取数据。

·接连读:读取一个今后给一个应对,这样器材会再给出下一个地址的数据内容。

(5)开端数据传输Start后、中止数据传输Stop前,SCL高电平期间,SDA上为有用数据。

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

一、程序阐明:

1, 24LC02器材地址是1010000R/W.

2, 数组写入24LC02采纳页写办法.

3, 数组code从24LC02读出时采纳自在读办法.

4, 选用4.00M晶体。

5,选用软件I2C。

二、硬件衔接:

1, SDA——->23 pin.(当然你能够恣意挑选脚位)

2, SCL——->18 Pin.(当然你能够恣意挑选脚位)

3, PORTD—–>外接8个LED,显现读出的数据,在这里,读出的刚好是一个闪烁的流水灯状况。

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

#i nclude “pic.h”

#define uchar unsigned char

#define nop() asm(“nop”

#define SCL TRISC3

#define SDA TRISC4

void start_i2c();

void stop_i2c();

void send_byte(uchar c);

uchar receive_byte();

void I_send_str(uchar sla,uchar suba,uchar *s,uchar no);

void delay_250ms();

void i2c_error ();

uchar code[]={0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff};

uchar no,ack,c,data;

void main(void)

{

uchar i;

TRISC=0Xff; //C口设为输入 RC3为SCL线,RC4为SDA线。

PORTC=0X00;

TRISD=0X00; //D口为输出,显现IC24LC02中读出的内容

PORTD=0X00; //初始显现全亮

I_send_str(0xa0,0x00,code,9); //页写入code数组到24LC02,器材地址为0Xa0,子地址为0X00,共9个数。

delay_250ms();

///////////开端读出到D口进行显现,依据Random read时序图。

while (1)

{

for (i=0x00;i<0x09;i++)

{

start_i2c();

send_byte(0xa0); //发送器材地址,即DEVICE ADDRESS。

if (ack==0) i2c_error(); //假如24LC02无应对。则进入I2C ERROR过错指示。

send_byte(i); //发送字地址,即WORD ADDRESS。D口显现数组。

if (ack==0) i2c_error();

start_i2c(); //重新发动总线。

send_byte(0xa1); //发送读指令和器材地址DEVICE ADDRESS。

if (ack==0) i2c_error();

data=receive_byte();

stop_i2c();

PORTD=data;

delay_250ms();

}

}

}

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

起动总线函数

函数原型: void start_i2c();

Function: start on the I2C bus

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

void start_i2c()

{

SDA=1; //发送启始条件的数据信号

nop();

SCL=1;

nop();nop();nop();nop();nop(); //24LC02要求树立时刻大于4,7S

SDA=0; //发送开端信号

nop();nop();nop();nop();nop();

SCL=0; //钳住I2C总线,预备发送数据或接纳数据

nop();nop();

}

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

中止总线函数

函数原型: void stop_i2c();

Function: stop the I2C bus

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

void stop_i2c()

{

SDA=0; //发送完毕条件的数据信号

nop();

SCL=1;

nop();nop();nop();nop();nop();

SDA=1;

nop();nop();nop();nop();

}

/*=================================================================

字节数据传送函数

函数原型: void send_byte(uchar c);

Function: 将数据C发送出去,能够是地址,也能够是数据,发完后等候回应,并对此状况

位进行操作(不应对或非应对都使ack=0 ),发送数据正常,ack=1;ack=0

表明被控器无应对或损坏。

==================================================================*/

void send_byte(uchar c)

{

uchar bit_count;

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

{

if ((c<

else {SDA=0;}

nop();

SCL=1;

nop();nop();nop();nop();nop();

SCL=0;

}

nop();nop();

SDA=1;

nop();nop();

SCL=1;

nop();nop();nop();

if (RC4==1) ack=0;

else ack=1; //用ASK=1为有应对信号

SCL=0;

nop();nop();

}

/*==================================================================

字节数据接纳函数

函数原型:uchar receive_byte();

FUNCTION: 用来接纳从器材传来的数据,并判别总线过错(不发应对信号),

发完后请用应对函数。

===================================================================*/

uchar receive_byte()

{

uchar retc,bit_count;

retc=0;

SDA=1;

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

{

nop();

SCL=0;

nop();nop();nop();nop();nop();

SCL=1;

nop();nop();

retc=retc<<1;

if (RC4==1) retc=retc+1;

nop();nop();

}

SCL=0;

nop();nop();

return (retc);

}

/*================================================================

向有子地址器材发送多字节数据函数

函数原型: bit I_send_str(uchar sla,uchar suba,uchar *s,uchar no);

Function: 从发动总线到发送地址,数据,完毕总线的全进程,从器材地址sla。假如

回来1表明操作成功,不然操作有误。

=================================================================*/

void I_send_str(uchar sla,uchar suba,uchar *s,uchar no)

{

uchar i;

start_i2c();

send_byte(sla);

if (ack==0) i2c_error();

send_byte(suba);

if (ack==0) i2c_error();

for (i=0;i

{

send_byte(*s);

if (ack==0) i2c_error();

s++;

}

stop_i2c();

// return(1);

}

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

延时函数

函数原型: void delay_250ms();

FUNCTION: 延明250ms

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

void delay_250ms()

{

unsigned int d=24999;

while (–d);

}

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

总线过错函数

函数原型: void i2c_error();

Function: 经过RD7闪烁8次表明总线操作失利一次报警。

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

void i2c_error ()

{

uchar i;

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

{

RD7=0;

delay_250ms();

RD7=1;

delay_250ms();

}

}

/**********END**************/

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/fangan/fpga/272850.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部