电工技术基础_电工基础知识_电工之家-电工学习网

欢迎来到电工学习网!

IIC总线协议剖析存储芯片at24c64

2017-09-08 15:36分类:电子技术 阅读:

 

前语:年前给教师做个红外抄表体系,,如今对当顶用到的一些模块总结一下.

1.只需在总线闲暇时才容许主张数据传送.

2.在数据传送进程中,其时钟线为高电往常,数据线有必要坚持安稳状况,不容许有跳变.时钟线为高电往常,数据线的任何电平改动将被看做总线的开端或接连信号.

3. 任何将数据传送到总线的器材作为发送器任何从总线接纳数据的器材为接纳器, 主器材和从器材都可以作为发送器或接纳器但由主器材操控传送数据.
4.有两根数据线:

SDA : IIC数据传送位
SCL : IIC 时钟操控位
下面临IIC的底层驱动加以阐明,并给出汇编和C言语的代码,以AT24C64为例.在这之前先界说一些常量和公共代码:

汇编:

SDA BIT P3.4 ;数据端
SCL BIT P3.5 ;时钟端

DELAY : NOP ;延时子程序,依据单片机的晶振纷歧样,延时长短略有纷歧样
NOP ;12MHZ晶振
NOP

NOP

NOP

NOP

RET
C言语:
  sbit SDA = P3.4;

sbit SCL = P3.5;

void delay(void) //延时子程序
{

unsigned char i;

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

}

开端信号:

时钟线坚持高电往常期,数据线电平从高到低的跳变作为IIC总线的开端信号.

汇编:

IIC_ST: ;IIC开端代码
LCALL DELAY

CLR SCL

LCALL DELAY

LCALL DELAY

SETB SDA

LCALL DELAY

LCALL DELAY

SETB SCL

LCALL DELAY

LCALL DELAY

CLR SDA

LCALL DELAY

LCALL DELAY

CLR SCL

LCALL DELAY

RET

C言语:

void iic_start(void)

{

SCL=0;

delay();

SDA=1;

delay();

SCL=1;

delay();

SDA=0;

delay();

SCL=0;

delay();

}

接连信号:

时钟线坚持高电往常期,数据线电平从低变高.

汇编:

IIC_SP:

LCALL DELAY

CLR SCL

LCALL DELAY

LCALL DELAY

CLR SDA

LCALL DELAY

LCALL DELAY

SETB SCL

LCALL DELAY

LCALL DELAY

SETB SDA

LCALL DELAY

RET

C言语:

void iic_stop(void)

{

delay();

SCL=0;

delay();

SDA=0;

delay();

SCL=1

delay();

SDA=1;

delay();

}

器材寻址:

首要发送一个开端信号,主张发送进程,然后发送它所需求的寻址的从器材的地址.8从位器材地址的高4位固定为1010,接下来的三位为器材的地址位,最低一位作为读写操控位.

1: 标明从器材进行读;

0: 标明对器材进行写.

应对信号:

IIC总线数据传送时,每成功的传送一个字节数据后,接纳器都有必要发作一个应对信号.应对的器材在第九个时钟周期时将SDA拉低,标明收到一个8位数据.

写操作:(字节办法)

主器材发送开端信号和从器材地址信息(R/W位清0)给从器材,在从器材送答复对信号后,主器材发送两个8位地址字写入从器材的地址指针,主器材在收到从器材的应对信号后,再发送数据到到被寻址的从器材存储单元,从器材再次应对,并在主器材发作接连信号后开端内部数据的擦写.

汇编:

;##############写数据到at24c64-ATW2##############

;阐明:写一字节数据到at24c64,失利PSW.5置1

;进口参数:A

;出口参数:无
;###############################################

IIC_WB:

MOV R2,#8

CLR SCL

J4: RLC A

LCALL DELAY

LCALL DELAY

MOV SDA,C

LCALL DELAY

LCALL DELAY

SETB SCL

LCALL DELAY

LCALL DELAY

CLR SCL

DJNZ R2,J4

SETB SDA

LCALL DELAY

LCALL DELAY

SETB SCL ;第九个时钟周期
LCALL DELAY

LCALL DELAY

JB SDA,J1 ;正常状况下,第九个时钟周期收到的SDA应为低
CLR SCL ;开释总线
LCALL DELAY

LCALL DELAY

CLR PSW.5 ;接纳成功
LJMP edw

J1: CLR SCL ;开释总线
SETB PSW.5 ;接纳失利
edw: RET

C言语:

void iic_write_byte(unsigned char w_byte)

