实时时钟及数据闪存本实例应用的MCU(32P脚)没有副时钟功能,实时时钟只能用纯软件编写。
实时时钟计数器就采用8位。
秒是0~59十进制的值表示,通过毫秒计数器上溢进行递增计数。
分是0~59十进制的值表示,通过秒计数器上溢进行递增计数。
小时是0~23十进制的值表示,通过分计数器上溢进行递增计数。
日是取1~31十进制的值表示,通过小时计数器的上溢进行递增计数。
计数器进行以下的计数。
• 01~31 (1、 3、 5、 7、 8、 10、 12月)
• 01~30 (4、 6、 9、 11月)
• 01~29 (2月 闰年)
• 01~28 (2月 平年)
月是取1~12十进制的值表示,通过日计数器的上溢进行递增计数。
年是取0~99十进制的值表示,通过月计数器的上溢进行递增计数。
其中能被4整除的是闰年。
实时时钟处理子程序:
DATE_CONT:
MOVA,#0
MOVX,!YEARREG ; 年计数寄存器
XCHA,X
MOV!MDUC,#0X80
MOVWMDAH,#0X0
MOVWMDAL,AX
MOVWMDBH,#0X0
MOVWMDBL,#0X4 ; 年计数寄存器能被4整除是闰年 SET1!DIVST
DATE_LOP:
NOP
NOP
MOVA,!MDUC
BT A.0,$DATE_LOP ; 除运算结束
MOVWAX,!MDCL
CMPWAX,#0
BNZ$DATE_CNTA
SET1!YEAR_BIT ; 置闰年标志
BR $MONTH_STAR
DATE_CNTA:
CLR1!YEAR_BIT ; 清闰年标志
MONTH_STAR:
CMP!MONTHREG,#1 ; 月计数寄存器是1月
BZ $DAY31_CON
CMP!MONTHREG,#3 ; 月计数寄存器是3月
BZ $DAY31_CON
CMP!MONTHREG,#5 ; 月计数寄存器是5月
BZ $DAY31_CON
CMP!MONTHREG,#7 ; 月计数寄存器是7月
BZ $DAY31_CON
CMP!MONTHREG,#8 ; 月计数寄存器是8月
BZ $DAY31_CON
CMP!MONTHREG,#10 ; 月计数寄存器是10月
BZ $DAY31_CON
CMP!MONTHREG,#12 ; 月计数寄存器是12月
BZ $DAY31_CON
CMP!MONTHREG,#4 ; 月计数寄存器是4月
BZ $DAY30_CON
CMP!MONTHREG,#6 ; 月计数寄存器是6月
BZ $DAY30_CON
CMP!MONTHREG,#9 ; 月计数寄存器是9月
BZ $DAY30_CON
CMP!MONTHREG,#11 ; 月计数寄存器是11月
BZ $DAY30_CON
MOVA,!FLASHRG
BT A.7,$DAY29_CON
CMP!DAYREG,#28 ; 日计数寄存器=28天
BNC$MONTH_SET
RET
DAY29_CON:
CMP!DAYREG,#29 ; 日计数寄存器=29天
BNC$MONTH_SET
RET
DAY30_CON:
CMP!DAYREG,#30 ; 日计数寄存器=30天
BNC$MONTH_SET
RET
DAY31_CON:
CMP!DAYREG,#31 ; 日计数寄存器=31天
BNC$MONTH_SET
RET
MONTH_SET:
CMP!MONTHREG,#12 ; 月计数寄存器=12
BNC$YEAR_STRA
INC!MONTHREG ; 月计数寄存器+1
CLRB!DAYREG ; 日计数寄存器归零
RET
YEAR_STRA:
INC!YEARREG ; 年计数寄存器+1
CLRB!MONTHREG ; 月计数寄存器归零
RET
数据闪存的读写是通过一个《Data Flash Library Type04 CC-RL》库文件来完成的。
改文件中包含了一下程序:
_R_FDL_Init
_R_FDL_Read
_PFDL_Close
_R_FDL_ExecuteWrite
_R_FDL_ClearDataFlash
读数据程序在主程序MAIN中,以下是写数据子程序。
写数据到Flash处理子程序:
DAFW_CONT:
MOVA,!FLASHRG
BT A.0,$DAFW_STAR ; 允许写FLASH TO DAFW_STAR
RET
DAFW_STAR:
BT A.1,$DAFW_BLOCK ; 允许块清楚 TO DAFW_BLOCK
MOVWAX,!_g_write_address
CMPWAX,#0X1FFF ; 判断是否所有数据块都已写完
BC $DAFW_WINTS ; _g_write_address < 0X1FFF TO DAFW_WINTS
SET1!ERASES_BT ; 置块清楚标志
RET
DAFW_WINTS:
MOVWDTE,#0XAC
MOVWAX,!_g_write_address
NOP
CALL!_R_FDL_Init
NOP
CALL!_R_FDL_Write
NOP
CALL!_PFDL_Close
MOVWAX,!_g_write_address
ADDWAX,#2
MOVW!_g_write_address,AX
CLR1!FLASH_EN
RET
DAFW_BLOCK:
MOVWDTE,#0XAC
MOV!_g_block_valeu,#0
NOP
CALL!_R_FDL_Init
NOP
CALL!_R_FDL_Erase
CLRB!BLOCK_TIM
MOVWDTE,#0XAC
DAFW_BLOCK_S:
NOP
INC!BLOCK_TIM
CMP!BLOCK_TIM,#100
BC $DAFW_BLOCK_S
MOVWDTE,#0XAC
MOV!_g_block_valeu,#1
NOP
CALL!_R_FDL_Erase
NOP
CALL!_PFDL_Close
MOVWAX,#0
MOVW!_g_write_address,AX
CLR1!ERASES_BT ; 清块清楚标志
RET
好了,基本的子程序模块已分析完了,下篇开始介绍编译器的应用,并介绍初始化文件及主程序的文件。