实验二 I2C存储器实验
- 格式:doc
- 大小:692.00 KB
- 文档页数:16
单片机汇编实验六:I2C串行总线存储器读写实验实验要求:由AT89S52 内部定时器1,按方式1 工作,每1 秒钟24C02的0001H 单元内容加2,以键盘作为外部中断输入信号,有键按下时,读取0001H 单元内容并由LED 显示。
//This is the sixthprogramof the homework;//Name :Wang Qi Date:2013/3/11 北京化工大学自实1001 SDA EQU P2.0 SCL EQU P2.1 ORG 0000H //主函数入口SJMP MAIN ORG 0013H //外部中断1 入口LJMP WZD0 ORG 001BH //计时器1 入口LJMP WT1 ORG 0050HMAIN: MOV SP,#60H MOV TMOD,#10H //设置T1 工作方式MOV TH1,#4CH //设初值MOV TL1,#00H MOV R7,#10 //计数器SETB EA //全局中断SETB ET1 //允许定时器1 SETB TR1 //启动定时器1 SETB IT1 //外部中断跳变触发方式SETB EX1 //允许外部中断1OK: MOV C,P3.4 //扫描键盘JNC OK1 MOV C,P3.5 JNC OK1 MOV C,P3.6 JNC OK1 MOV C,P3.7 JNC OK1 SJMP OKOK1: CLR P3.3 //中断信号SETB P3.3 SJMP OKWZD0: SETB P3.3 //中断程序PUSH TH1 //保护现场PUSH TL1CLR TR1 //停止T1 计数MOV R2,#01H CALL DU MOV P1,R3POP TL1POP TH1SETB TR1RETIWT1: MOV TH1,#4CH //定时函数MOV TL1,#00H DJNZ R7,RET0 MOV R7,#10 //1 秒到来了INC 30H INC 30H mov R2,#01H MOV R3,30H CALL XIERET0: RETI//////////////I2C 协议摘自网络Thanks to the authorXIE: //写数据子程序,R2 是要写入的24c02 的字节位置地址,R3 是要写入的内容LCALL STAR;起始条件MOV A,#10100000B //寻址24C02 的总线硬件地址并使用写入命令LCALL SDATA //传输数据A 给24C02MOV A,R2 //确定要写入的字节位置地址LCALL SDATA //传输数据A给24C02MOV A,R3 //把数据R3 写入刚指定的字节地址LCALL SDATA //传输数据A 给24C02LCALL STOP //写入结束LCALL CHULI //提供2ms 给24C02。
I2C 总线实验(实时时钟、EEPROM 和ZLG7290 的实验)一.实验目的加深用户对I2C 总线的理解,熟悉I2C 器件的使用,提供用户实际开发的能力。
二.实验设备及器件IBM PC 机一台DP-51PROC 单片机综合仿真实验仪一台三.实验内容进行I2C 总线控制的实时时钟、EEPROM、ZLG7290 键盘LED 控制器实验。
四.实验要求熟练掌握I2C 总线的控制,灵活运用I2C 主控器软件包,深刻理解实时时钟、EEPROM、ZLG7290 键盘LED 控制的各种功能。
五.实验步骤1.使用导线连接D5 区的SCL、SDA 到A2 区的P16、P17(SCL~P16、SDA~P17),连接D5 区的RST_L、INT_KEY 到A2 区的P10、INT0(RST_L~P10、INT_KEY~INT0),短接D5 区的JP1 跳线。
2.把模拟I2C 软件包“VIIC_C51.C”文件加入到Keil C51 的项目中,程序源文件的开头包含“VIIC_C51.H”头文件。
修改VIIC_C51.C 文件中的sbit SDA=P1^7;和sbit SCL=P1^6;。
图3.21 RTC原理图3.使用函数ISendStr(uchar sla,uchar suba,uchar *s,uchar no)对PCF8563T实时时钟进行设置初始时间,再使用IRcvStr(uchar sla,uchar suba,uchar*s,uchar no)对PCF8563T 实时时钟的时间进行读取。
EEPROM 原理图4.使用函数ISendStr(uchar sla,uchar suba,uchar *s,uchar no);对24WC02EEPROM 进行写入,再使用IRcvStr(uchar sla,uchar suba,uchar *s,uchar no);对24WC02 EEPROM 进行读取。
ZLG7290 原理图5.对ZLG7290 键盘LED 控制器的操作也同理,只是在程序开始的地方增加复位操作和程序中间增加查询是否有键按下。
任务二:I2C存储器读写(计数器,并能断电存储)实验原理1)I2C总线概述I2C总线是PHLIPS公司推出的一种串行总线,是具备多主机系统所需的包括总线裁决和高低速器件同步功能的高性能串行总线。
2)I2C信号线I2C总线只有两根双向信号线。
一根是数据线SDA,另一根是时钟线SCL。
I2C总线通过上拉电阻接正电源。
当总线空闲时,两根线均为高电平。
连到总线上的任一器件输出的低电平,都将使总线的信号变低,即各器件的SDA及SCL都是线“与”关系。
图 1 I2C总线框图3)I2C总线的数据传送a)数据位的有效性规定I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。
图 2 SDA与SCL的工作时序图b) 起始和终止信号SCL线为高电平期间,SDA线由高电平向低电平的变化表示起始信号SCL线为高电平期间,SDA线由低电平向高电平的变化表示终止信号。
起始和终止信号都是由主机发出的,在起始信号产生后,总线就处于被占用的状态;在终止信号产生后,总线就处于空闲状态。
c) I2C总线的数据传送速率I2C总线的通信速率受主机控制,能快能慢,最高速率限制为100Kb/sd) I2C总线的数据传送格式主机向从机发送数据从机向主机发送数据图 3 I2C总线的数据传送格式S:起始位SA: 从机地址,7位W/:写标志位,1位R:读标志位,1位A:应答位,1位A/:非应答位,1位D:数据,8位P:停止位阴影:主机产生的信号无阴影:从机产生的信号4)总线的寻址I2C总线协议有明确的规定:采用7位的寻址字节(寻址字节是起始信号后的第一个字节)。
寻址字节的位定义D7~D1位组成从机的地址。
D0位是数据传送方向位,为“0”时表示主机向从机写数据,为“1”时表示主机由从机读数据。
主机发送地址时,总线上的每个从机都将这7位地址码与自己的地址进行比较,如果相同,则认为自己正被主机寻址,根据R/位将自己确定为发送器或接收器。
I2C存储器实验实验目的1、了解I2C总线的工作原理2、掌握I2C总线驱动程序的设计和调试方法3、掌握I2C总线存储器的读写方法实验仪器单片机开发板、稳压电源、计算机实验原理1、 I2C总线常识I2C总线采用一个双线式漏极开路接口,可在一根总线上支持多个器件和主控器。
所连接的器件只会把总线拉至低电平,而决不会将其驱动至高电平。
总线在外部通过一个电流源或上拉电阻器连接至一个正电源电压。
当总线空闲时,两条线路均为高电平。
在标准模式中,I2C 总线上的数据传输速率高达100kbit/s,而在快速模式中则高达400kbit/s。
I2C总线上的每个器件均由一个存储于该器件中的唯一地址来识别,并可被用作一个发送器或接收器(视其功能而定)。
除了发送器和接收器之外,在执行数据传输时,还可把器件视作主控器或受控器。
主控器是负责启动总线上的数据传输并生成时钟信号以允许执行该传输的器件。
同时,任何被寻址的器件均被视作受控器。
CAT24WC01/02/04/08/16是一个1K/2K/4K/8K/16K位串行CMOS EEPROM,内部含有128/256/512/1024/2048个8位字节,CATALYST公司的先进CMOS技术实质上减少了器件的功耗,CAT24WC01有一个8字节页写缓冲器,CAT24WC02/04/08/16有一个16字节页写缓冲器,该器件通过I2C总线接口进行操作,有一个专门的写保护功能,并且器件能与400KHzI2C 总线兼容。
引脚名称和功能如图1所示。
图1 24系例I2C存储器引脚说明通过器件地址输入端A0、A1和A2可以实现将最多8个24WC01和24WC02器件4个24WC04器件,2个24WC08器件和1个24WC16器件连接到总线上。
2、I2C总线协议(1)只有在总线空闲时才允许启动数据传送。
(2)在数据传送过程中,当时钟线为高电平时,数据线必须保持稳定状态,不允许有跳变。
时钟线为高电平时,数据线的任何电平变化将被看作总线的起始或停止信号。
I2C 总线实验(实时时钟、EEPROM 和ZLG7290 的实验)一.实验目的加深用户对I2C总线的理解,熟悉I2C器件的使用,提高用户实际开发的能力。
二.实验设备及器件IBM PC机一台DP-51PRO 单片机综合仿真实验仪一台三.实验内容进行I2C 总线控制的实时时钟、EEPROM、ZLG7290 键盘LED 控制器实验。
四.实验要求熟练掌握I2C 总线的控制,灵活运用I2C 主控器软件包,深刻理解实时时钟、EEPROM、ZLG7290 键盘LED 控制的各种功能。
五.实验步骤1.使用导线连接D7 区的J4和A2区的P16、P17(SCL~P16、SDA~P17),连接D7 区的J2和A2区的P10、INT0(/RST~P10、INT_KEY~INT0),短接D7 区的JP1跳线。
(连接导线的时候如果导线长度不够,可以利用C8 区的J109、J12、J13、J14、J21 作转接。
)2.把模拟I2C 软件包“VIIC_C51.C”文件加入到Keil C51 的项目中,程序源文件的开头包含“VIIC_C51.H”头文件。
修改VIIC_C51.C 文件中的sbit SDA=P1^7; 和sbit SCL=P1^6;。
3.使用函数ISendStr(uchar sla,uchar suba,uchar *s,uchar no)对PCF8563T 实时时钟进行设置初始时间,再使用IRcvStr(uchar sla,uchar suba,uchar *s,uchar no)对PCF8563T 实时时钟的时间进行读取。
4.使用函数ISendStr(uchar sla,uchar suba,uchar *s,uchar no);对24WC02EEPROM 进行写入,再使用IRcvStr(uchar sla,uchar suba,uchar *s,uchar no);对24WC02 EEPROM 进行读取。
实验二:存储器实验一:实验目的:1:掌握随机存储器RAM的工作特性及使用方法;2:掌握半导体存储器存储和读出数据的工作原理;3:了解半导体存储器电路的定时要求;二:实验条件:1:PC机一台;2:MAX+PLUSⅡ软件;三:实验内容(一)1:所用到的芯片74244:收发器(双向的三态缓冲器)74161:4位二进制计数器(作为程序计数器PC)74273:8个D触发器(作为地址寄存器AR)7448:七段译码器(显示输入的数据)2:实验电路图(A)存储器RAM(B)数据输入电路由两个十六进制计数器连接成16*16=256进制的计数器,可以实现八位的输入。
(C) 数码管扫描显示电路由一个扫描电路scan和一个七段译码器7449组成,scan内部是一个二选一的多路复用器。
(D)存储器电路图3、波形仿真(A)地址计数器74161产生地址练习☆置数法产生地址:(0-300ns)eg:产生地址为03Heg:产生地址06H(B)地址的产生,所以采用边写边读的方法,从下图D[7..0]上的输出可以看出01H—05H都写入了01H—05H单元中。
☆LDAR在写数据的时候打开(使地址和数据同步加1),读的时候关闭;☆读数据的时候PC_BUS关闭;(C)存储器进行读/写操作,连读操作☆修改部分的电路图:分析:只需要把74161的LD 信号改为上图所示的控制信号,其他的控制不变,即数据和地址加1的情况有两种,一是当161LOAD有效时,二是当读信号时,但是要注意读数据的时候要把161LOAD关掉,以防加两次1.☆0-600ns:将07H写入第07H单元,并读出数据☆600ns-1.8us:将0EH写入第08H单元(省略了读数据的操作,若要写完读数据后立刻读数据可参看上面(B)的仿真),从外部送进数据09H,0AH,0BH作为地址(可以省去清零后再计数等不必要的步骤,提高效率),并通过161计数产生数据0DH,0CH,0BH,0DH写入09H单元,0CH写入0AH单元,0BH写入0B单元。
实验二 存储器实验一、实验目的学会存储器的读写方法,了解控制信号的作用。
二、实验电路〈见附录 5 〉三、实验原理存储器实验电路由RAM(6116),AR(74LS273 )等组成。
SW7~SW0为逻辑开关量,以产生地址和数据 : 寄存器 AR 输出 A7~AO 提供存储器地址,通过显示灯可以显示地址。
D7~D0 为总线 , 通过显示灯可以显示数据。
当LDAR 为高电平、BUSSW→为低电平 ,T3 信号上升沿到来时, 开关 SW7~SW0 产生的地址信号送入地址寄存器 AR。
当 CE 为低电平、 WE 为高电平、BUSSW→为低电平,T3 上升沿到来时,开关SW7~SW0 产生的数据写入存储器由A7-A0确定的存储单元内。
当CE为低电平、WE为低电平、BUSSW→为高电平,T3上升沿到来时,存储器为读出数据 ,D7~D0显示由A7-A0所确定的地址中的数据。
实验中,除T3信号外,CE、WE、LDAR、BUSSW→为电位控制信号,因此通过对应逻辑开关来模拟控制信号的电平,而LDAR、WE控制信号受时序信号T3定时。
四、实验步骤实验前预置下列逻辑电平状态 :BUSALU→=1、 /PC→SW→=1、BUSBUS=1,BUS0=1、Rl→BUS=1,R2→BUS=1使总线处在空闲状态, TJ、DP对应R→的逻辑开关置成11状态(高电平输出),时序发生器处于单拍输出状态,实验是在单步状态下进行的, 以便能清楚地看见每一步的运算过程。
将时钟脉冲f0-f3任选一个为“1”,其他三个均为“0”。
实验步骤按表2进行。
实验对表中的开关进行置1或置0,即对有关控制信号置l或置0。
表3中只列出了存储器实验步骤中的一部分,即对几个存储器单元进行了读写,对其它存储单元的操作与之相类似。
表中带↑的地方表示按一次单次脉冲P0。
注意:表中列出的总线显示 D7~DO及地址显示A7~A0,显示情况是:在写入RAM地址时,由 SW7~SW0开关量地址送至 D7~D0,总线显示SW7~SW0开关量,而A7~A0则显示上一个地址,在按P0后,地址才进入AR锁存器, 即在单次脉冲(T3)作用后, A7~A0 同D7~D0才显示一样。
由AT89S52内部定时器1,按方式1工作,每0.5秒钟24LC32的0001H单元内容加1,以键盘作为外部中断输入信号,有键按下时,读取0001H单元内容并送LED显示。
SDA EQU P3.6SCL EQU P3.7ORG 0000HSJMP MAINORG 0003HLJMP PIINT0ORG 001BHLJMP PIT1ORG 0050HMAIN:MOV P1,#0EHMOV P0,#0FFHMOV SP,#60HMOV TMOD,#10H ;设置T1工作方式MOV TH1,#4CH ;设初值MOV TL1,#00HMOV R7,#20 ;计数器SETB PX0;INT0为高优先级CLR PT1 ;T0为低优先级SETB EASETB ET1 ; 允许定时器1SETB TR1 ;启动定时器1SETB IT0SETB EX0 ;允许INT0中断; 扫描键盘MOV P2,#0FHSJMP $PIINT0:PUSH TH1 ;保护现场PUSH TL1CLR TR1MOV R2,#01HLCALL READMOV P0,R3POP TL1POP TH1SETB TR1RETIPIT1:MOV TH1,#4CHMOV TL1,#00HDJNZ R7,LOOPMOV R7,#20INC 30HINC 30HMOV R2,#01HMOV R3,30HLCALL WRITELOOP: RETIWRITE: ;写数据子程序,R2是要写入的24c02的字节位置地址,R3是要写入的内容LCALL STAR;起始条件MOV A,#10100000B ;寻址24C02的总线硬件地址并使用写入命令LCALL SDATA ; 传输数据A给24C02MOV A,#00HLCALL SDATAMOV A,R2 ;确定要写入的字节位置地址LCALL SDATA ;传输数据A给24C02MOV A,R3 ;把数据R3写入刚指定的字节地址LCALL SDATA ;传输数据A给24C02LCALL STOP ;写入结束LCALL CHULI ;提供2ms给24C02内部处理刚写入的数据RETREAD: ;读数据子程序,R2是要读的24c02的字节位置地址,读完后A传给R3LCALL STAR;起始条件MOV A,#10100000B;寻址24C02的总线硬件地址并使用写入命令LCALL SDATA ;传输数据A给24C02MOV A,#00HLCALL SDATAMOV A,R2 ;注意,这里是使24C02的字节地址指针变成R2的值,也就是确定要读取的字节位置地址LCALL SDATA ;传输数据A给24C02LCALL STAR ;重复起始条件MOV A,#10100001B;寻址24C02的总线硬件地址并使用读出命令(这里正式发起读命令) LCALL SDATA;传输数据A给24C02LCALL RDATA;从之前指定的字节地址中读出字节内容到ALCALL STOP ;读取完毕(这里并没有连续读取,只能读一个字节,要多个字节连续读取,请自己在R2上做变址读取循环)MOV R3,A ;读出的字节传给R3RETSTAR:SETB SDA ;起始条件子程序SETB SCLLCALL DELAYLCALL DELAYRETSDATA:MOV R0,#08H ;向24C02传输数据子程序LOOP0:CLR SCLRLC AMOV SDA,CNOPNOPSETB SCLLCALL DELAYDJNZ R0,LOOP0CLR SCLNOPSETB SDANOPNOPSETB SCLREP:MOV C,SDAJC REPNOPNOPNOPCLR SCLNOPNOPRETRDATA:MOV R0,#08H ;从24C02读取数据子程序(读取一个字节以后不做应答) LOOP1:SETB SCLLCALL DELAYMOV C,SDARLC ACLR SCLLCALL DELAYDJNZ R0,LOOP1SETB SCLLCALL DELAYCLR SCLRETSTOP:CLR SDA ;结束条件LCALL DELAYLCALL DELAY SETB SDALCALL DELAYRETDELAY: NOPNOPNOPNOPRETCHULI:MOV R6,#04HWR0:MOV R5,#0F8H DJNZ R5,$DJNZ R6,WR0RETEND。
i2c实验报告I2C实验报告引言:I2C(Inter-Integrated Circuit)是一种串行通信协议,用于在集成电路(IC)之间进行短距离通信。
它由飞利浦公司(现在的恩智浦半导体)于1982年开发,旨在简化数字设备之间的通信。
本文将介绍我进行的一次I2C实验,并分享其中的经验和教训。
实验目的:本次实验的目的是通过I2C协议实现两个设备之间的通信。
我们选择了一块Arduino开发板和一个I2C温度传感器作为实验设备。
通过成功实现I2C通信,我们将能够读取温度传感器的数据,并在Arduino上进行处理和显示。
实验步骤:1. 连接硬件:首先,我们将Arduino和温度传感器通过I2C总线连接起来。
我们使用了Arduino的SDA和SCL引脚分别连接到温度传感器的SDA和SCL引脚。
此外,我们还将温度传感器的VCC引脚连接到Arduino的5V引脚,将GND引脚连接到Arduino的GND引脚。
2. 编写代码:接下来,我们使用Arduino IDE编写代码来实现I2C通信。
首先,我们需要包含Wire库,该库提供了I2C通信所需的函数和方法。
然后,我们初始化I2C总线,并设置温度传感器的地址。
通过调用Wire.beginTransmission()和Wire.endTransmission()函数,我们可以向传感器发送读取温度数据的请求,并使用Wire.requestFrom()函数获取传感器返回的数据。
3. 读取温度数据:在代码中,我们使用Wire.available()函数检查是否有数据可用。
如果有数据可用,我们使用Wire.read()函数读取数据,并进行必要的计算和转换,以获得实际的温度值。
最后,我们将温度值显示在Arduino的串口监视器上。
实验结果:经过一番努力,我们成功地实现了I2C通信,并能够读取温度传感器的数据。
通过观察串口监视器,我们可以看到实时的温度值。
这为我们进一步的温度控制和监测提供了基础。
实验报告班级姓名学号组员实验题目:I2C一、实验目的:1、掌握24C04与ATmega8单片机接口的方法。
2、掌握I2C总线使用。
二、实验仪器:1、A VRA Tmega8 单片机开发板一块2、+9V直流电源一个3、USBISP下载电缆一根三、实验原理I2C总线是一种用于IC器件之间连接的二线制总线。
它通过SDA(串行数据线)及SCL(串行时钟线)两根线在连到总线上的器件之间传送信息,并根据地址识别每个器件:不管是单片机、存储器、LCD驱动器还是键盘接口。
1.I2C总线的基本结构采用I2C总线标准的单片机或IC器件,其内部不仅有I2C接口电路,而且将内部各单元电路按功能划分为若干相对独立的模块,通过软件寻址实现片选,减少了器件片选线的连接。
CPU不仅能通过指令将某个功能单元电路挂靠或摘离总线,还可对该单元的工作状况进行检测,从而实现对硬件系统的既简单又灵活的扩展与控制。
I2C总线接口电路结构如图1所示。
2.双向传输的接口特性传统的单片机串行接口的发送和接收一般都各用一条线,如MCS51系列的TXD和RXD,而I2C总线则根据器件的功能通过软件程序使其可工作于发送或接收方式。
当某个器件向总线上发送信息时,它就是发送器(也叫主器件),而当其从总线上接收信息时,又成为接收器(也叫从器件)。
主器件用于启动总线上传送数据并产生时钟以开放传送的器件,此时任何被寻址的器件均被认为是从器件。
I2C总线的控制完全由挂接在总线上的主器件送出的地址和数据决定。
在总线上,既没有中心机,也没有优先机。
总线上主和从(即发送和接收)的关系不是一成不变的,而是取决于此时数据传送的方向。
SDA和SCL均为双向I/O线,通过上拉电阻接正电源。
当总线空闲时,两根线都是高电平。
连接总线的器件的输出级必须是集电极或漏极开路,以具有线“与”功能。
I2C总线的数据传送速率在标准工作方式下为100kbit/s,在快速方式下,最高传送速率可达400kbit/s。
信息工程学院实验报告
1、熟悉掌握对RAM 的操作。
2、学习汇编程序的编写。
3、熟悉ZY15MicInt12BB 微机原理及接口试验箱使用方法。
实 验 环 境:
Windows 7 湖北众友
实 验 内 容 及 过 程: 1、首先在ZY15MicInt12BB 微机原理及接口实验箱中按实验要求连接好电路,再将试验箱与PC 机连接。
接线如图T2-1所示:
图T2-1
2、打开试验箱电源,带液晶模块稳定显示“NOW COM IS STANDBY ”后,再打开湖北众友软件,选择端口号。
如图T2-2所示:
图T2-2
3、打开实验文件,在湖北众友上,然后在“编译”菜单下选择“编译、连接、装载”,若一切无误,系统将提示装载成功。
如图4。
最后再点击连续运行,就能在实验箱上看
到结果了。
如图T2-3和图T2-4所示:
图T2-3
图T2-4
实验结果及分析:
装载、编译、链接文件,运行程序,在实验箱的液晶上会根据编写的程序内容显示字母A到字母Z,具体如图T2-5所示:
图T2-5。
I2C总线通信实验一.实验目的1.掌握HCS12单片与E2PPROM设备之间的通信2.熟悉相关的寄存器,使用C语言编程。
二.实验任务从单片机中发送一个数据到A T24C02中,然后再让单片机从A T24C02中读取数据,再把数据显示到数码管中。
三.AT24C02电路图A0=0,A1=0,A2=0;可以知道A T24C02的从设备写地址为10100000(0xa0),读设备地址为10100001(0xa1);四.寄存器的简单介绍由于涉及的寄存内容较多,请读者自己查阅数据手册。
五.实验代码本实验的流程图实验代码如下:#include <hidef.h>#include "derivative.h"void IICInit(void){IBFD= 0x68;//总线频率:8MHz,IIC总线频率:62.5KHz,SDA保持时间:2.45usIBAD = 0xF0; //D7-D0位是MCU作为从机时的地址,最低位不使用IBCR = 0x88; //不发送应答信号//接收模式//从机模式//禁止IIC中断//能IIC模块}//SendSignal:在IIC总线上发送起停信号---------------------------------------*//功能:根据需要产生开始或停止信号* //参数:Signal = 'S'(Start),产生开始信号;Signal = 'O'(Over),产生停止信号*//返回:无* //-------------------------------------------------------------------------*void SendSignal(INT8U Signal){if (Signal == 'S')IBCR |= 0x20; //主机模式选择位MST由0变为1,可以产生开始信号else if (Signal == 'O')IBCR &= ~0x20; //主机模式选择位MST由1变为0,可以产生停止信号}//Wait:等待应答或一个字节数据的传送完成------------------------------------*//功能:在时限内,循环检测接收应答标志位,或传送完成标志位,判断MCU是否接收到应* // 答信号或一个字节是否已在总线上传送完毕* //参数:x = 'A'(Ack),等待应答;x = 'T'(Transmission),等待一个字节数据传输完成*//返回:0:收到应答信号或一个字节传送完毕;1:未收到应答信号或一个字节没传送完* //-------------------------------------------------------------------------*INT8U Wait(INT8U x){INT8U ErrTime, i;ErrTime = 255; //定义查询超时时限for (i = 0;i < ErrTime;i++){if (x == 'A') //等待应答信号{if ((IBSR & 0x01) == 0)SCISend1('c');return 0; //传送完一个字节后,收到了从机的应答信号}else if (x == 'T') //等待传送完成一个字节信号{if ((IBSR & 0x02) != 0){IBSR |= 0x02; //清IICIF标志位SCISend1('d');return 0; //成功发送完一个字节}}}if (i >= ErrTime)SCISend1('f');return 1; //超时,没有收到应答信号或发送完一个字节}//IICread1:从从机读1个字节数据---------------------------------------------*//功能:从从机读1个字节数据* //参数: *// (1) DeviceAddr:设备地址*// (2) AccessAddr:访问地址*// (3) Data:带回收到的一个字节数据*//返回:为0,成功读一个字节;为1,读一个字节失败* //内部调用:SendSignal,Wait *//-------------------------------------------------------------------------*INT8U IICread1(INT8U DeviceAddr, INT8U AccessAddr, INT8U *Data){IBCR |= 0x10; //TX = 1,MCU设置为发送模式SendSignal('S'); //发送开始信号IBDR = DeviceAddr & 0xfe; //发送设备地址,并通知从机接收数据if (Wait('T')) //等待一个字节数据传送完成return 1; //没有传送成功,读一个字节失败if (Wait('A')) //等待从机应答信号return 1; //没有等到应答信号,读一个字节失败IBDR = AccessAddr; //发送访问地址if (Wait('T')) //等待一个字节数据传送完成return 1; //没有传送成功,读一个字节失败if (Wait('A')) //等待从机应答信号return 1; //没有等到应答信号,读一个字节失败IBCR |= 0x04; //主机模式下,RSTA位置1,产生重复开始信号IBDR = DeviceAddr | 0x01; //通知从机改为发送数据if (Wait('T')) //等待一个字节数据传送完成return 1; //没有传送成功,读一个字节失败if (Wait('A')) //等待从机应答信号return 1; //没有等到应答信号,读一个字节失败IBCR &= 0xef; //TX = 0,MCU设置为接收模式*Data = IBDR; //读出IBDR,准备接收数据if (Wait('T')) //等待从机应答信号return 1; //没有等到应答信号,读一个字节失败SendSignal('O'); //发送停止信号*Data = IBDR; //读出接收到的一个数据return 0; //正确接收到一个字节数据}//IICwrite1:向从机写1个字节数据--------------------------------------------*//功能:向从机写1个字节数据* //参数: * // (1) DeviceAddr:设备地址*// (2) AccessAddr:访问地址*// (3) Data:要发给从机的1个字节数据* //返回:为0,成功写一个字节;为1,写一个字节失败* //内部调用:Start, SendByte, WaitAck, Stop *//-------------------------------------------------------------------------*INT8U IICwrite1(INT8U DeviceAddr, INT8U AccessAddr, INT8U Data){IBCR |= 0x10; //TX = 1,MCU设置为发送模式SendSignal('S'); //发送开始信号IBDR = DeviceAddr & 0xfe; //发送设备地址,并通知从机接收数据if (Wait('T')) //等待一个字节数据传送完成return 1; //没有传送成功,写一个字节失败if (Wait('A')) //等待从机应答信号return 1; //没有等到应答信号,写一个字节失败IBDR = AccessAddr; //发送访问地址if (Wait('T')) //等待一个字节数据传送完成return 1; //没有传送成功,写一个字节失败if (Wait('A')) //等待从机应答信号return 1; //没有等到应答信号,写一个字节失败IBDR = Data; //写数据if (Wait('T')) //等待一个字节数据传送完成return 1; //没有传送成功,写一个字节失败if (Wait('A')) //等待从机应答信号return 1; //没有等到应答信号,写一个字节失败SendSignal('O');//发送停止信号return 0;}int WriteData=0xf0; //8位LED,高四位灭,低四位亮。
Proteus仿真I2C存储器实验一、实验目的1、了解I2C总线的工作原理2、掌握I2C总线驱动程序的设计和调试方法3、掌握I2C总线存储器的读写方法二、实验说明1、I2C总线常识I2C总线上的每个器件均由一个存储于该器件中的唯一地址来识别,并可被用作一个发送器或接收器(视其功能而定)。
AT24C02是一个2K位串行EEPROM,内部含有256个8位字节,AT24C02有一个8字节页写缓冲器,该器件通过I2C总线接口进行操作。
引脚名称和功能如图1所示。
图1 24系例I2C存储器引脚说明通过器件地址输入端A0、A1和A2可以实现将最多8个24C02器件连接到总线上。
2、I2C总线协议(1)只有在总线空闲时才允许启动数据传送。
(2)在数据传送过程中,当时钟线为高电平时,数据线必须保持稳定状态,不允许有跳变。
时钟线为高电平时,数据线的任何电平变化将被看作总线的起始或停止信号。
(3)起始信号,时钟线保持高电平期间,数据线电平从高到低的跳变作为I2C总线的起始信号。
(4)停止信号,时钟线保持高电平期间,数据线电平从低到高的跳变作为I2C 总线的停止信号。
I2C 总线时序:3、页写操作的数据帧结构根据页缓冲区的大小,页写的字节数不能超过缓冲区大小。
如果在发送停止信号之前主器件发送超过缓冲区大小,地址计数器将自动翻转,先前写入的数据被覆盖。
如图2所示。
图2页写操作数据帧结构三、实验内容先搭建一个“I2C存储器实验”的仿真电路,该单片机系统功能是采用页写的方式,把器件地址为A0H的24C02器件的片内50H地址开始的8个存储单元分别写入数据“00、11、22、、、、、、77”。
四、.参考硬件电路五、参考汇编程序SDA EQU P3.5 ;定义24c02的串行数据线SCL EQU P3.4 ;定义24c02的串行时钟线SNUM EQU 40HSLAW EQU 41HORG 0000HAJMP MAINORG 0040HMAIN:MOV SP,#5FHLCALL LDATAMOV SLAW,#0A0H ;24c02的器件地址MOV SNUM,#9 ;要发送9个字节数据MOV R1,#30H ;数据缓冲区的首地址CALL WRNB ;调用发送n个字节的子程序SJMP $LDATA:MOV R0,#30H ;片内ram的地址:30H 31H 32H 33H 34H 35H…..MOV @R0,#50H ;存放的数据:50H 00H 11H 22H 33H 44H……INC R0MOV @R0,#00HINC R0MOV @R0,#11HINC R0MOV @R0,#22HINC R0MOV @R0,#33HINC R0MOV @R0,#44HINC R0MOV @R0,#55HINC R0MOV @R0,#66HINC R0MOV @R0,#77HRET;起始信号STA:SETB SDASETB SCLNOPCLR SDANOPNOPCLR SCLRET;终止信号STP:CLR SDASETB SCLNOPNOPSETB SDANOPNOPCLR SDACLR SCLRET;发应答位"0" ASK:CLR SDASETB SCLNOPNOPCLR SCLSETB SDARET;发非应答位"1" NAS:SETB SDASETB SCLNOPCLR SCLCLR SDARET;应答位检查,正常应答时F0标志为0,否则F0为1 ASKC:SETB SDASETB SCLCLR F0MOV C,SDAJNC CEND ;应答位为1,不置位F0SETB F0CEND: CLR SCLRET;发送到24c02一个字节,预发送的数据存于A中WRB:MOV R0,#08HLOOP0:RLC AMOV SDA,CNOPNOPSETB SCLNOPNOPNOPNOPCLR SCLDJNZ R0,LOOP0RET;--------------------------------*;*函数名称:WRNB *;*功能描述:对E2PROM指定的页写入SNUM个字节的数据* ;*调用函数:STA WRB ASKC STP *;*入口条件:SLAW--I2C器件写地址*;* R1-片内RAM发送数据缓冲区的首地址* ;--------------------------------*WRNB:LCALL STAMOV A,SLAWLCALL WRB ;写器件的写地址LCALL ASKCJB F0, WRNBWLP: ;向E2PROM写入SNUM个字节的数据MOV A,@R1LCALL WRBLCALL ASKCJB F0, WRNBINC R1DJNZ SNUM, WLPLCALL STPRETEND六、思考练习题1、请说说I2C总线的优点有哪些?2、编写程序,将自己学号写入24C02地址为30H开始的存储单元。
任务二:I2C存储器读写(计数器,并能断电存储)实验原理1)I2C总线概述I2C总线是PHLIPS公司推出的一种串行总线,是具备多主机系统所需的包括总线裁决和高低速器件同步功能的高性能串行总线。
2)I2C信号线I2C总线只有两根双向信号线。
一根是数据线SDA,另一根是时钟线SCL。
I2C总线通过上拉电阻接正电源。
当总线空闲时,两根线均为高电平。
连到总线上的任一器件输出的低电平,都将使总线的信号变低,即各器件的SDA及SCL都是线“与”关系。
图1 I2C总线框图3)I2C总线的数据传送a)数据位的有效性规定I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。
图2 SDA与SCL的工作时序图b) 起始和终止信号SCL线为高电平期间,SDA线由高电平向低电平的变化表示起始信号SCL线为高电平期间,SDA线由低电平向高电平的变化表示终止信号。
起始和终止信号都是由主机发出的,在起始信号产生后,总线就处于被占用的状态;在终止信号产生后,总线就处于空闲状态。
c) I2C总线的数据传送速率I2C总线的通信速率受主机控制,能快能慢,最高速率限制为100Kb/sd) I2C总线的数据传送格式主机向从机发送数据从机向主机发送数据图3 I2C总线的数据传送格式S:起始位SA: 从机地址,7位W/:写标志位,1位R:读标志位,1位A:应答位,1位A/:非应答位,1位D:数据,8位P:停止位阴影:主机产生的信号无阴影:从机产生的信号4)总线的寻址I2C总线协议有明确的规定:采用7位的寻址字节(寻址字节是起始信号后的第一个字节)。
寻址字节的位定义D7~D1位组成从机的地址。
D0位是数据传送方向位,为“0”时表示主机向从机写数据,为“1”时表示主机由从机读数据。
主机发送地址时,总线上的每个从机都将这7位地址码与自己的地址进行比较,如果相同,则认为自己正被主机寻址,根据R/位将自己确定为发送器或接收器。
I2C存储器实验实验目的1、了解I2C总线的工作原理2、掌握I2C总线驱动程序的设计和调试方法3、掌握I2C总线存储器的读写方法实验仪器单片机开发板、稳压电源、计算机实验原理1、 I2C总线常识I2C总线采用一个双线式漏极开路接口,可在一根总线上支持多个器件和主控器。
所连接的器件只会把总线拉至低电平,而决不会将其驱动至高电平。
总线在外部通过一个电流源或上拉电阻器连接至一个正电源电压。
当总线空闲时,两条线路均为高电平。
在标准模式中,I2C 总线上的数据传输速率高达100kbit/s,而在快速模式中则高达400kbit/s。
I2C总线上的每个器件均由一个存储于该器件中的唯一地址来识别,并可被用作一个发送器或接收器(视其功能而定)。
除了发送器和接收器之外,在执行数据传输时,还可把器件视作主控器或受控器。
主控器是负责启动总线上的数据传输并生成时钟信号以允许执行该传输的器件。
同时,任何被寻址的器件均被视作受控器。
CAT24WC01/02/04/08/16是一个1K/2K/4K/8K/16K位串行CMOS EEPROM,内部含有128/256/512/1024/2048个8位字节,CATALYST公司的先进CMOS技术实质上减少了器件的功耗,CAT24WC01有一个8字节页写缓冲器,CAT24WC02/04/08/16有一个16字节页写缓冲器,该器件通过I2C总线接口进行操作,有一个专门的写保护功能,并且器件能与400KHzI2C 总线兼容。
引脚名称和功能如图1所示。
图1 24系例I2C存储器引脚说明通过器件地址输入端A0、A1和A2可以实现将最多8个24WC01和24WC02器件4个24WC04器件,2个24WC08器件和1个24WC16器件连接到总线上。
2、I2C总线协议(1)只有在总线空闲时才允许启动数据传送。
(2)在数据传送过程中,当时钟线为高电平时,数据线必须保持稳定状态,不允许有跳变。
时钟线为高电平时,数据线的任何电平变化将被看作总线的起始或停止信号。
(3)起始信号时钟线保持高电平期间,数据线电平从高到低的跳变作为I2C 总线的起始信号。
(4) 停止信号时钟线保持高电平期间,数据线电平从低到高的跳变作为I2C 总线的停止信号。
I2C 总线时序:I2C 总线时序图I2C总线启动停止信号波形:SCL为高电平,SDA降沿为启动信号;SCL为高电平,SDA 上升沿为停止信号。
I2C 总线启动停止信号I2C总线写周期波形:SCL正脉冲锁存数据,或SCL为高电平数据有效。
SCL高电平期间SDA数据应保持不变。
I2C 总线写时序波形I2C总线应答信号波形:I2C总线数据传送时,每成功地传送一个字节数据后,接收器都必须产生一个应答信号。
应答的器件在第9个时钟周期时将SDA线拉低,表示其已收到一个8 位数据。
I2C 总线读时序3、24C系列存储器读写操作(1)24系列常用存储器器件地址安排24系例存储器器件地址安排(2)字节写操作在字节写模式下,主器件发送起始命令和从器件地址信息(R/W位置零)给从器件,在从器件产生应答信号后,主器件发送CAT24WC01/02/04/08/16的1字节地址(存储容量大的存储器字节地址两字节),主器件在收到从器件的另一个应答信号后,再发送数据到被寻址的存储单元。
CAT24WC01/02/04/08/16再次应答,并在主器件产生停止信号后,开始内部数据的擦写,在内部擦写过程中从器件不再应答主器件的任何请求(10ms)。
如图所示。
字节写操作数据帧结构(3)页写操作(提高写入速度)根据页缓冲区的大小,页写的字节数不能超过缓冲区大小。
如果在发送停止信号之前主器件发送超过缓冲区大小,地址计数器将自动翻转,先前写入的数据被覆盖。
如图所示。
页写操作数据帧结构(4)当前地址读操作当读取一个字节数据后,存储器内部地址计数器加1。
当读到最后一字节时,计数器将翻转到0且继续输出数据。
CAT24WC01/02/04/08/16 接收到从器件地址信号后(R/W 位置1),它首先发送一个应答信号,然后发送一个8位字节数据。
主器件产生一个非应答信号(这里是主器件发送的非应答信号),再产生一个停止信号。
如图所示。
当前地址读操作数据帧结构(5)任意地址读操作、连续读操作任意地址读、连续读操作数据帧结构4、I2C总线存储读写程序设计I2C总线存储器读写程序分为两层:硬件接口程序和存储器读写程序。
其中硬件接口程序有:总线启动、停止、发数据、收数据、发响应、发非响应、读从器件响应状态等。
存储器读写程序有:单字节写数据、页写数据、当前地址读数据、任意地址读数据、连续读数据等。
参考上面的时序图设计硬件接口相关子程序。
I2C总线接口程序流程图I2C总线数据读写流程图存储器读写程序设计。
这里以单字节读、写程序为例说明,其它子程序由读者自行设计。
I2C存储器单字节读写流程图实验参考程序:/******************************************************************************普中科技--------------------------------------------------------------------------------* 实验名 : 24C02EEPROM存储试验* 实验说明 : 使用LCD1602显示写入的数据和读出的数据* 连接方式 : 见连接图* 注意 :******************************************************************************/ #include<reg51.h>#include"i2c.h"#include"lcd.h"//--定义使用的IO口--////数码管IO#define GPIO_DIG P0sbit LSA=P2^2;sbit LSB=P2^3;sbit LSC=P2^4;//按键IOsbit K1=P3^0;sbit K2=P3^1;sbit K3=P3^2;sbit K4=P3^3;//--定义全局变量--//unsigned char wordCode0[6] = "write:";unsigned char wordCode1[6] = " read:";//--声明全局函数--//void At24c02Write(unsigned char ,unsigned char );unsigned char At24c02Read(unsigned char );void Delay10ms(unsigned int c); //误差 0us/****************************************************************************** * 函数名 : main* 函数功能 : 主函数* 输入 : 无* 输出 : 无******************************************************************************/ void main(){unsigned int num0 = 0,num1 = 0,n;LcdInit();LcdWriteCom(0x80);for(n=0; n<6; n++){LcdWriteData(wordCode0[n]);}LcdWriteCom(0x80 + 0x40);for(n=0; n<6; n++){LcdWriteData(wordCode1[n]);}while(1){if(K1 == 0) //按键1按下{Delay10ms(1);if(K1 == 0)At24c02Write(2,num0);while((n < 50)&&(K3==0)){n++;Delay10ms(1);}n=0;n=0;}if(K2 == 0) //按键2按下{Delay10ms(1);if(K2 == 0)num1 = At24c02Read(2);while((n < 50)&&(K2 == 0)){n++;Delay10ms(1);}n=0;}if(K3 == 0) //按键3按下{Delay10ms(1);if(K3 == 0)num0++;while((n < 50)&&(K3 == 0)){n++;Delay10ms(1);}n=0;if(num0==256)num0=0;}if(K4 == 0) //按键4按下{Delay10ms(1);if(K4 == 0)num0 = 0;while((n < 50) && (K4 == 0)){n++;Delay10ms(1);}n=0;}LcdWriteCom(0x87);LcdWriteData('0' + (num0/1000));//千位LcdWriteData('0' + (num0%1000/100));//百位LcdWriteData('0' + (num0%1000%100/10));//十位LcdWriteData('0' + (num0%1000%100%10));//个位LcdWriteCom(0x87 + 0x40);LcdWriteData('0' + (num1/1000));//千位LcdWriteData('0' + (num1%1000/100));//百位LcdWriteData('0' + (num1%1000%100/10));//十位LcdWriteData('0' + (num1%1000%100%10));//个位}}/****************************************************************************** * 函数名 : Delay10ms* 函数功能 : 延时函数,延时10ms* 输入 : 无* 输出 : 无******************************************************************************/void Delay10ms(unsigned int c) //误差 0us{unsigned char a, b;//--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--// for (;c>0;c--){for (b=38;b>0;b--){for (a=130;a>0;a--);}}}/****************************************************************************** * 函数名 : void At24c02Write(unsigned char addr,unsigned char dat)* 函数功能 : 往24c02的一个地址写入一个数据* 输入 : 无* 输出 : 无******************************************************************************/void At24c02Write(unsigned char addr,unsigned char dat){I2C_Start();I2C_SendByte(0xa0, 1);//发送写器件地址I2C_SendByte(addr, 1);//发送要写入内存地址I2C_SendByte(dat, 0); //发送数据I2C_Stop();}/****************************************************************************** * 函数名 : unsigned char At24c02Read(unsigned char addr)* 函数功能 : 读取24c02的一个地址的一个数据* 输入 : 无* 输出 : 无******************************************************************************/unsigned char At24c02Read(unsigned char addr){unsigned char num;I2C_Start();I2C_SendByte(0xa0, 1); //发送写器件地址I2C_SendByte(addr, 1); //发送要读取的地址I2C_Start();I2C_SendByte(0xa1, 1); //发送读器件地址num=I2C_ReadByte(); //读取数据I2C_Stop();return num;}#include"i2c.h"/****************************************************************************** * 函数名 : Delay1us()* 函数功能 : 延时* 输入 : 无* 输出 : 无******************************************************************************/void I2C_Delay10us(){uchar a, b;for(b=1; b>0; b--){for(a=2; a>0; a--);}}/****************************************************************************** * 函数名 : I2C_Start()* 函数功能 : 起始信号:在I2C_SCL时钟信号在高电平期间I2C_SDA信号产生一个下降沿* 输入 : 无* 输出 : 无* 备注 : 起始之后I2C_SDA和I2C_SCL都为0******************************************************************************/void I2C_Start(){I2C_SDA = 1;I2C_Delay10us();I2C_SCL = 1;I2C_Delay10us();//建立时间是I2C_SDA保持时间>4.7usI2C_SDA = 0;I2C_Delay10us();//保持时间是>4usI2C_SCL = 0;I2C_Delay10us();}/****************************************************************************** * 函数名 : I2C_Stop()* 函数功能 : 终止信号:在I2C_SCL时钟信号高电平期间I2C_SDA信号产生一个上升沿* 输入 : 无* 输出 : 无* 备注 : 结束之后保持I2C_SDA和I2C_SCL都为1;表示总线空闲******************************************************************************/void I2C_Stop(){I2C_SDA = 0;I2C_Delay10us();I2C_SCL = 1;I2C_Delay10us();//建立时间大于4.7usI2C_SDA = 1;I2C_Delay10us();}/****************************************************************************** * 函数名 : I2cSendByte(uchar num)* 函数功能 : 通过I2C发送一个字节。