24c02读写程序_第1页
24c02读写程序_第2页
24c02读写程序_第3页
24c02读写程序_第4页
24c02读写程序_第5页
已阅读5页,还剩29页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、E2PROM芯片24C02的读写程序 一、实验目的: 给24C02的内部RAM写入一组数据,数据从24C02内部RAM的01h开始存放。然后再把这组数据读出来,检验写入和读出是否正确。 在这里我们给24C02中写入0、1、2的段码,然后把它读出来,送到数码管显示。二、理论知识准备:上面两个实验主要学习的是利用单片机的串口进行通讯,本实验要介绍的是基于I2C总线的串行通讯方法,下面我们先介绍一下I2C总线的相关理论知识。(一)、I2C总线概念I2C总线是一种双向二线制总线,它的结构简单,可靠性和抗干扰性能好。目前很多公司都推出了基于I2C总线的外围器件,例如我们学习板上的24C02芯片,就是一个

2、带有I2C总线接口的E2PROM存储器,具有掉电记忆的功能,方便进行数据的长期保存。(二)、I2C总线结构I2C总线结构很简单,只有两条线,包括一条数据线(SDA)和一条串行时钟线(SCL)。具有I2C接口的器件可以通过这两根线接到总线上,进行相互之间的信息传递。连接到总线的器件具有不同的地址,CPU根据不同的地址进行识别,从而实现对硬件系统简单灵活的控制。一个典型的I2C总线应用系统的组成结构如下图所示(假设图中的微控制器、LCD驱动、E2PROM、ADC各器件都是具有I2C总线接口的器件):我们知道单片机串行通讯的发送和接收一般都各用一条线TXD和RXD,而I2C总线的数据线既可以发送也可

3、以接受,工作方式可以通过软件设置。所以,I2C总线结构的硬件结构非常简洁。当某器件向总线上发送信息时,它就是发送器,而当其从总线上接收信息时,又成为接收器。(三)、I2C总线上的数据传送下面我们看看I2C总线是如何进行数据传送的。我们知道,在一根数据线上传送数据时必须一位一位的进行,所以我们首先研究位传送。1、位传输I2C总线每传送一位数据必须有一个时钟脉冲。被传送的数据在时钟SCL的高电平期间保持稳定,只有在SCL低电平期间才能够改变,示意图如下图所示,在标准模式下,高低电平宽度必须不小于4.7us。那么是不是所有I2C总线中的信号都必须符合上述的有效性呢?只有两个例外,就是开始和停止信号。

4、开始信号:当SCL为高电平时,SDA发生从高到低的跳变,就定义为开始信号。停止信号:当SCL为高电平时,SDA发生从低到高的跳变,就定义为结束信号。开始和结束信号的时序图如下图所示:2、数据传输的字节格式SDA传送数据是以字节为单位进行的。每个字节必须是8位,但是传输的字节数量不受限制,首先传送的是数据的最高位。每次传送一个字节完毕,必须接收到从机发出的一个应答位,才能开始下一个字节的传输。如果没有接受到应答位,主机则产生一个停止条件结束本次的传送。那么从机应该发出什么信号算是产生了应答呢?这个过程是这样的。当主器件传送一个字节后,在第9个SCL时钟内置高SDA线,而从器件的响应信号将SDA拉

5、低,从而给出一个应答位。好啦,了解了I2C传输数据的格式,现在来研究双方传送的协议问题。3、 I2C数据传输协议I2C总线的数据传输协议如下:(1)、主器件发出开始信号(2)、主器件发出第一个字节,用来选通相应的从器件。其中前7位为地址码,第8位为方向位(R/W)。方向位为“0”表示发送,方向位为“1”表示接受。(3)、从机产生应答信号,进入下一个传送周期,如果从器件没有给出应答信号,此时主器件产生一个结束信号使得传送结束,传送数据无效。(4)、接下来主、从器件正式进行数据的传送,这时在I2C总线上每次传送的数据字节数不限,但每一个字节必须为8位(传送的时候先送高位,再送低位)。当一个字节传送

