自从有了存储器93C46,24C01,终于有了比较理想的不担心失电丢数据的存储器了!
单片机也有了内部储存用户数据区域,通过IAP操作,可实现数据长久保存,不用外挂存储器啦!
而市场上也有了号称与单片机系统速度同步的铁电存储器!
百花齐放的时代,有了更多选择!
单片机内部的可改写储存区,对一些大量的一次性写入数据来说,的确很不错!但是,写入之前必须擦除,且一次擦除512字节!对一些经常性需要改这改那的场合,就遇上一个小小的不方便,哪怕修改一个数,也得擦除512字节!与铁电存储器比较一下,才发现24C之类的覆盖改写是多么的宝贵!它不需任何擦除就可任意改写任一个数据!完全可以按照需要去选择.
最近做项目时,就遇上了这个问题.储存区域保存有几个手机号码,及一些语句,运行中随时需要更改某一个号码,或某一语句,处理起来不方便啦! --- 这时,覆盖改写是一大优势!
其次,存储器与单片机可以分离,也就方便通过其它工具(例如电脑或者编程器)进行批量操作与数据更新!
于是,也买来些FM24C128A铁电存储器,并且进行实际测试.
尽管网上有许多文章以及器件手册,可以参考学习,但是,没有实践的知识就都是人家的!
在测试中,按照最快速度去写入/读出,结果,一开始就发现有错误出现,(见图).
过去做一些仪表项目,存储器都是24C02便足够,而24C128容量就大了许多,前者仅仅256字节,后者是16000字节!并且,说是很快很快也心存疑惑,到底有多快?
经过多次实验,我使用的单片机一条指令执行时间为0.25us,首先发现是读出不用任何延时也没有什么问题,足够快!随后发现是每一次写完8位数据后,需要有一个延时! 于是.从小到大,逐步增加延时时间,当时间到达近1ms时,就完全正常了!
实验程序如下:
;==============================
;//FM24C128A读写测试程序 bjxs1508 2018-10-10 4:08
;-----------------------------------------------------------
P24DA EQU P12 ;引脚
P24CK EQU P13
P24DAM EQU P12M;工作模式寄存器
P24CKM EQU P13M
FC EQU C ;系统C标志
;--------------------------------
ARDSH DS 1;地址H
ARDSL DS 1;地址L
R DS 1;延时
TEMP DS 1;延时
RE24 DS 1;存放读出数据
WR24 DS 1;存放待写数据
;==============================
;******程序开始*******
.CODE
;;;;;; 初始化略;;;;;;;;;
;==============================
B_LOOP:
@RST_WDT
CALL B_WR24C ;写入256个字节:连续写入成功!
CALL B_RED24C ;读取256个字节;连续读出成功!
JMP B_LOOP
;================================
B_RED24C:
ZMN ARDSH,#3FH ;24C128最后1页256字节!
ZMN ARDSL,#0 ;低8位地址00开始使用
ZHLN #1,#00H
ZB0 FGIE;开中断
@@:
CALL B_RED24Z
MOV_ @HL,RE24
ZM0 RE24
INCMS L
INCMS ARDSL
JMP @B
RET
;===============================
B_WR24C:;写入数据
ZB0 FGIE;禁止中断
ZMN ARDSH,#3FH;24C128最后1页256字节!
ZMN ARDSL,#0
@@:
MOV_ WR24,#3EH ;256字节连续写入3EH
CALL B_WRE24C
CALL B_Delms ;960us延时仅此处调用!
INCMS ARDSL
JMP @B
RET
;============================
;FM24C128A读写子程序
;============================
B_WRE24C:
MOV_ R,#08H;防止出错,重复次数
B_WR24START:
CALL B_START
BS0 FC
JMP B_RETESWR;如果总线无效跳转
MOV A,#0A0H ;0A0H 指定写操作
CALL B_Send ;发送器件地址
BS0 FC
JMP B_WRTOP ;没有应答跳转
MOV A,ARDSH ;发送地址高字节
CALL B_Send
BS0 FC
JMP B_WRTOP ;没有应答跳转
MOV A,ARDSL ;发送低字节地址
CALL B_Send
BS0 FC
JMP B_WRTOP ;没有应答跳转
MOV A,WR24 ;得到数据
CALL B_Send ;发送数据
BS0 FC
JMP B_WRTOP ;没有应答跳出
ZB0 FC ;清除错误标志
B_WRTOP:
CALL B_STOP
BS1 FC
JMP B_EXIT24B
B_RETESWR:
DECMS R
JMP B_WR24START
B_EXIT24B:
RET
;===============================
B_RED24Z:
MOV_ R,#08H ;重复次数
B_Reta:
CALL B_START
BS0 FC
JMP B_RET255
MOV A,#0A0H ;指定写操作
CALL B_Send
BS0 FC
JMP B_RETOP
MOV A,ARDSH
CALL B_Send
BS0 FC
JMP B_RETOP
MOV A,ARDSL
CALL B_Send
BS0 FC
JMP B_RETOP
JMP B_CRERE
B_RETOP:
CALL B_STOP
BS1 FC
JMP B_EXITB
B_RET255:
DECMS R
JMP B_Reta
B_EXITB:
RET
;==============================
B_CRERE:
MOV_ R,#08H ;防止出错,重复次数
B_CRE24:
CALL B_START
BS0 FC
JMP B_CRE250
MOV A,#0A1H;指定读操作
CALL B_Send
BS0 FC
JMP B_CTOP
CALL B_RE8B
CALL B_NAK
ZB0 FC
B_CTOP:
CALL B_STOP
BS1 FC
JMP B_EndRE
B_CRE250:
DECMS R
JMP B_CRE24
B_EndRE:
RET
;===============================
B_Send:
MOV RE24,A
MOV_ SSS,#8
ZB1 P24DAM
B_Sen01:
RLCM RE24
BS0 FC
ZB1 P24DA
BS1 FC
ZB0 P24DA
NOP
ZB1 P24CK
NOP
ZB0 P24CK
DECMS SSS
JMP B_Sen01
ZB0 P24DAM
NOP
ZB1 P24CK
NOP
ZB0 FC
BS0 P24DA
ZB1 FC
ZB0 P24CK
RET
;----------------------------------------------------------------
B_RE8B:
ZB0 P24DAM
MOV_ SSS,#8
B_RE8S:
NOP
ZB1 P24CK
NOP
ZB0 FC
BS0 P24DA
ZB1 FC
RLCM RE24
ZB0 P24CK
DECMS SSS
JMP B_RE8S
RET
;===============================
B_START:
ZB1 P24DAM
ZB1 P24CKM
ZB1 P24DA
ZB1 P24CK
NOP
BS1 P24DA
JMP B_ErrE
ZB0 P24DA
NOP
ZB0 P24CK
NOP
ZB0 FC
RET
B_ErrE:
NOP
ZB1 FC
RET
;----------------------------------------------------------
B_STOP:
ZB1 P24DAM
ZB0 P24DA
NOP
ZB1 P24CK
NOP
ZB1 P24DA
NOP
RET
;=============================
B_NAK:
ZB1 P24DAM
ZB1 P24DA
NOP
ZB1 P24CK
NOP
ZB0 P24CK
RET
;=============================
B_Delms:;时间太短会失败!---仅仅一处调用!
Z2MN TEMP,R,#15,#0H ;这个才会成功! 2018-10-10 0:42
@@: ;15*256*0.25=960us
DECMS R
JMP @B
DECMS TEMP
JMP @B
RET
;**********************************
ENDP
;********************************** |