;=============================================================================== ; sd2400系列SRAM/EEPROM功能测试程序 ; 本程序功能如下: ; ; READ_TIME :读时间子程序 ; WRITE_TIME :写时间子程序 ; READ_TRIM :读调整寄存器程序 ; TIMEWRITE_ON :写允许打开 ; TIMEWRITE_OFF :写允许关闭 ; TIMESTATUS_INT16HZ:输出16hz频率中断 ; WRITE_EEFL :写EEPROM ; WRITESRAM :写SRAM ; READSRAM :读SRAM ; ; Last update:2007/11/06 ; 本程序仅供参考,如有问题请联系:陈工 0755-83246178,fax:83225561 ; 13922865036 chendw@whwave.com.cn http://www.whwave.com.cn ;=============================================================================== ;define the general register ;LED寄存器 DIG1 EQU 20H ;LED第一位缓冲器 DIG2 EQU 21H ; DIG3 EQU 22H ; DIG4 EQU 23H ; DIG5 EQU 24H ; DIG6 EQU 25H ; DIG7 EQU 26H ; DIG8 EQU 27H FLAG EQU 28H ;通用标志寄存器 ;BIT0=1, ACK ERR ;BIT0=0 ,ACK OK TRIM EQU 5EH YEAR EQU 36H ;年 MONTH EQU 35H ;月 DAY EQU 34H ;日 WEEK EQU 33H ;星期 HOUR EQU 32H ;小时 MINUTE EQU 31H ;分钟 SECOND EQU 30H ;秒 ;单片机与实时时钟间通信寄存器 TIMETEMP EQU 2EH ;时间数据缓存器 TIMETX EQU 43H ;时间数据发送寄存器 TIMERX EQU 44H ;时间数据接收寄存器 ;单片机与IIC通信寄存器 IICTEMP EQU 2FH ;IIC标志寄存器 SLAVE_ADD EQU 40H ;SD7218地址寄存器 DATAI1 EQU 41H DATAI2 EQU 42H TXBUF EQU 47H ;IIC数据发送寄存器 RXBUF EQU 48H ;IIC数据接收寄存器 KEYBUF EQU 49H ;键盘数据缓冲器 READDATA EQU 4FH ;SRAM寄存器 SRAMADD_LO EQU 52H ;SRAM地址低8位 SRAMADD_HI EQU 53H ;SRAM地址高8位 SRAMDATA EQU 54H ;写入SRAM内的数据 VERIFY_LO EQU 55H ;校验次数低八位 VERIFY_HI EQU 56H ;校验次数高八位 TYPE EQU 57H ;sd2400型号寄存器 EE_PAGE EQU 58H TEMP EQU 5CH ; CON_REG2 EQU 5FH ;sd2400的控制寄存器 VAL_CON_REG2_12 EQU 0H ;12H VAL_CON_REG2_24 EQU 20H ;24H ;-------------------------------------------------------------------------- ;define time device address sd2400_R EQU 65H ;sd2400的器件地址(读) sd2400_W EQU 64H ;sd2400的器件地址(写) ;--------------------------------------------------------------------------- ;define port bit ;各通信口位代号 SDA EQU P3.1 ;IIC的SDA口线 SCL EQU P3.2 ;IIC的SCL口线 KEY EQU P3.0 ;键盘中断信号线 T_SDA EQU P3.4 ;sd2400的SDA口线 T_SCL EQU P3.5 ;sd2400的SCL口线 ST_SDA EQU P3.7 ;标准时间的SDA口线 ST_SCL EQU P3.3 ;标准时间的SCL口线 ;=========================================================================== ORG 0000H ;RESET LJMP START ;--------------------------------------------------------------------------- ORG 0100H START: CLR A ;开始初始化各寄存器 MOV IE,A ;关中断 MOV SP,#60H ;定义堆栈 CLR FLAG ;清除标志位 CLR VERIFY_LO LCALL LONGDELAY LCALL LONGDELAY ;延时,稳定电路 LCALL TIMESTATUS_INT16HZ ;----------------------------------------------------------------- LOOP: LCALL LONGDELAY ;DELAY 300MS LCALL READ_TIME JMP LOOP ;======================????????????????===================== ;??:????????????????????????? | ;??:???????????????????????? | ;??:NONE | ;????:A,R0,R1,TXBUF,YEAR,MONTH,DATE,DAY,HOUR,MINUTE,SECOND | ;=========================================================== WRITE_TIME: MOV 37H,#0h MOV 38H,#0h MOV 39H,#0h MOV 3AH,#0h MOV 3BH,#0h MOV 3CH,#0h MOV 3DH,#0h MOV 3EH,#0h MOV 3FH,#00H ; CLEAR THE RTC'RAM LCALL TIMEWRITE_ON LCALL T_IICSTART JB FLAG.1,T_ERR_IICSTOP ;如SDA线被箝位为低电平则退出 TIME_WRITE_1: MOV TIMETX,#sd2400_W ;发送写时钟sd2400的数据命令 LCALL T_SENDH_L JB FLAG.0,T_ERR_IICSTOP ;ACK信号不正常则退出. MOV TIMETX,#00H ;时间内部的起始地址 LCALL T_SENDH_L TIME_WRITE_2: MOV R0,#SECOND MOV R1,#7H WRTIME1:MOV A,@R0 MOV TIMETX,A LCALL T_SENDH_L INC R0 DJNZ R1,WRTIME1 LCALL T_IICSTOP LCALL T_IICSTART MOV TIMETX,#sd2400_W ;发送时钟sd2400的器件地址(写) LCALL T_SENDH_L MOV TIMETX,#12H ;设置时钟数据的内部起始地址为12H LCALL T_SENDH_L ; MOV TIMETX,#0H ;清12H的为0 LCALL T_SENDH_L LCALL T_IICSTOP LCALL TIMEWRITE_OFF RET ;==================读实时时钟实时数据寄存器子程序========================== ;功能:从实时时钟读入当前时间数据 | ;入口:NONE | ;出口:接收数据放在年、月、日、星期、时、分、秒各寄存器 | ;影响资源:A,R0,R3,TIMETX,TIMERX,YEAR,MONTH,DAY,WEEK,HOUR,MINUTE,SECOND | ;========================================================================== READ_TIME: RDTIME_LOOP: LCALL T_IICSTART JB FLAG.1,T_ERR_IICSTOP ;如SDA线被箝位为低电平则退出 MOV TIMETX,#sd2400_W ;发送写时钟sd2400的数据命令 LCALL T_SENDH_L JB FLAG.0,T_ERR_IICSTOP ;ACK信号不正常则退出. MOV TIMETX,#0H ;读时间内部的起始地址 LCALL T_SENDH_L LCALL T_IICSTART ;重新开始信号 MOV TIMETX,#sd2400_R ;发送读时钟sd2400的数据命令 LCALL T_SENDH_L MOV R0,#SECOND MOV R3,#7H RDTIME1: LCALL T_RXH_L MOV A,TIMERX MOV @R0,A INC R0 DJNZ R3,RDTIME2 ;读完一个字节数据后确认数据传输 JMP RDTIME3 ;若为最后一个字节数据则为NOACK RDTIME2: CALL T_ACK JMP RDTIME1 RDTIME3: CALL T_NOACK LCALL T_IICSTOP RDTIME_RET: ANL HOUR,#7FH ;屏蔽小时的最高位 RET T_ERR_IICSTOP: LCALL T_IICSTOP RET ;============================ACK=========================================== ;功能:延时 入口:NONE 出口:NONE | ;影响资源: | ;========================================================================== T_ACK: CLR TIMETEMP.1 LCALL T_BITOUT RET ;============================ACK=========================================== ;功能:延时 入口:NONE 出口:NONE | ;影响资源: | ;========================================================================== T_NOACK: SETB TIMETEMP.1 LCALL T_BITOUT RET ;===============================保存错误代码=============================== ;功能:保存MCU与IIC接口通信时的错误状态 | ;入口:TIMETEMP.0=ACK位缙? | ;出口:FLAG.0 =错误代码 | ;========================================================================== T_ACK_ERR: JNB TIMETEMP.0,T_ACK_ERR_RET ;检查ACK信号是否正常 SETB FLAG.0 ;置ACK出错标志位 T_ACK_ERR_RET: RET ;===============================启用IIC总线================================ ;功能:开启实时时钟的IIC总线 ;入口:NONE 出口:NONE ;影响资源:NONE ;========================================================================== T_IICSTART: CLR FLAG.1 SETB T_SDA SETB T_SCL LCALL DELAY JB T_SDA,T_IIC_SDAHI SETB FLAG.1 T_IIC_SDAHI: CLR T_SDA LCALL DELAY CLR T_SCL LCALL DELAY RET ;===============================关闭IIC总线================================ ;功能:关闭实时时钟IIC总线 ;入口:NONE 出口:NONE ;影响资源:NONE ;========================================================================== T_IICSTOP:CLR T_SDA SETB T_SCL LCALL DELAY SETB T_SDA LCALL DELAY RET ;============================发送一个字节,由高位到低位发送================ ;功能:从MCU发送一个字节给实时时钟,由高位到低位发送 | ;入口:发送数据放在TIMETX 出口:NONE | ;影响资源:A,R2,TIMETX | ;========================================================================== T_SENDH_L:MOV A,TIMETX MOV R2,#08H CLR FLAG.0 T_SENDH_L1: MOV C,ACC.7 MOV TIMETEMP.1,C LCALL T_BITOUT RL A DJNZ R2,T_SENDH_L1 LCALL T_BITIN LCALL T_ACK_ERR RET ;==========================发送一个字节,由低位到高位发送================== ;功能:从MCU发送一个字节给实时时钟,由低位到高位发送 | ;入口:发送数据放在TIMETX 出口:NONE | ;影响资源:A,R2,TIMETX | ;========================================================================== T_SENDL_H:MOV A,TIMETX MOV R2,#08H CLR FLAG.0 T_SENDL_H1: MOV C,ACC.0 MOV TIMETEMP.1,C LCALL T_BITOUT RR A DJNZ R2,T_SENDL_H1 LCALL T_BITIN LCALL T_ACK_ERR RET ;=================================接收一个字节============================= ;功能:MCU从IIC总线接收一个字节,MSB在前,LSB在后 | ;入口:NONE 出口:接收数据放在RXBUF中 | ;影响资源:A,R2,TIMEBIT,RXBUF | ;========================================================================== T_RXH_L:MOV R2,#08H T_RXH_L1: LCALL T_BITIN MOV C,TIMETEMP.0 MOV ACC.7,C RLC A DJNZ R2,T_RXH_L1 MOV TIMERX,A RET ;=================================接收一个字节============================= ;功能:MCU从IIC总线接收一个字节,LSB在前,MSB在后 | ;入口:NONE 出口:接收数据放在RXBUF中 | ;影响资源:A,R2,TIMEBIT,RXBUF | ;========================================================================== T_RXL_H:MOV R2,#08H T_RXL_H1: LCALL T_BITIN MOV C,TIMETEMP.0 RRC A DJNZ R2,T_RXL_H1 MOV TIMERX,A RET ;================================送出一位数================================ ;功能:从MCU发送一位数给实时时钟 | ;入口:发送位数放在EEPREM.1 出口:NONE | ;影响资源:A,TIMETEMP | ;========================================================================== T_BITOUT: MOV C,TIMETEMP.1 MOV T_SDA,C LCALL DELAY SETB T_SCL LCALL DELAY CLR T_SCL LCALL DELAY RET ;=================================读入一位数=============================== ;功能:MCU从实时时钟接收一位数 | ;入口:NONE 出口:接收位数放在TIMETEMP.0 | ;影响资源:A,TIMETEMP | ;========================================================================== T_BITIN: SETB T_SDA SETB T_SCL LCALL DELAY MOV C,T_SDA MOV TIMETEMP.0,C CLR T_SCL LCALL DELAY RET ;============================写状态寄存器程序============================== ;功能:读/写实时时钟状态寄存器,对其进行设置 | ;入口:NONE 出口:NONE | ;影响资源: A,TIMETX | ;========================================================================== TIMESTATUS_INT12OFF: LCALL TIMEWRITE_ON LCALL T_IICSTART MOV TIMETX,#sd2400_W ;发送时钟sd2400的器件地址(写) LCALL T_SENDH_L MOV TIMETX,#10H ;设置时钟数据的内部起始地址为10H LCALL T_SENDH_L MOV TIMETX,#10000000B ;向10H寄存器写数据,disable int output LCALL T_SENDH_L MOV TIMETX,#00000000B ;向11H寄存器写数据 LCALL T_SENDH_L MOV TIMETX,#00000000B ;向12H寄存器写数据,TURN OFF INTA/INTB LCALL T_SENDH_L MOV TIMETX,#00000000B ;向13H寄存器写数据,TURN OFF INTA/INTB LCALL T_SENDH_L LCALL T_IICSTOP LCALL TIMEWRITE_OFF RET ;----------------------------------- TIMEWRITE_ON: LCALL T_IICSTART JB FLAG.1,T1_ERR_IICSTOP ;如SDA线被箝位为低电平则退出 MOV TIMETX,#sd2400_W ;发送时钟sd2400的器件地址(写) LCALL T_SENDH_L MOV TIMETX,#10H ;设置时钟数据的内部起始地址为10H LCALL T_SENDH_L ; MOV TIMETX,#80H ;置10H的WRTC1为1 LCALL T_SENDH_L LCALL T_IICSTOP ; LCALL T_IICSTART JB FLAG.1,T1_ERR_IICSTOP ;如SDA线被箝位为低电平则退出 MOV TIMETX,#sd2400_W ;发送时钟sd2400的器件地址(写) LCALL T_SENDH_L MOV TIMETX,#0FH ;设置时钟数据的内部起始地址为0FH LCALL T_SENDH_L ; MOV TIMETX,#84H ;置0FH的WRTC2.WRTC3为1 LCALL T_SENDH_L LCALL T_IICSTOP ; RET ;----------------------------------- TIMEWRITE_OFF: LCALL T_IICSTART JB FLAG.1,T1_ERR_IICSTOP ;如SDA线被箝位为低电平则退出 MOV TIMETX,#sd2400_W ;发送时钟sd2400的器件地址(写) LCALL T_SENDH_L MOV TIMETX,#0FH ;设置时钟数据的内部起始地址为0FH LCALL T_SENDH_L ; MOV TIMETX,#0H ;置0FH的为0 LCALL T_SENDH_L MOV TIMETX,#0H ;置10H的为0 LCALL T_SENDH_L LCALL T_IICSTOP ; RET ;----------------------------------- TIMESTATUS_INT16HZ: LCALL TIMEWRITE_ON LCALL T_IICSTART MOV TIMETX,#sd2400_W ;发送时钟sd2400的器件地址(写) LCALL T_SENDH_L MOV TIMETX,#10H ;设置时钟数据的内部起始地址为10H LCALL T_SENDH_L MOV TIMETX,#0A1H ;向10H寄存器写数据,频率中断输出 LCALL T_SENDH_L MOV TIMETX,#06H ;向11H寄存器写数据,16hz LCALL T_SENDH_L LCALL T_IICSTOP LCALL TIMEWRITE_OFF RET ;----------------------------------- T1_ERR_IICSTOP: NOP RET ;==============================WRITE SRAM/EEPROM ========================== ;功能:把数据储存到sd2400的SRAM的全部地址中去 ;入口:数据首地址在A中,储存首地址在SRAMADD中,数据个数在SRAMNUM中 ;出口:无 ;影响资源:A,TIMETX,SRAMADD,R0,R1,SRAMNUM ;========================================================================== WRITESRAM: LCALL T_IICSTART JNB FLAG.1,SRAM_WRITE_1 LJMP SRAM_ERROR ;SDA线被箝位为低电平则退出 SRAM_WRITE_1: MOV TIMETX,#0A0H ;A2A1A0="000" LCALL T_SENDH_L ;SLAVE ADDRESS JNB FLAG.0,SRAM_WRITE_2 LJMP SRAM_ERROR ;ACK信号不正常则退出? SRAM_WRITE_2: MOV A,SRAMADD_LO ;RAM首地址在SRAMADD_LO中 MOV TIMETX,A ;WORD ADDRESS LCALL T_SENDH_L MOV A,TYPE CJNE A,#3,SRAM_WRITE_NODE1 ;sd2400DP JMP SRAM_WRITE_DE SRAM_WRITE_NODE1: CJNE A,#4,SRAM_WRITE_NODE ;sd2400EP SRAM_WRITE_DE: MOV A,#0 ;RAM首地址的低八位 MOV TIMETX,A ;WORD ADDRESS LCALL T_SENDH_L SRAM_WRITE_NODE: MOV A,SRAMADD_HI ;RAM页地址在SRAMADD_HI中 MOV R0,A WRITESRAM_PAGES: MOV A,#0 MOV R1,A ; WRITESRAM_LOOP: ;循环写入连续数据 MOV A,SRAMDATA MOV TIMETX,A LCALL T_SENDH_L DJNZ R1,WRITESRAM_LOOP DJNZ R0,WRITESRAM_PAGES LCALL T_IICSTOP RET ;==========================读取SRAM 数据子程序============================== ;功能:从SRAM中读取数据 ;入口:储存数据首地址在A中,SRAM读取数据首地址在SRAMADD中,数据个数在SRAMNUM中 ;出口:读取数据储存在CPU中 ;影响资源:A,TIMETX,SRAMADD,R0,R1,SRAMNUM,SRAMRX ;=========================================================================== READSRAM: LCALL T_IICSTART JNB FLAG.1,SRAM_READ_1 LJMP SRAM_ERROR ;SDA线被箝位为低电平则退出 SRAM_READ_1: MOV TIMETX,#0A0H ;A2A1A0="000" LCALL T_SENDH_L ;SLAVE ADDRESS JNB FLAG.0,SRAM_READ_2 LJMP SRAM_ERROR ;ACK信号不正常则退出? SRAM_READ_2: MOV A,SRAMADD_LO ;RAM首地址在SRAMADD_LO中 MOV TIMETX,A ;WORD ADDRESS LCALL T_SENDH_L MOV A,TYPE CJNE A,#3,SRAM_READ_NODE1 ;sd2400DP JMP SRAM_READ_DE SRAM_READ_NODE1: CJNE A,#4,SRAM_READ_NODE ;sd2400EP SRAM_READ_DE: MOV A,#0 ;RAM首地址的低八位 MOV TIMETX,A ;WORD ADDRESS LCALL T_SENDH_L SRAM_READ_NODE: LCALL T_IICSTART MOV A,#0A1H ;发送读操作指令 MOV TIMETX,A LCALL T_SENDH_L MOV A,SRAMADD_HI ;RAM页地址在SRAMADD_HI中 MOV R0,A CLR FLAG.7 ;清除RAM错误标志 MOV A,#0 MOV R1,A READSRAM_LOOP: ;循环读取数据 LCALL T_RXH_L MOV A,TIMERX CJNE A,SRAMDATA,SRAM_ERROR DJNZ R1,READSRAM_NEXT ;读完一个字节数据后确认数据传输 JMP READSRAM2 READSRAM_NEXT: CALL T_ACK JMP READSRAM_LOOP READSRAM2: DJNZ R0,READSRAM_NEXT ;PAGES READSRAM_INT: CALL T_NOACK LCALL T_IICSTOP RET SRAM_ERROR: SETB FLAG.7 JMP READSRAM_INT ;==============================WRITE 2K EEPROM ========================== ;功能:把数据储存到sd2400的EEPROM的全部地址中去 ;入口:数据首地址在A中,储存首地址在SRAMADD中,数据个数在SRAMNUM中 ;出口:无 ;影响资源:A,TIMETX,SRAMADD,R0,R1,SRAMNUM ;========================================================================== WRITE_EEFL: MOV R4,#0 ;PAGE SELECT WRITE_EEFL_LOOP: LCALL T_IICSTART JNB FLAG.1,EEFL_WRITE_1 LJMP SRAM_ERROR ;SDA线被箝位为低电平则退出 EEFL_WRITE_1: MOV A,R4 RL A ORL A,#0A0H ;&A2A1A0 MOV TIMETX,A LCALL T_SENDH_L ;SLAVE ADDRESS JNB FLAG.0,EEFL_WRITE_2 LJMP SRAM_ERROR ;ACK信号不正常则退出? EEFL_WRITE_2: MOV A,SRAMADD_LO ;RAM首地址在SRAMADD_LO中 MOV TIMETX,A ;WORD ADDRESS LCALL T_SENDH_L MOV A,SRAMADD_HI ;RAM页地址在SRAMADD_HI中 MOV R0,A WRITEEEFL_PAGES: MOV A,#0 MOV R1,A ; WRITEEEFL_LOOP: ;循环写入连续数据 MOV A,SRAMDATA MOV TIMETX,A LCALL T_SENDH_L LCALL DELAY10MS DJNZ R1,WRITEEEFL_LOOP DJNZ R0,WRITEEEFL_PAGES LCALL T_IICSTOP RET ;============================短延时子程序================================== ;功能:延时 入口:NONE 出口:NONE | ;影响资源:R7,PSW | ;========================================================================== DELAY: MOV R7,#2 DELAY1: NOP DJNZ R7,DELAY1 RET ;-------- DELAY_7218: MOV R7,#10 DELAY1_7218: NOP DJNZ R7,DELAY1_7218 RET LONGDELAY: ;DELAY 300MS MOV R6,#240 LD0: MOV R7,#250 ;5*250*240 LD1: NOP NOP NOP DJNZ R7,LD1 DJNZ R6,LD0 RET DELAY10MS: ;DELAY >10MS MOV R6,#11 LD00: MOV R7,#250 ;5*250*11 LD10: NOP NOP NOP DJNZ R7,LD10 DJNZ R6,LD00 RET END