6、完毕时,再发送一个应答位(第9位),如上一条所述,这样每次传送一个字节都需要9个时钟脉冲。数据的传送过程如下图所示:(四)、24C02芯片相关介绍AT24C02是带有I2C总线接口的E2PROM存储器,具有掉电记忆的功能,并且可以象普通RAM一样用程序改写。它的容量是256个字节(00h0ffh),有A2、A1、A0三位地址,可见I2C总线上可以连接8片AT24C02,它的寻址字节是1010 A2A1A0 R/W。板上面24C02的电路连接如图所示:我们对引脚的功能作一个简单的解释: VCC,GND:电源、地引脚 A2A1A0:地址引脚 SCLK、SDA:通信引脚 WP:写保护引脚从上面的电路

7、连接知:A2A1A0=000,可见如果要对24C02进行写操作,寻址字节是1010 000 0;如果对24C02进行读操作,寻址字节是1010 000 1。用单片机的P1.6脚作为串行时钟线,用P1.7脚作串行数据线。(五)、程序分析 写过程:(1)、主机首先发出开始信号(2)、发出写24C02的寻址字节1010 000 0,即0A0H(3)、发数据写入24C02的地址,本例中为01H(4)、往24C02中写入数据,这里是3个字节,分别为48h,0ebh,52h。(5)、写完毕发出停止信号 读过程:(1)、主机发出start信号(2)、发写24C02的寻址字节1010 000 0(大家可能要问

8、:我们是读数据,为什么要发写信号呢?这是因为你首先要送出一个信号,说明从24C02中的哪个地址读取数据。)(3)、发要读取的数据在24C02中的地址,即01h(4)、主机发start信号(5)、发读24C02的寻址字节1010 000 1(5)、从24 C02中读取数据(6)、读取完毕发出停止信号在这个程序中,我们把开始信号,结束信号、写一个字节数据、读一个字节数据都编制成为通用的子程序,便于在程序中随时调用。发送和接受应答位的过程放到子程序中,这样可以使得程序结构简化。具体的程序如下所示,希望大家认真理解。三、实验程序Org 0000hI2cdata equ 30h ;发送数据缓冲区的首址2

9、402data equ 01h ;接受缓冲区首址numdata equ 03h ;传送的字节数,传送3个字节Sda bit p1.7Sclbit p1.6Ajmp mainMain: Lcall init ;初始化给30h,31h,32h中存入0,1,2的段码Mainwr:Lcall start ;启动 Mov r7,#0a0h Lcall send ;发送写24C02的寻址字节 Mov r7,#2402data Lcall send ;发送数据存入24C02的地址 Mov r5,#Numdata ;欲发送的字节数 Mov r0,#i2cdata ;发送缓冲区的首址wrloop:Mov a,r

10、0 Mov r7,a Inc r0 Lcall send Djnz r5, wrloop ;把3个字节的数据发送出去 lcall stop ;停止 lcall d1s mov r5,#Numdata ; 要读取的字节数重新赋值Mainre:lcall start ;启动 Mov r7,#0a0h Lcall send ;发送写24C02的寻址字节 Mov r7,#2402data Lcall send ;发接受缓冲区首址 Lcall start ; 再次启动 Mov r7,#0a1h Lcall send ;发送读24C02的寻址字节Reloop: Lcall read ;调用读取一个字节数据

11、的子程序 mov p0,r7 ;把读进来的数送到p0口显示 lcall d1s lcall d1s Djnz r5,reloop Lcall stop ;3字节读取完毕发出停止信号 Ajmp $init: mov p2,#0ffh ;初始化,30h、31h、32h中存入0、1、2的段码 mov 30h,#48h mov 31h,#0ebh mov 32h,#52h retstart:setb sda ;启动信号子程序,大家可以参考开始信号的时序图 setb scl lcall d5u clr sda lcall d5u clr scl retstop:clr sda ;停止信号子程序 setb

12、 scllcall d5u setb sda lcall d5u clr sda clr scl ret;send是发送一个字节子程序send: mov r6,#08h mov a,r7 ;要发送的数在r7中sendlop1 : rlc a ;左环移,把A的最高位移入cy mov sda,c ;把cy的值通过sda发送出去 setb scl ;在scl上产生一个时钟 lcall d5u clr scl djnz r6, sendlop1 ;重复8次,发送一个字节;cack是检查应答信号的子程序cack:setb sda ;主机首先拉高sda setb scl ;发出一个时钟 lcall d5u