{

unsigned char i;

SCL=0;

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

{

delay();

if((w_byte<<i)&0x80)

SDA=1;

else

SDA=0;

delay();

SCL=1;

delay();

SCL=0;

}

SDA=1;

delay();

SCL=1; //第九个时钟周期
delay();

if(SDA==1) //正常状况下,第九个时钟周期时,收到的SDA应当为低电平
{ //写入犯错
SCL=0;

PSW.5=1; //犯错象征
}

else

{ //写入成功
SCL=0;

PSW.5=0; //成功象征
}

}

读操作:

读操作的初始化办法和写操作相同,仅把R/W方位1.

读操作的品种:

1. 当即/其时地址读(本例未用)

2. 挑选/随机读: 容许对恣意字节进行读,首要发送开端信号,从器材地址和它想读的字节数数据地址,施行一个伪写操作,在AT24C64应对往后,主器材从头发送开端信号和从器材地址,此刻R/W方位1.AT24C64照顾并发送应对信号,然后输出所恳求的一个8位字节数据.主器材不发送应对信号但发作一个接连信号.

汇编1:

;/** 单字节读 **/

;读出的一个字节寄存在A中
IIC_RB:

CLR A

CLR C

LCALL DELAY

LCALL DELAY

CLR SCL

LCALL DELAY

LCALL DELAY

MOV R2,#8

J5: SETB SCL

LCALL DELAY

LCALL DELAY

MOV C,SDA

RLC A

LCALL DELAY

LCALL DELAY

CLR SCL

LCALL DELAY

LCALL DELAY

DJNZ R2,J5

CLR SDA

LCALL DELAY

LCALL DELAY

SETB SCL ;第九个时钟周期,应将SDA拉低作为应对信号
LCALL DELAY

LCALL DELAY

CLR SCL ;开释总线
LCALL DELAY

LCALL DELAY

SETB SDA

RET

汇编2:

;################序列读究竟一字节###############

;读究竟一字节时需求发送接连信号
IIC_RL:

CLR A

CLR C

LCALL DELAY

LCALL DELAY

CLR SCL

LCALL DELAY

LCALL DELAY

MOV R2,#8

J50: SETB SCL

LCALL DELAY

LCALL DELAY

MOV C,SDA

RLC A

LCALL DELAY

LCALL DELAY

CLR SCL

LCALL DELAY

LCALL DELAY

DJNZ R2,J50

SETB SDA

LCALL DELAY

LCALL DELAY

SETB SCL ;接连信号
LCALL DELAY

LCALL DELAY

RET

C言语1: 单字节读
unsigned char iic_read_byte(void)

{

unsigned char i,j=0;

delay();

SCL=0;

delay();

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

{

SCL=1;

delay();

j<<=1;

if(SDA==1)

j+=1;

delay();

SCL=0;

delay();

}

SDA=0;

delay();

SCL=1;

delay();

SCL=0;

delay();

SDA=1;

return j;

}

C言语2: 序列读究竟一字节
unsigned char iic_read_last_byte(void)

{

unsigned char I,j=0;

delay();

SCL=0;

delay();

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

{

SCL=1;

delay();

j<<=1;

if(SDA==1)

j+=1;

delay();

SCL=0;

delay();

}

SDA=1;

delay();

SCL=1; //接连信号
delay();

return j;

}

举例: 以AT公司出产的IIC器材EEPROM: at24c64为例,对该器材进行读写
1. 原理图

AT24C64器材简介:


2.将坐落R0(buf)所指向的地址单元中的COUNT(count)个数据写入AT24C64的ADDRH,ADDRL(addrh,dddrl)地址单元中.(括号内为c言语变量)

汇编:(会用到上面给出的IIC驱动子程序以及界说的一些变量和接口)

ADDRH EQU 13H

ADDRL EQU 14H ;界说读写AT24C64的首地址

STOR1: MOV COUNT,#4 ;写入的字节数
MOV ADDRH,#xx ; 写入到AT24C64的地址字
MOV ADDRL,#xx

LCALL WRDAT ;将坐落R0所指向的地址单元中的COUNT个数据写入
;AT24C64的ADDRH,ADDRL地址单元中

;###########悉数参数写入AT24C64,共4字节#################

;阐明:将表号和用户电量共四字节数据写入AT24C64中
;进口参数:

; 1.数据直接寻址地址-R0

; 2.写入到AT24C64的地址字-ADDRH,ADDRL

; 3.写入字节数-COUNT

;出口参数:无
;#######################################################

WRDAT: LCALL IIC_ST ;START

MOV A,#0A0H

LCALL IIC_WB ;写器材寻址00H(榜首片AT24C64) 将A中的字符发送
JB PSW.5,WRDAT

MOV A,ADDRH

LCALL IIC_WB

JB PSW.5,WRDAT

