|
第一届51测试网有奖征文精彩回放,深圳学林电子版权所有 www.51c51.com (专业51单片机学习网站)转载注明出处! 更多精彩稿件请访问论坛http://www.51c51.com/bbs/index.asp |
|
| 作品1:字符型液晶显示模块
作者联系: 邓杰 |
|
| 作品2:用8X8LED点阵屏循环显示 | 作品7:用虚拟IIC总线实现24C02
的应用
|
| 作品3:虚拟仿真仪器UMPS的应用:牛余朋 |
作品8:语音编程、远程控制试验板
社区乞丐 |
| 作品4:万年历数字钟及可调时钟系统 |
作品9:定时开关控制器的制作 |
|
用虚拟IIC总线实现串行EEPROM 24C02 在单片机中的应用
南阳理工学院电子系
张全领 1、引言 本文是介绍串行E2
PROM
24C02 与单片机的连接,
给出了接口电路及具体应用程序,含有有键盘程序、动态显示程序。 2、串行E2
PROM
24C02的硬件连接
如图1
所示,24C02
与单片机AT89S52的连接采用的是I2C
总线(
Inter IC Bus) 。I2C
总线是由串行数据线SDA
与时钟线SCL
构成的,
所有的控制命令和数据均通过这两条线传输。单片机AT89S52
作为主器件,它在I2C
总线上产生时钟脉冲、寻址信号、起停信号;
24C02 作为从器件,它通过串行数据线SDA
与时钟线SCL
与单片机AT89S52的引脚P3.6
、
P3.7
相连。24C02
提供2k
位串行E2
PROM
, 内部组态为256
×8
位。A0、A1、A2
为芯片的地址线,在使用中把这三条线接地。WP
为低电平时,允许写操作。AT89S52是一种低功耗、高性能CMOS8位微控制器,具有8K在系统可编程Flash存储器,与工业80C51产品指令各引脚完全兼容。
图1 2.
1 总线的操作时序如图2
所示,
SCL 和SDA
两总线平时通过上拉电阻为高电平,
SDA 为数据线,SCL为时钟线。
图2 摘要:
本文介绍的是串行E2
PROM
与单片机AT89S52
的硬件连接,
阐述了AT89S52
对24C02
的读写操作时序、操作方法,最后给出了一个完整的应用程序。 关键词:
I2C
总线
串行E2
PROM SCL
低电平时间周期内可能改变。SCL
高电平周期期间数据改变表示“开始”或“停止”两种状态:
当SCL
处于高电平时,DSA
由高电平转向低电平表示“开始”,
由低电平转向高电平表示“停止”状态。其中“开始”状态必须在其它操作之前执行,
而“停止”状态则终止所有操作。除以上两个状态,24C02
与外界的通讯还需另一个状态,
即确认状态ACK
, 该确认是在每个字节之后第九个时钟周期发生,在后面的读、写过程将予以介绍。 2.2
24C02 数据写操作 写操作时序如图3
所示。在写操作中,主器件发送完写控制字节10100000
, 等接收到24C02
通过SDA
发出确认信号ACK
后,
主器件接着随时钟输入8
位地址码(00
-0FFH) , 收到24C02
再次发出确认信号ACK
后,才发送待写入的数据。最后,主设备必须用停止状态来终止写操作。在写控制字节中高四位被指定为1010
, 芯片地址为A2、A1、A0
为000
,R/ W = 0 。
2.
3 24C02 数据读操作读操作时序如图4
所示。若是读当前地址内容,主器件发送完读控制字节10100001
,并收到ACK信号后,
即可一位位地读出该单元内容;
若要读随意地址内容,
由主器件先发送写控制字节10100000
, 然后发送待读的E2
PROM
单元地址(00
- 0FFH) , 收到ACK信号后由主器件再次产生起始条件,接着发送读控制字节,
收到ACK信号后,
即可读出该单元内容。最后,数据的读取不通过确认应答,而是通过产生一个停止状态来应答。
3、说明:
我正在学习单片机,在学习过程中认为键盘、显示、数据存储等,这些基本模块非常重要。我也写过键盘程序、动态显示程序、还有串行E2
PROM
24C02的一些相关程序。本次只是把三个模块稍加综合。在初始状态下,实现8位数码管全部为0,按键是4*4键盘,其中含有存储、取出显示、清除三个功能键,(
其它键本来是表示0-C ,但是由于我的实验板是74LS48做译码
,无法正常显示字母,我在程序中把它们全改成了0——9的数字。)由低位到高位移动显示,即按下第一次键显示的数,到第二次有键按下时,会被挤到第二位显示,依次类推,如果第九次按键,就会把第一次键值挤出,因为只能显示八位。串行E2
PROM
24C02的程序,我在学习中感觉比键盘、显示子程序有点难度,所以基本上都带有详细的注释及说明。 以下,说一下图5(仿真图),其实它与原理图没有太大区别,就是省去了晶振、复位及一些驱动放大电路,我想这对每个单片机爱好者来说,没有太大问题。如果哪位读者对原理图感兴趣的话,可以给我留言,我可以用Protel作图再发过去。由于本人也是穷学生一个。根本没有数码相机这样高消费的东西,没有办法把实物照片发过,希望石大哥见谅! 另外,我也是一名单片机初学者,因此能力有限。希望与大家共同学习提高。虽然本人呕心沥血(夸张一点)使程序可以实现应有功能。不过,也是无法满足大侠的需要,里面一定会有很多不足之处,希望读者批评指正。 参考文献:《单片机外围器件手册——存储器分册》
图5 附源程序: /********************************************************************* * 本程序是练习键盘、显示及串行IIC的程序
* * 以12M晶振为例
* * 谨适合初学者
* * 作者:张全领
* ********************************************************************/ SDA EQU
P3.7 SCL EQU
P3.6 SLAW EQU 0A0H
;WRITE的外围地址 SLAR EQU 0A1H
;READ的外围地址 NUMBYT EQU 8 ;字节个数 ORG
0000H LJMP
MAIN ORG
000BH ;采用定时器0中断 SJMP
ITIME0 ORG
0040H /*********INTERRUPT 中断显示******************************************/ ITIME0:MOV TH0,#LOW(65536-40000)
;重赋初值 MOV TL0,#HIGH(65536-40000) MOV
P0,40H ORL
P0,#70H
;使第一位显示 CALL
T1MS
;延时 MOV
P0,41H ORL
P0,#60H CALL
T1MS MOV
P0,42H ORL
P0,#50H CALL
T1MS MOV
P0,43H ORL
P0,#40H CALL
T1MS MOV
P0,44H ORL
P0,#30H CALL
T1MS MOV
P0,45H ORL
P0,#20H CALL
T1MS MOV
P0,46H ORL
P0,#10H CALL
T1MS MOV
P0,47H ORL
P0,#00H CALL
T1MS RETI
T1MS: MOV R5,0FFH
;延时程序 DJNZ R5,$ RET
/**********MAIN 程序*************************************************/ MAIN:
MOV SP,#60H
MOV P2,#0FFH
MOV R0,#40H
MOV R2,#08H CLEAR:
;清除显示区内容
MOV @R0,#00H
INC R0
DJNZ R2,CLEAR
MOV TMOD,#01H
;定时器0,工作方1
MOV TH0,#HIGH(65536-40000);赋初值
MOV TL0,#LOW(65536-40000)
SETB EA
SETB ET0
SETB TR0 LOOP:
;调用键盘程序
CALL KEY
SJMP LOOP /* **************键盘程序以下*****************************************/ KEY:
ACALL KS1
;判断键是否按下
JNZ LK1
;有键按下(A不等于0)转到LK1,消抖动延时
AJMP KEY
;无键按下返回 LK1:ACALL T12MS
;调用12MS延时
ACALL KS1
;有无键按下,若有则为确实有键盘按下
JNZ LK2
;键按下转列扫描
AJMP KEY
;不是键按下返回 LK2:MOV R2,#0EFH
;全扫描字11101111放入R2
MOV R4,#00H
;首列号 LK4:MOV P2,R2
;全扫描字送P2口
MOV A,P2
JB ACC.0,LONE
;判断第0行无键按下,转第一行,ACC.0=0为有键按下
MOV A,#00H
;第0行首列号
AJMP LKP
;转求键号 LONE:
JB ACC.1,LTWO
MOV A,#04H
AJMP LKP LTWO:
JB ACC.2,LTHR
MOV A,#08H
AJMP LKP LTHR:
JB ACC.3,NEXT
MOV A,#12 LKP:ADD A,R4
;R4列号 键号=行号+列号
PUSH ACC
;键号进堆栈保护 LK3:ACALL T12MS
ACALL KS1
;判断是否释放
JNZ LK3
;未释放等待
POP ACC
;释放,出栈键号入A
MOV DPTR ,#TABLE
;首地址放入DPTR
MOV B,#3
MUL AB
JMP @A+DPTR
;散转 TTR:RET NEXT:
INC R4
;列号加1
MOV A,R2
JNB ACC.7,KND
;四列扫描完,返回
RL A
;未完,左移一位
MOV R2,A
;放入R2
AJMP LK4
;重新进入逐行判断 KND:AJMP KEY
;重新调用键盘程序 KS1:MOV P2,#0FH
;判断键是否按下
MOV A, P2
CPL A
ANL A,#0FH
RET
TABLE:
LJMP KEY0
LJMP KEY1
LJMP KEY2
LJMP KEY3
LJMP KEY4
LJMP KEY5
LJMP KEY6
LJMP KEY7
LJMP KEY8
LJMP KEY9
LJMP KEYA
LJMP KEYB
LJMP KEYC
LJMP KEYD
LJMP KEYE
LJMP KEYF KEY0:
MOV A,#00H
SJMP LEDA KEY1: MOV A,#01H
SJMP LEDA KEY2: MOV A,#02H
SJMP LEDA KEY3: MOV A,#03H
SJMP LEDA KEY4: MOV A,#04H
SJMP LEDA KEY5: MOV A,#05H
SJMP LEDA
KEY6: MOV A,#06H
SJMP LEDA KEY7: MOV A,#07H
SJMP LEDA KEY8: MOV A,#08H
SJMP LEDA KEY9: MOV A,#09H
SJMP LEDA KEYA: MOV A,#01H
SJMP LEDA KEYB: MOV A,#02H
SJMP LEDA
KEYC: MOV A,#03H
SJMP LEDA KEYD: ;MOV A,#04H
LJMP QING24 KEYE: ;MOV A,#05H
LJMP READ24 KEYF: ;MOV A,#06H
LJMP WRITE24 LEDA: CLR ET0
XCH A,40H
XCH A,41H
XCH A,42H
XCH A,43H
XCH A,44H
XCH A,45H
XCH A,46H
XCH A,47H
SETB ET0
LJMP TTR T12MS:
;延时12MS子程序
MOV R7,#18H TM: MOV R6,#0FFH TM6:DJNZ R6,$
DJNZ R7,TM
RET ;存储
写进24的程序 WRITE24:
MOV R5,#0
MOV R1,#40H
CLR ET0
LCALL SEND_NBYTE
SETB ET0
LJMP TTR ;取出
读24内容 READ24:
MOV R5,#0
MOV R1,#40H
CLR ET0
LCALL READ_NBYT
SETB ET0
LJMP TTR ;清24的内容 QING24:
MOV R5,#0
MOV 50H,#00H
MOV R1,#50H
CLR ET0
LCALL SEND_CLR
SETB ET0
LJMP TTR ;**************************************************************************** ;发送n字节程序:SEND_NBYTE ;发送的字节个数放入R3中,24c02器件内地址在R5中;发送缓冲区首址在r1中 ;**************************************************************************** SEND_NBYTE: MOV
R3,#NUMBYT LCALL STA MOV
A,#SLAW ;发送外围器件地址 LCALL SEND LCALL CACK JB
F0, SEND_NBYTE MOV
A,R5 ;从器件内地址 LCALL SEND LCALL CACK JB
F0,SEND_NBYTE WRDA: MOV A,@R1
;主发送缓冲区首址在R1中 LCALL SEND LCALL CACK JB
F0,SEND_NBYTE INC
R1 DJNZ
R3,WRDA LCALL
STP RET
;************************************************************************ ;接收n字节程序:READ_NBYTE |