13、sendlop2:mov c,sda ;读入sda的状态,如果是0表示接受到了应答 jc sendlop2clr scl ;接受到应答位,结束时钟retread: mov r6,#08h ;读取一个字节子程序readlop1: setb sda ;置sda为输入方式 setb scl ;发出一个时钟 lcall d5u mov c,sda ;读入sda状态 rlc a ;把该位的状态移入A中 clr scl ;结束时钟 djnz r6,readlop1 ;重复8次,读入一个字节 mov r7,a ;读进来的数放在r7中;sack是发送应答位子程序sack:clr sda ;拉低sda线 set

14、b scl ;发出时钟信号 lcall d5u clr scl setb sda retd5u: nop ;延时5us子程序 nop nop nop nop retd1s: mov r1,#100 ;延时1s子程序del1: mov r4,#20del2: mov r3,#0ffhdel3: djnz r3,del3 djnz r4,del2 djnz r1,del1 ret end大家把这个程序下载到测试板上面,发现数码管依次显示数字0、1、2;简洁的24C02读写汇编程序;- I2C_SDA EQU P1.6 ; PIN 5 I2C_SCL EQU P1.7 ; PIN 6 ;= I2C_

15、WRITE: ; WRITE 8 BYTES TO EEROM ; INPUT: A - A*8 = EEROM START ADDR ; R0 - RAN START ADDR ; USE: C, A, R0, R6, R7 ACALL I2C_START ACALL OUT MOV R6, #8 WR_LP:MOV A, R0 ACALL OUT INC R0 DJNZ R6, WR_LP AJMP I2C_STOP ;= I2C_READ: ; READ 8 BYTES FROM EEROM ; INPUT: A - A*8 = EEROM START ADDR ;R0 - RAN ST

16、ART ADDR ;USE: C, A, R0, R6, R7 ACALL I2C_START ACALL OUT MOV R6, #8 MOV A, #0A1H; #RDCMD ACALL OUTS BRDLP: MOV R7, #8 SETB I2C_SDA INLP: CLR I2C_SCL ACALL DELAY6 SETB I2C_SCL NOP MOV C, I2C_SDA RLC A DJNZ R7, INLP CLR I2C_SCL MOV R0, A INC R0 DJNZ R6, ACKLP ;- I2C_STOP: CLR I2C_SDA ACALL DELAY5 SET

17、B I2C_SCL ACALL DELAY5 SETB I2C_SDA DELAY6: NOP DELAY5: NOP RET ;- I2C_START: SWAP A RR A MOV R6, A MOV A, #0A0H; #WTCMD ACALL OUTS MOV A, R6 RET ;- ACKLP: CLR I2C_SDA SETB I2C_SCL ACALL DELAY5 CLR I2C_SCL AJMP BRDLP ;= OUTS: SETB I2C_SDA SETB I2C_SCL ACALL DELAY5 CLR I2C_SDA ACALL DELAY5 CLR I2C_SC

18、L ;= OUT: SETB C MOV R7, #9 OTLP: RLC A NOP MOV I2C_SDA, C NOP NOP SETB I2C_SCL ACALL DELAY5 CLR I2C_SCL DJNZ R7, OTLP RET ;= END;SDA EQU P1.6 ;(你可以根据你的情况变更引脚) ;SCL EQU P1.7 ;D15US,D1MS子程序分别为15uS和1mS延时程序,请根据你的晶体自行编写。 ;* ;24C01写初始.(传递的数据在R7中). ;* sda bit p1.7 scl bit p1.6 org 0000 ajmp star org 00040

19、 star: mov p3,#00H mov 30H,#01H mov 31h,#88h nop nop nop acall at2401w nop nop nop nop nop ajmp $ AT2401W: MOV P1,#0FFH ;置SDA/SCL=1 LCALL R2STAR ;写开始状态字 MOV R7,#10100000B ;SET 2401=写 LCALL R2SEND ;送 MOV ACC,30H ;30H指向2401数据的起始地址 MOV R7,ACC ;将要写2401的起始地址送到R7 LCALL R2SEND MOV ACC,31H ;取第一个号 MOV R7,ACC

20、 ;数据传递到R7 LCALL R2SEND ;写具体号码 LCALL R2STOP ;停止 LCALL D1MS ;等待一定时间使24C01内部写完成 RET ;- ;写到2401 本程序开始及结束SDA & SCL 均=0 ,发送数据在R7 ;- R2SEND: PUSH ACC ;保存ACC MOV ACC,R7 ;将R7中的数发送出去 MOV R6,#08H ;往2401发送数据 R2SLOP1: RLC A ;将ACC中的数据移到数据线上 MOV SDA,C ;送出数据 LCALL D15US SETB SCL ;发送串行时钟进行写操作 LCALL D15US CLR SCL DJN