MOV A,ADDRL

LCALL IIC_WB ;存储单元地址
JB PSW.5,WRDAT

MOV R7,COUNT

WRDAT0: MOV A,@R0

LCALL IIC_WB ;写入数据
JB PSW.5,WRDAT

INC R0

DJNZ R7,WRDAT0

LCALL IIC_SP ;接连
LCALL DL20MS ;延时,等候将数据擦写到at24c64中
RET

C言语:

unsigned char count=0x04;

unsigned char addrh=0xxx;

unsigned char addrl=0xxx;

unsigned char t_buf[];

while(!write_byte(t_buf,addrh,addrl,count));

/*###########悉数参数写入AT24C64,共4字节#################

//阐明:将表号和用户电量共四字节数据写入AT24C64中
//进口参数:

; 1.数据直接寻址地址-buf

; 2.写入到AT24C64的地址字-addh,addrl

; 3.写入字节数-count

;出口参数:1标明写成功,0标明写失利
;#######################################################*/

bit write_byte(unsigned char * buf, //

unsigned char addrh,

unsigned char addrl,

unsigned char count)

{

unsigned char i;

iic_start(); //start

iic_write_byte(0x0a0); //写器材寻址0x00(榜首片at24c64)

if(PSW.5)

return 0;

iic_write_byte(addrh);

if(PSW.5)

return 0;

iic_write_byte(addrl);

if(PSW.5)

return 0;

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

{

iic_write_byte(*buf);

if(PSW.5)

return 0;

buf++;

}

iic_stop();

return 1;

}

2. 从at24c64的ADDRH,ADDRL(addrh,addrl)地址单元中读出COUNT(count)个数据寄存到单片机R0(buf)指定的地址单元中.(括号中为C言语变量)

汇编: (会用到上面给出的IIC驱动子程序以及界说的一些变量和接口)

ADDRH EQU 13H

ADDRL EQU 14H ;界说读写AT24C64的首地址

STOR1: MOV COUNT,#4 ;读收支的字节数
MOV ADDRH,#xx ; 读入的AT24C64的地址字
MOV ADDRL,#xx

LCALL LDDAT ; 从at24c64中读数据

;/*############从at24c64中读数据#########################

; 进口参数:

LDDAT: LCALL IIC_ST ;START

MOV A,#0A0H ;对器材进行写
LCALL IIC_WB ;虚写操作器材寻址00H(榜首片AT24C64)

JB PSW.5,LDDAT

MOV A,ADDRH

LCALL IIC_WB ;

JB PSW.5,LDDAT

MOV A,ADDRL

LCALL IIC_WB ;虚写存储单元地址
JB PSW.5,LDDAT

;以上为先初始化一个读数据地址
LCALL IIC_ST ;START

MOV A,#0A1H

LCALL IIC_WB ;读操作器材寻址00H(榜首片AT24C64)

JB PSW.5,LDDAT

MOV R7,COUNT

CJNE R7,#01,LD01

LJMP LDDAT1

LD01: DEC R7

LDDAT0: LCALL IIC_RB ;现行地址读(0000H)

MOV @R0,A

INC R0

DJNZ R7,LDDAT0

LDDAT1: LCALL IIC_RL ;读究竟一字节,读完后给AT24C64发接连信号
MOV @R0,A

inc r0

LCALL IIC_SP ;接连信号
RET

C言语:

unsigned char count=0x04;

unsigned char addrh=0xxx;

unsigned char addrl=0xxx;

unsigned char r_buf[];

while(!read_byte(r_buf,addrh,addrl,count));

/* */

bit read_byte(unsigned char *buf, //寄存读到的数据
unsigned char addrh,

unsigned char addrl, //要读的数据地址
unsigned char count) //需求读的个数
{

unsigned char i;

iic_start();

iic_write_byte(0x0a0); //对器材进行寻址,虚写操作器材 寻址00H(榜首片)

if(PSW.5)

return 0;

iic_write_byte(addrh); //虚写存储单元地址
if(PSW.5)

return 0;

iic_write_byte(addrl); //虚写存储单元地址
if(PSW.5)

return 0;

//以上为初始化一个读数据地址
iic_start(); //重发开端信号
iic_write_byte(0x0a1); //对器材读指令
if(PSW.5)

return 0;

if(count==1)

{

*buf=iic_read_last_byte();

buf++;

}

else

{

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

{

*buf=iic_read_byte();

buf++;

}

}

iic_stop();

return 1;

}

上一篇:抱负集成运放的条件

下一篇:TDK电容类型命名规矩

相关推荐

电工推荐

    电工技术基础_电工基础知识_电工之家-电工学习网
返回顶部