21、Z R6,R2SLOP1 ;串行发送8 BIT SETB SDA ;准备接收ACK LCALL D15US SETB SCL ;接收ACK的时钟 LCALL D15US R2SLOP2: MOV C,SDA ;写完后等待确认信号 ACK JC R2SLOP2 CLR SCL ;为下一步其它操作做准备 CLR SDA POP ACC ;还原ACC LCALL D1MS ;等待内部写完 RET ;* ;2401读初始. ;- AT2401RC: LCALL R2STAR ;写状态字 MOV R7,#10100000B ;SET 2401=WRI LCALL R2SEND ;送出状态字 MOV A,

22、30H ;上程序传来的读取地址 MOV R7,A ;地址数据送R7 LCALL R2SEND ;送出数据 MOV P1,#11111111B ;保证SDA/SCL起始=1 LCALL R2STAR MOV R7,#10100001B ;0A1H ;读状态 LCALL R2SEND LCALL R2READ ;读所需的数 LCALL R2STOP RET ;* ;设置开始 ,初始SDA &SCL=1,结束 SDA & SCL=0 ;- R2STAR: LCALL D15US ;对2401操作开始 CLR SDA ;在SCL=1时,SDA由1变为0表示开始 LCALL D15US CLR SCL

23、LCALL D15US RET ;- ;读取2401数据 ;- R2READ: PUSH ACC ;保存ACC MOV R6,#08H R2RLOP1: SETB SDA ;置数据线=1 LCALL D15US SETB SCL ;输出一个串行时钟 LCALL D15US MOV C,SDA ;读数据线上的数据到 C RLC A ;移到 ACC LCALL D15US CLR SCL DJNZ R6,R2RLOP1 ;读 8 BIT 数据 LCALL D15US CLR SDA MOV R7,ACC ;将接收到的数据保存到R7 POP ACC ;还原ACC RET ;- ;设置结束 在SEND

24、 & READ 后DSA & SCL均=0 ,本程序退出后 SDA & SCL=1 ;- R2STOP: LCALL D15US ;对2401操作结束 SETB SCL ;在SCL=1时,SDA由0变为1表示结束 LCALL D15US SETB SDA LCALL D15US RET d1ms: mov r2,#0F8h a_1: djnz r2,a_1 nop ret d15us: mov r3,#0fh b_1: djnz r3,B_1 ret 上面的程序是把C51,31H的88数写在24CXX的01地址上, 用的是6M的晶体,用P1。7=SDA数据线 P1。6是SCL时钟线;=;24c

25、02的读写程序;AUTHOR:LIXIN;CREATE DATE:2004-5-23;MODIFY DATE :2004-5-23;电协资料001.DOC;用于2号板; =BITCNT EQU 41HSUBADR EQU 40HSDA BIT P0.5SCL BIT P0.4ORG 00HJMP MAINORG 0100HMAIN: MOV R7,#01010101B ACALL WRITE_24C02 ACALL DELAY ACALL READ_24C02 ;MOV P2,A MOV P3,A ACALL DELAY ;MOV P2,#0FFH MOV P3,#0FFH ACALL DEL

26、AY JMP MAIN;=DELAY: MOV R0,#0FFHDELAY0: MOV R1,#0FFHDELAY1: NOP NOP NOP DJNZ R1,DELAY1 DJNZ R0,DELAY0 RET;=WRITE_24C02: ACALL START ;发送IC总线起始条件 MOV A,#0A0H ;24C02总线地址 ACALL SENTBYTE ;发送24C02器件总线地址 JB F0,SENDRETURN ;出错返回 MOV A,SUBADR ;取存储地址 ACALL SENTBYTE JB F0,SENDRETURN MOV A,R7 ACALL SENTBYTE ;发送一

27、次数据 JB F0,SENDRETURN ;出错返回 ACALL STOP ;发送IC总线停止条件DELAY10: ;延时10MS等待数据写完 MOV 44H,30HD1: MOV 45H,#34H DJNZ 45H,$ DJNZ 44H,D1SENDRETURN:RET;=READ_24C02: ;读24C02 ACALL START ;发送IC总线起始条件 MOV A,#0A0H ACALL SENTBYTE ;24C02总线地址 JB F0,RCVRETURN ;出错返回 MOV A,SUBADR ;取存储地址 ACALL SENTBYTE ;发送24C02器件总线地址 JB F0,SE

28、NDRETURN ;出错返回 ACALL START ;发送IC总线重复起始条件 MOV A,#0A0H ;24C02总线地址 SETB ACC.0 ;取总线读操作数 ACALL SENTBYTE ;发送被控制总线地址 JB F0,RCVRETURN ;出错返回 ACALL RCVBYTE ;接受数据RCVRETURN:RET;=START: SETB SDA ;发送起始条件的数据信号 NOP NOP NOP SETB SCL ;发送起始条件的时钟信号 NOP ;起始条件建立时间大于4.7s NOP NOP CLR SDA ;发送起始信号 NOP ;起始条件锁定时间大于4s NOP NOP C

29、LR SCL ; 钳住IC总线准备发送或接受数据 RET;=STOP: CLR SDA ;发送停止条件的数据信号 NOP NOP NOP SETB SCL ;发送停止条件的时钟信号 NOP ;起始条件建立时间大于4s NOP NOP SETB SDA ;发送IC总线停止信号 NOP NOP NOP NOP RET;=SENTBYTE: ;送数8位 MOV BITCNT,#08HSENTB: RLC A ;要发送的数据左移,发送入位C MOV SDA,C NOP NOP NOP SETB SCL ;置时钟线为高,通知被控制开始接受数据位 NOP ;保证时钟高周期大于4s NOP NOP CLR

30、SCL ;钳住总线准备接受下一个数据位 DJNZ BITCNT,SENTB ;8位没发送完继续发送 NOP NOP SETB SDA ;8位发送完后释放数据线准备收应答位 NOP NOP SETB SCL ;开始接受应答信号 NOP NOP CLR F0 ;预先清发送数据出错标志 JNB SDA,ACKEND ;判断是否接受应答信号正常转ACKEND SETB F0 ;未受到应答置位错误标志ACKEND: NOP CLR SCL ;发送结束钳住总线准备下一步发送或接受数据或进行其他处理 RET;=RCVBYTE: SETB SDA ;置数据线为输入方式 MOV BITCNT,#08H ;要传送

31、的数据长度为8位RCV: NOP CLR SCL ;置时钟线为低,准备接受数据 NOP ;时钟低周期大于4.7s NOP NOP NOP NOP SETB SCL ;置时钟线为高使数据线上数据有效 NOP NOP MOV C,SDA RLC A ;接受的数据位放入ACC NOP NOP DJNZ BITCNT,RCV ;8位没收完继续接受 CLR SCL ;8位接受完置时钟线和数据线 NOP NOP CLR SDA SETB SDA ;接受非应答信号 NOP NOP SETB SCL ;置时钟线为高使应答位有效 NOP ;时钟高周期大于4.7s NOP SETB SDA NOP NOP NOP

32、 CLR SCL ;清时钟线钳住IC总线以便发送停止条件 RET END;这是将0600H地址中以下的8个数据写到24C02的01H为首址单元中去的汇编程序 转自电子制作ORG0000HSCLBITP3.4;定义24C02的串行时钟线SDABITP3.5;定义24C02的串行数据线LJMPSTARTSTART:LCALLSTAR;调用MOVR2,#08H;一个数据有8位MOVDPTR,#0600H;定义源数据的位置LOOP:MOVA,#00HMOVCA,A+DPTRLCALLSDATALCALLACKJCLOOPINCDPTRDJNZR2,LOOPLCALLSTOP;调用停止子程序STAR:SETBSDASETBSCLNOPNOPNOPNOPCLRSDANOPNOPNOPNOPCLRSCLRETSDATA:MOVR0,#08HLOOP0:RLCAMOVSDA,CNOPNOPSETBSCLNOPNOPNOPNOPCLRSCLDJNZR0,LOOP0RETACK:SETBSDANOPNOPSETBSCLNOPNOPNOPNOPMOVC,SDACLRSCLRETSTOP:CLRSDANOPNOPNOPNOPSETBSCLNOPNOPNOPNOPSETBSDANOPNOPNOPNOPRET

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论