;2002-03-21...26 ;9008D主板上编程28SF040芯片 ;8D_ALL.asm ;用串口收发的方式实现了对flash芯片sst28sf040的所有的接口操作! ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ;硬件引脚 LED_GRE_PIN .REG P1.6 LED_YEL_PIN .REG P1.5 LED_RED_PIN .REG P3.3 LED_IC1_PIN .REG P3.2 LED_IC2_PIN .REG P3.5 ;编程标志位 XRAM_BLOCK_BIT .REG 00H ;外部RAM块的选择(0/1) LADD_OVERFLOW_BIT .REG 01H ;逻辑地址溢出(=1) ;外部操作地址 FLASH_START_ADD .EQU 4000H ;器件起始地址 TEMP_DPTR_SADDR .EQU 0000H ;XRAM中公共数据存储区的起 始地址 XRAM_ADDH .EQU 00H ;操作FLASH所用的XRAM的起始地址 XRAM_ADDL .EQU 00H ;FLASH 操作的芯片寻址字节 FADD_PAGE .EQU 30H ;A14...A18 FADD_HIGH .EQU 31H ;A8 ...A13 FADD_LOW .EQU 32H ;A0 ...A7 ;FLASH 操作的逻辑字节 LADD_H3BIT .EQU 33H ;A16...A18 LADD_8TF .EQU 34H ;A8 ...A15 LADD_0T7 .EQU 35H ;A0 ...A7 P1_DATA .EQU 36H ;FOR P1 STATE P1_HIGH_3BIT .EQU 37H ;保存P1.7...P1.5的状态 F_CHIP_ID_BYTE1 .EQU 38H ;SST公司标识字节 F_CHIP_ID_BYTE2 .EQU 39H ;28xx040芯片标识字节 ;常数 CONST_BLANK_CHAR .EQU 0FFH ;FLASH 擦除后的空白字符 CONST_TEST_DATA1 .EQU 55H ;测试XRAM的数据1 CONST_TEST_DATA2 .EQU 0AAH ;测试XRAM的数据2 CONST_CMD_CHIP_READ_ID .EQU 'I' ;读芯片ID命令,0 CONST_CMD_ERASE_CHIP .EQU 'E' ;芯片擦除命令,1 CONSR_CMD_ERASE_SECTOR .EQU 'e' ;扇区擦除命令,2 CONSR_CMD_READ_SECTOR .EQU 'R' ;扇区读取命令,3 CONSR_CMD_READ_BYTE .EQU 'r' ;字节读取命令,4 CONSR_CMD_WRITE_SECTOR .EQU 'W' ;扇区写入命令,5 CONSR_CMD_WRITE_BYTE .EQU 'w' ;字节写入命令,6 CONSR_CMD_BCHECK_CHIP .EQU 'V' ;芯片查空命令,7 CONSR_CMD_BCHECK_SECTOR .EQU 'v' ;扇区查空命令,8 ;出错返回的定义 ;命令接口中: OPERATE_SUCCESS .EQU 30H ;成功 ERR_CHIP_READ_ID .EQU 31H ;读芯片ID命令处理出错 ERR_ERASE_CHIP .EQU 32H ;芯片擦除命令处理出错 ERR_READ_BYTE .EQU 33H ;字节读取命令处理出错 ERR_READ_SECTOR .EQU 34H ;扇区读取命令处理出错 ERR_WRITE_SECTOR .EQU 35H ;扇区写入命令处理出错 ERR_ERASE_SECTOR .EQU 36H ;扇区擦除命令处理出错 ERR_BCHECK_SECTOR .EQU 37H ;扇区查空命令处理出错 ERR_BCHECK_CHIP .EQU 38H ;芯片查空命令处理出错 ERR_WRITE_BYTE .EQU 39H ;字节写入命令处理出错 ;串口子程序中: ERR_BYTE_RECV_TIMEOUT .EQU 40H ;串口字节接收超时出错 ERR_RECV_DATA_NOT_ALL .EQU 41H ;串口数据接收不完整出错 ERR_RECV_ILLEGAL_CMD .EQU 42H ;串口收到非法命令出错 ERR_RECV_ILLEGAL_ADDR .EQU 43H ;串口收到非法地址值出错 ;FLASH操作子程序中: ERR_FLASH_WRITE_TIMEOUT .EQU 50H ;FLASH写入等待超时 ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ORG 0000H LJMP MAIN ;======================================================= ORG 0040H MAIN: MOV IE,#00H MOV SP,#60H LCALL HD_LED_TEST_START LCALL COM_INIT_SET MOV P1_HIGH_3BIT,#0 PRE_START: MOV A,#1 LCALL HD_LIGHT_A_LED START: LCALL PUB_RECV_A_CMD JNC RECV_A_CMD MOV A,#ERR_RECV_ILLEGAL_CMD LCALL COM_SEND_BYTE LJMP START RECV_A_CMD: MOV A,#2 LCALL HD_LIGHT_A_LED LCALL PUB_GO_SUB MOV A,#2 LCALL HD_SHUT_A_LED LJMP PRE_START ;======================================================= ;ALL MODE ;这里的各个命令的相互关系是独立的,有上位机控制他们的次序! ;程序的命令接口层子程序,操作失败时才有出错的串口应答, ;操作成功先发送应答字节再发送数据串(如果有的话) ;------------------------------- ;字节的写入 ;入口:[LADD_H3BIT,LADD_8TF,LADD_0T7,写入字节值] ;出口:[串口应答字节] ;使用:[] ;------------------------------- CMD_BYTE_WRITE: LCALL COM_RECV_BYTE JNC CBW_1 CBW_0: MOV A,#ERR_BYTE_RECV_TIMEOUT LJMP CBW_17 CBW_1: MOV LADD_H3BIT,A LCALL COM_RECV_BYTE JNC CBW_3 LJMP CBW_0 CBW_3: MOV LADD_8TF,A MOV A,LADD_H3BIT ANL A,#0F8H JZ CBW_06 CBW_04: MOV A,#ERR_RECV_ILLEGAL_ADDR LJMP CBW_17 CBW_06: LCALL COM_RECV_BYTE JNC CBW_07 LJMP CBW_0 CBW_07: MOV LADD_0T7,A CBW_08: LCALL COM_RECV_BYTE JNC CBW_09 MOV A,#ERR_RECV_DATA_NOT_ALL LJMP CBW_15 CBW_09: PUSH ACC LCALL F_SDUP POP ACC LCALL F_WRITE_BYTE JC CBW_11 MOV A,#OPERATE_SUCCESS LJMP CBW_15 CBW_11: MOV A,#ERR_BCHECK_SECTOR CBW_15: PUSH ACC LCALL F_CHIP_RESET LCALL F_SDP POP ACC CBW_17: LCALL PUB_JUDGE_GIVE_RED LCALL COM_SEND_BYTE RET ;------------------------------- ;芯片的查空 ;入口:[无] ;出口:[串口应答字节] ;使用:[] ;------------------------------- CMD_CHIP_BCHECK: LCALL F_BCHECK_CHIP JC CCB_09 CCB_07: MOV A,#OPERATE_SUCCESS LJMP CCB_15 CCB_09: MOV A,#ERR_BCHECK_CHIP CCB_15: PUSH ACC LCALL F_CHIP_RESET POP ACC LCALL PUB_JUDGE_GIVE_RED LCALL COM_SEND_BYTE RET ;------------------------------- ;扇区的查空 ;入口:[LADD_H3BIT,LADD_8TF] ;出口:[串口应答字节] ;使用:[] ;------------------------------- CMD_SECTOR_BCHECK: LCALL COM_RECV_BYTE JNC CSB_41 CSB_40: MOV A,#ERR_BYTE_RECV_TIMEOUT LJMP CSB_57 CSB_41: MOV LADD_H3BIT,A LCALL COM_RECV_BYTE JNC CSB_43 LJMP CSB_40 CSB_43: MOV LADD_8TF,A MOV A,LADD_H3BIT ANL A,#0F8H JZ CSB_46 CSB_44: MOV A,#ERR_RECV_ILLEGAL_ADDR LJMP CSB_57 CSB_46: LCALL F_BCHECK_SECTOR JC CSB_49 CSB_47: MOV A,#OPERATE_SUCCESS LJMP CSB_55 CSB_49: MOV A,#ERR_BCHECK_SECTOR CSB_55: PUSH ACC LCALL F_CHIP_RESET POP ACC CSB_57: LCALL PUB_JUDGE_GIVE_RED LCALL COM_SEND_BYTE RET ;------------------------------- ;扇区的擦除 ;入口:[LADD_H3BIT,LADD_8TF] ;出口:[串口应答字节] ;使用:[] ;------------------------------- CMD_SECTOR_ERASE: LCALL COM_RECV_BYTE JNC CSE_1 CSE_0: MOV A,#ERR_BYTE_RECV_TIMEOUT LJMP CSE_17 CSE_1: MOV LADD_H3BIT,A LCALL COM_RECV_BYTE JNC CSE_3 LJMP CSE_0 CSE_3: MOV LADD_8TF,A MOV A,LADD_H3BIT ANL A,#0F8H JZ CSE_06 CSE_04: MOV A,#ERR_RECV_ILLEGAL_ADDR LJMP CSE_17 CSE_06: LCALL F_SDUP LCALL F_ERASE_SECTOR JC CSE_09 CSE_07: MOV A,#OPERATE_SUCCESS LJMP CSE_15 CSE_09: MOV A,#ERR_ERASE_SECTOR CSE_15: PUSH ACC LCALL F_CHIP_RESET LCALL F_SDP POP ACC CSE_17: LCALL PUB_JUDGE_GIVE_RED LCALL COM_SEND_BYTE RET ;------------------------------- ;扇区的写入 ;入口:[LADD_H3BIT,LADD_8TF,256字节的数据] ;出口:[串口应答字节] ;使用:[XRAM_BLOCK_BIT,TEMP_DPTR_SADDR] ;------------------------------- CMD_SECTOR_WRITE: LCALL COM_RECV_BYTE JNC CSW_1 CSW_0: MOV A,#ERR_BYTE_RECV_TIMEOUT LJMP CSW_15 CSW_1: MOV LADD_H3BIT,A LCALL COM_RECV_BYTE JNC CSW_3 LJMP CSW_0 CSW_3: MOV LADD_8TF,A MOV A,LADD_H3BIT ANL A,#0F8H JZ CSW_06 CSW_04: MOV A,#ERR_RECV_ILLEGAL_ADDR LJMP CSW_15 CSW_06: MOV R7,#0 MOV DPTR,#TEMP_DPTR_SADDR CLR XRAM_BLOCK_BIT LCALL COM_RECV_STRING JNC CSW_09 CSW_07: MOV A,#ERR_RECV_DATA_NOT_ALL LJMP CSW_15 CSW_09: MOV DPTR,#TEMP_DPTR_SADDR CLR XRAM_BLOCK_BIT LCALL F_WRITE_SECTOR JNC CSW_12 CSW_11: MOV A,#ERR_WRITE_SECTOR LJMP CSW_15 CSW_12: MOV A,#OPERATE_SUCCESS CSW_15: LCALL PUB_JUDGE_GIVE_RED LCALL COM_SEND_BYTE RET ;------------------------------- ;扇区的读取 ;入口:[LADD_H3BIT,LADD_8TF] ;出口:[串口应答字节,256字节值] ;使用:[XRAM_BLOCK_BIT,TEMP_DPTR_SADDR] ;------------------------------- CMD_SECTOR_READ: LCALL COM_RECV_BYTE JNC CSR_1 CSR_0: MOV A,#ERR_BYTE_RECV_TIMEOUT CSR_00: LCALL PUB_JUDGE_GIVE_RED LCALL COM_SEND_BYTE RET CSR_1: MOV LADD_H3BIT,A LCALL COM_RECV_BYTE JNC CSR_3 LJMP CSR_0 CSR_3: MOV LADD_8TF,A MOV A,LADD_H3BIT ANL A,#0F8H JZ CSR_06 CSR_04: MOV A,#ERR_RECV_ILLEGAL_ADDR LJMP CSR_00 CSR_06: CLR XRAM_BLOCK_BIT MOV DPTR,#TEMP_DPTR_SADDR LCALL F_READ_SECTOR MOV A,#OPERATE_SUCCESS CSR_09: LCALL COM_SEND_BYTE MOV R7,#0 MOV DPTR,#TEMP_DPTR_SADDR CLR XRAM_BLOCK_BIT LCALL COM_SEND_STRING RET ;------------------------------- ;字节读取 ;入口:[LADD_H3BIT,LADD_8TF,LADD_0T7] ;出口:[串口应答字节,字节值] ;------------------------------- CMD_BYTE_READ: LCALL COM_RECV_BYTE JNC CRAB_1 CRAB_0: MOV A,#ERR_BYTE_RECV_TIMEOUT CRAB_90: LCALL PUB_JUDGE_GIVE_RED LCALL COM_SEND_BYTE RET CRAB_1: MOV LADD_H3BIT,A ANL A,#0F8H JZ CRAB_2 MOV A,#ERR_RECV_ILLEGAL_ADDR LJMP CRAB_90 CRAB_2: LCALL COM_RECV_BYTE JNC CRAB_3 LJMP CRAB_0 CRAB_3: MOV LADD_8TF,A LCALL COM_RECV_BYTE JNC CRAB_6 LJMP CRAB_0 CRAB_6: MOV LADD_0T7,A LCALL F_READ_A_BYTE PUSH ACC MOV A,#OPERATE_SUCCESS LCALL COM_SEND_BYTE POP ACC LCALL COM_SEND_BYTE RET ;------------------------------- ;芯片擦除 ;入口:[无] ;出口:[串口应答字节] ;------------------------------- CMD_CHIP_ERASE: LCALL F_SDUP LCALL F_ERASE_CHIP JNC CCE_03 MOV A,#ERR_ERASE_CHIP LJMP CCE_05 CCE_03: MOV A,#OPERATE_SUCCESS CCE_05: PUSH ACC LCALL F_CHIP_RESET LCALL F_SDP POP ACC LCALL PUB_JUDGE_GIVE_RED LCALL COM_SEND_BYTE RET ;------------------------------- ;读芯片ID ;入口:[无] ;出口:[串口应答字节,F_CHIP_ID_BYTE1/2] ;------------------------------- CMD_READ_CHIP_ID: LCALL F_READ_CHIP_ID MOV A,#OPERATE_SUCCESS LCALL COM_SEND_BYTE MOV A,F_CHIP_ID_BYTE1 LCALL COM_SEND_BYTE MOV A,F_CHIP_ID_BYTE2 LCALL COM_SEND_BYTE RET ;========================================================== ;串口子程序 ;------------------------------ ;通过串口接收一个定长字符串存放到外部RAM ;入口: [DPTR,R7,XRAM_BLOCK_BIT] ;出口: [C=1 500ms接收超时,C=0 正确] ;使用: [ACC,DPTR,C] ;------------------------------ COM_RECV_STRING: LCALL HD_SELECT_XRAM LCALL HD_XRAM_PAGE_SEL CRS_0: LCALL COM_RECV_BYTE JNC CRS_3 RET CRS_3: MOVX @DPTR,A INC DPTR DJNZ R7,CRS_0 CLR C RET ;------------------------------ ;通过串口发送一个存储在外部RAM的定长字符串 ;入口: [DPTR,R7,XRAM_BLOCK_BIT] ;出口: [C=1 500ms发送超时,C=0 正确] ;使用: [ACC,DPTR,C] ;------------------------------ COM_SEND_STRING: LCALL HD_SELECT_XRAM LCALL HD_XRAM_PAGE_SEL CSS_1: MOVX A,@DPTR LCALL COM_SEND_BYTE JNC CSS_3 RET CSS_3: INC DPTR DJNZ R7,CSS_1 CLR C RET ;------------------------------ ;通过串口限时接收一个字节 ;入口: [无] ;出口: [Acc, C=1 500ms接收超时,C=0 正确] ;使用: [ACC,DPH,DPL,SBUF,C,RI] ;------------------------------ COM_RECV_BYTE: PUSH DPH PUSH DPL CRB_03: MOV DPH,#250 CRB_06: MOV DPL,#250 ;2US CRB_09: NOP ;1 NOP ;1 NOP ;1 NOP ;1 JBC RI,CRB_15 ;2US DJNZ DPL,CRB_09 ;2US DJNZ DPH,CRB_06 ;2US CRB_12: SETB C ;TIMEOUT=(8*250+4)*250 us=500ms LJMP CRB_18 CRB_15: MOV A,SBUF PUSH ACC MOV A,#4 LCALL HD_FLUSH_A_LED POP ACC CLR C CRB_18: POP DPL POP DPH RET ;------------------------------ ;通过串口限时发送一个字节 ;入口: [Acc] ;出口: [C=1 500ms发送超时,C=0 正确] ;使用: [ACC,DPH,DPL,SBUF,C,TI] ;------------------------------ COM_SEND_BYTE: PUSH DPH PUSH DPL CLR TI MOV SBUF,A PUSH ACC MOV A,#5 LCALL HD_FLUSH_A_LED POP ACC CSB_03: MOV DPH,#250 CSB_06: MOV DPL,#250 ;2US CSB_09: NOP ;1 NOP ;1 NOP ;1 NOP ;1 JBC TI,CSB_15 ;2US DJNZ DPL,CSB_09 ;2US DJNZ DPH,CSB_06 ;2US CSB_12: SETB C ;TIMEOUT=(8*250+4)*250 us=500ms LJMP CSB_18 CSB_15: CLR C CSB_18: POP DPL POP DPH RET ;-------------------------------------------- ;入口:[无] ;出口:[无] ;使用:[Acc,TR1,TH1,TL1,TMOD,PCON,SCON] ;串口初始化程序: 9600,8,1,n(f=11.0592MHz) ;-------------------------------------------- COM_INIT_SET: PUSH ACC CLR TR1 MOV A,TMOD ANL A,#0FH ORL A,#20H MOV TMOD,A MOV TH1,#0FDH MOV TL1,#0FDH MOV PCON,#00H MOV SCON,#50H CLR RI CLR TI SETB TR1 POP ACC RET ;========================================================== ;硬件操作模块 ;-------------------------------- ;延时100us ;-------------------------------- PUB_DELAY_100us: PUSH ACC CLR A PD100_0: INC A CJNE A,#27,PD100_0 POP ACC NOP NOP RET ;------------------------------------------------------------------------------ ;入口 [无] ;出口 [无] ;使用 [A] ;------------------------------------------------------------------------------ PUB_DELAY_1ms: PUSH ACC CLR A PD1_0: INC A NOP CJNE A,#228,PD1_0 POP ACC RET ;------------------------------------------------------------------------------ ;入口 [A] ;出口 [无] ;使用 [A] ;------------------------------------------------------------------------------ PUB_DELAY_100ms: PUSH ACC MOV A,#100 PD250: LCALL PUB_DELAY_1ms DEC A JNZ PD250 POP ACC RET ;------------------------------- ;测试如果是出错应答则红灯闪烁三次 ;------------------------------- PUB_JUDGE_GIVE_RED: CJNE A,#OPERATE_SUCCESS,JGR_0 RET JGR_0: LCALL PUB_FLUSH_RED_TRHEE RET ;------------------------------- ;开机时灯的测试 ;灯全部关闭,依次点亮,依次关闭 ;------------------------------- HD_LED_TEST_START: LCALL HD_LED_ALL_OFF LCALL PUB_DELAY_100ms SETB LED_GRE_PIN LCALL PUB_DELAY_100ms SETB LED_YEL_PIN LCALL PUB_DELAY_100ms SETB LED_RED_PIN LCALL PUB_DELAY_100ms SETB LED_IC1_PIN LCALL PUB_DELAY_100ms SETB LED_IC2_PIN LCALL PUB_DELAY_100ms CLR LED_GRE_PIN LCALL PUB_DELAY_100ms CLR LED_YEL_PIN LCALL PUB_DELAY_100ms CLR LED_RED_PIN LCALL PUB_DELAY_100ms CLR LED_IC1_PIN LCALL PUB_DELAY_100ms CLR LED_IC2_PIN RET ;------------------------------- ;红灯闪烁三次 ;入口:[无] ;出口:[无] ;使用:[Acc,PUB_DELAY_100ms] ;------------------------------- PUB_FLUSH_RED_TRHEE: SETB LED_RED_PIN LCALL PUB_DELAY_100ms CLR LED_RED_PIN LCALL PUB_DELAY_100ms SETB LED_RED_PIN LCALL PUB_DELAY_100ms CLR LED_RED_PIN LCALL PUB_DELAY_100ms SETB LED_RED_PIN LCALL PUB_DELAY_100ms CLR LED_RED_PIN RET ;------------------------------- ;闪烁一个指定的灯 ;入口:[Acc=1,2,3,4,5表示绿/黄/红/IC1/IC2灯] ;出口:[无] ;使用:[Acc,PUB_DELAY_100us] ;------------------------------- HD_FLUSH_A_LED: CJNE A,#1,HFAL_2 SETB LED_GRE_PIN LCALL PUB_DELAY_100us LCALL PUB_DELAY_100us CLR LED_GRE_PIN RET HFAL_2: CJNE A,#2,HFAL_3 SETB LED_YEL_PIN LCALL PUB_DELAY_100us LCALL PUB_DELAY_100us CLR LED_YEL_PIN RET HFAL_3: CJNE A,#3,HFAL_4 SETB LED_RED_PIN LCALL PUB_DELAY_100us LCALL PUB_DELAY_100us CLR LED_RED_PIN RET HFAL_4: CJNE A,#4,HFAL_5 SETB LED_IC1_PIN LCALL PUB_DELAY_100us LCALL PUB_DELAY_100us CLR LED_IC1_PIN RET HFAL_5: CJNE A,#5,HFAL_6 SETB LED_IC2_PIN LCALL PUB_DELAY_100us LCALL PUB_DELAY_100us CLR LED_IC2_PIN HFAL_6: RET ;------------------------------- ;点亮一个指定的灯 ;入口:[Acc=1,2,3,4,5表示绿/黄/红/IC1/IC2灯] ;出口:[无] ;------------------------------- HD_LIGHT_A_LED: CJNE A,#1,HLAL_2 SETB LED_GRE_PIN MOV A,P1_HIGH_3BIT SETB ACC.6 MOV P1_HIGH_3BIT,A RET HLAL_2: CJNE A,#2,HLAL_3 SETB LED_YEL_PIN MOV A,P1_HIGH_3BIT SETB ACC.5 MOV P1_HIGH_3BIT,A RET HLAL_3: CJNE A,#3,HLAL_4 SETB LED_RED_PIN RET HLAL_4: CJNE A,#4,HLAL_5 SETB LED_IC1_PIN RET HLAL_5: CJNE A,#5,HLAL_6 SETB LED_IC2_PIN HLAL_6: RET ;------------------------------- ;熄灭一个指定的灯 ;入口:[Acc=1,2,3,4,5表示绿/黄/红/IC1/IC2灯] ;出口:[无] ;------------------------------- HD_SHUT_A_LED: CJNE A,#1,HSAL_2 CLR LED_GRE_PIN MOV A,P1_HIGH_3BIT CLR ACC.6 MOV P1_HIGH_3BIT,A RET HSAL_2: CJNE A,#2,HSAL_3 CLR LED_YEL_PIN MOV A,P1_HIGH_3BIT CLR ACC.5 MOV P1_HIGH_3BIT,A RET HSAL_3: CJNE A,#3,HSAL_4 CLR LED_RED_PIN RET HSAL_4: CJNE A,#4,HSAL_5 CLR LED_IC1_PIN RET HSAL_5: CJNE A,#5,HSAL_6 CLR LED_IC2_PIN HSAL_6: RET ;------------------------------- ;所有灯都关闭 ;入口:[无] ;出口:[无] ;------------------------------- HD_LED_ALL_OFF: CLR LED_GRE_PIN CLR LED_YEL_PIN CLR LED_RED_PIN CLR LED_IC1_PIN CLR LED_IC2_PIN RET ;------------------------------- ;所有灯都打开 ;入口:[无] ;出口:[无] ;------------------------------- HD_LED_ALL_ON: SETB LED_GRE_PIN SETB LED_YEL_PIN SETB LED_RED_PIN SETB LED_IC1_PIN SETB LED_IC2_PIN RET ;------------------------------------- ;对FLASH操作的逻辑地址加1 ;输入:[LADD_H3BIT,LADD_8TF,LADD_0T7] ;输出:[LADD_H3BIT,LADD_8TF,LADD_0T7,LADD_OVERFLOW_BIT=1 OVERFLOW] ;使用:[ACC,C] ;------------------------------------- F_INC_LADD: CLR C MOV A,#1 ADDC A,LADD_0T7 MOV LADD_0T7,A MOV A,LADD_8TF ADDC A,#0 MOV LADD_8TF,A MOV A,LADD_H3BIT ADDC A,#0 SETB LADD_OVERFLOW_BIT JBC ACC.3,FIL_RESET_ADD CLR LADD_OVERFLOW_BIT FIL_RESET_ADD: MOV LADD_H3BIT,A RET ;------------------------------- ;设置P1端口和DPTR的值 ;输入:[FADD_PAGE,FADD_HIGH,FADD_LOW] ;输出:[P1_DATA,DPTR] ;使用:[ACC,B,P1_HIGH_3BIT] ;------------------------------- F_GET_P1_DATA_AND_DPTR: MOV A,FADD_PAGE ANL A,#1FH MOV FADD_PAGE,A MOV A,P1_HIGH_3BIT ANL A,#0E0H ORL A,FADD_PAGE MOV P1_DATA,A MOV DPH,FADD_HIGH MOV DPL,FADD_LOW RET ;----------------------------------- ;将FLASH的逻辑操作地址转换为芯片工作地址 ;入口:[LADD_H3BIT,LADD_8TF,LADD_0T7] ;出口:[FADD_PAGE,FADD_HIGH,FADD_LOW] ;使用:[ACC,B] ;----------------------------------- F_LADD_TO_FADD: MOV FADD_LOW,LADD_0T7 MOV B,LADD_8TF MOV A,LADD_H3BIT JBC B.7,FLTF_2 CLR ACC.7 LJMP FLTF_3 FLTF_2: SETB ACC.7 FLTF_3: JBC B.6,FLTF_5 CLR ACC.6 LJMP FLTF_6 FLTF_5: SETB ACC.6 FLTF_6: SETB B.6 MOV FADD_HIGH,B RL A RL A MOV FADD_PAGE,A RET ;------------------------------- ;操作P1口,进行外部RAM的块的选择 ;入口:[XRAM_BLOCK_BIT=0/1(2块)] ;出口:[无] ;------------------------------- HD_XRAM_PAGE_SEL: JB XRAM_BLOCK_BIT,SEL_PAGE1 SEL_PAGE0: CLR P1.4 RET SEL_PAGE1: SETB P1.4 RET ;------------------------------- ;使外部RAM的使能有效 ;入口:[无] ;出口:[无] ;------------------------------- HD_SELECT_XRAM: CLR P2.6 CLR P2.7 RET ;------------------------------- ;使外部ROM(flash)的使能有效 ;入口:[无] ;出口:[无] ;------------------------------- HD_SELECT_FLASH: HD_SELECT_XROM: SETB P2.6 CLR P2.7 RET ;========================================================== ;命令接口的分解部分 ;========================================================== ;------------------------------------- ;写入FLASH的一个字节 ;输入:[LADD_H3BIT,LADD_8TF,LADD_0T7,Acc 数据值] ;输出:[C=0 成功, C=1 失败] ;使用: [Acc,DPTR,F_LADD_TO_FADD,F_GET_P1_DATA_AND_DPTR,P1_DATA,FLASH_START_ADD,WAIT_WR_ END] ;------------------------------------- F_WRITE_BYTE: PUSH DPH PUSH DPL PUSH ACC LCALL F_LADD_TO_FADD LCALL F_GET_P1_DATA_AND_DPTR MOV P1,P1_DATA PUSH DPH PUSH DPL MOV DPTR,#FLASH_START_ADD MOV A,#10H MOVX @DPTR,A POP DPL POP DPH POP ACC MOVX @DPTR,A LCALL F_WAIT_WR_END POP DPL POP DPH RET ;------------------------------------- ;芯片的查空 ;输入:[无] ;输出:[C=0 成功, C=1 失败] ;使用:[Acc,DPTR,C,LADD_H3BIT,LADD_8TF,F_BCHECK_SECTOR] ;------------------------------------- F_BCHECK_CHIP: PUSH DPH PUSH DPL MOV LADD_H3BIT,#0 MOV LADD_8TF,#0 CLR LADD_OVERFLOW_BIT FBC_01: LCALL F_BCHECK_SECTOR JNC FBC_03 LJMP FBC_OUT FBC_03: JNB LADD_OVERFLOW_BIT,FBC_01 CLR C FBC_OUT: POP DPL POP DPH RET ;------------------------------------- ;扇区的查空 ;输入:[扇区号LADD_H3BIT,LADD_8TF] ;输出:[C=0 成功, C=1 失败,输入参数已经更改] ;使用:[Acc,R7,DPTR] ;------------------------------------- F_BCHECK_SECTOR: PUSH DPH PUSH DPL MOV R7,#0 MOV LADD_0T7,#0 FBS_NEXT_BYTE: LCALL F_READ_A_BYTE CJNE A,#CONST_BLANK_CHAR,FBS_ERR LCALL F_INC_LADD DJNZ R7,FBS_NEXT_BYTE CLR C LJMP FBS_OUT FBS_ERR: SETB C FBS_OUT: POP DPL POP DPH RET ;------------------------------------- ;扇区的擦除 ;输入:[扇区号LADD_H3BIT,LADD_8TF] ;输出:[C=0 成功, C=1 失败,输入参数已经更改] ;使用: [Acc,R7,DPTR,F_WRITE_A_BYTE,F_INC_LADD,HD_XRAM_PAGE_SEL,HD_SELECT_FLASH/XRAM,F_W AIT_WR_END] ;DPTR地址范围:0000H...3FFFH ;------------------------------------- F_ERASE_SECTOR: PUSH DPH PUSH DPL MOV LADD_0T7,#0 LCALL F_LADD_TO_FADD LCALL F_GET_P1_DATA_AND_DPTR MOV P1,P1_DATA PUSH DPH PUSH DPL LCALL HD_SELECT_FLASH MOV DPTR,#FLASH_START_ADD MOV A,#20H MOVX @DPTR,A LCALL HD_SELECT_XRAM LCALL HD_SELECT_FLASH POP DPL POP DPH MOV A,#0D0H MOVX @DPTR,A MOV R7,#100 FSE_WAIT: LCALL F_WAIT_WR_END JNC FSE_OUT DJNZ R7,FSE_WAIT SETB C FSE_OUT: POP DPL POP DPH RET ;------------------------------------- ;写入FLASH的一个扇区 ;输入:[扇区地址LADD_H3BIT,LADD_8TF,XRAM的地址DPTR,XRAM_BLOCK_BIT] ;输出:[C=0 成功, C=1 失败,输入参数已经更改] ;使用: [Acc,B,DPTR,F_WRITE_A_BYTE,F_INC_LADD,HD_XRAM_PAGE_SEL,HD_SELECT_FLASH/XRAM] ;DPTR地址范围:0000H...3FFFH ;------------------------------------- F_WRITE_SECTOR: MOV LADD_0T7,#0 MOV B,#0 FWS_NEXT: PUSH B LCALL HD_XRAM_PAGE_SEL LCALL HD_SELECT_XRAM MOVX A,@DPTR INC DPTR PUSH DPH PUSH DPL PUSH ACC LCALL F_SDUP POP ACC LCALL F_WRITE_BYTE JC FWS_ERR LCALL F_CHIP_RESET LCALL F_SDP LCALL F_INC_LADD POP DPL POP DPH POP B DJNZ B,FWS_NEXT LCALL F_CHIP_RESET LCALL F_SDP CLR C RET FWS_ERR: LCALL F_CHIP_RESET LCALL F_SDP POP ACC POP DPL POP DPH POP B SETB C RET ;------------------------------------- ;读取FLASH的一个扇区(256字节)存放到指定的外部RAM ;输入:[扇区地址LADD_H3BIT,LADD_8TF,XRAM的地址DPTR,XRAM_BLOCK_BIT] ;输出:[输入参数已经更改] ;使用: [Acc,R7,DPTR,F_READ_A_BYTE,F_INC_LADD,HD_XRAM_PAGE_SEL,HD_SELECT_FLASH/XRAM] ;DPTR地址范围:0000H...3FFFH ;------------------------------------- F_READ_SECTOR: MOV LADD_0T7,#0 MOV R7,#0 FRS_NEXT: PUSH DPH PUSH DPL LCALL HD_SELECT_FLASH LCALL F_READ_A_BYTE PUSH ACC LCALL F_INC_LADD POP ACC POP DPL POP DPH LCALL HD_XRAM_PAGE_SEL LCALL HD_SELECT_XRAM MOVX @DPTR,A INC DPTR DJNZ R7,FRS_NEXT RET ;---------------------------------- ;读取FLASH的一个字节 ;输入:[LADD_H3BIT,LADD_8TF,LADD_0T7] ;输出:[Acc] ;使用:[Acc,DPTR,F_LADD_TO_FADD,F_GET_P1_DATA_AND_DPTR,P1_DATA,HD_SELECT_FLASH] ;---------------------------------- F_READ_A_BYTE: PUSH DPH PUSH DPL LCALL F_LADD_TO_FADD LCALL F_GET_P1_DATA_AND_DPTR MOV P1,P1_DATA LCALL HD_SELECT_FLASH MOVX A,@DPTR POP DPL POP DPH RET ;------------------------------------- ;芯片的擦除 ;输入:[无] ;输出:[C=0 成功,=1 失败] ;使用: [Acc,R7,DPTR,HD_SELECT_FLASH/XRAM,FLASH_START_ADD,F_WAIT_WR_END,F_CHIP_RESET] ;------------------------------------- F_ERASE_CHIP: PUSH DPH PUSH DPL LCALL HD_SELECT_FLASH MOV DPTR,#FLASH_START_ADD MOV A,#30H MOVX @DPTR,A LCALL HD_SELECT_XRAM LCALL HD_SELECT_FLASH MOV DPTR,#FLASH_START_ADD MOV A,#30H MOVX @DPTR,A MOV R7,#200 FEC_WAIT: LCALL F_WAIT_WR_END JNC FEC_OUT LCALL PUB_DELAY_100us DJNZ R7,FEC_WAIT SETB C FEC_OUT: POP DPL POP DPH RET ;------------------------------------- ;读取芯片ID的值 ;输入:[无] ;输出:[F_CHIP_ID_BYTE1/2] ;使用:[Acc,DPTR,FLASH_START_ADD,F_READ_A_BYTE,F_CHIP_RESET] ;------------------------------------- F_READ_CHIP_ID: PUSH DPH PUSH DPL MOV DPTR,#FLASH_START_ADD MOV A,#90H MOVX @DPTR,A MOV LADD_H3BIT,#00H MOV LADD_8TF,#00H MOV LADD_0T7,#00H LCALL F_READ_A_BYTE MOV F_CHIP_ID_BYTE1,A LCALL F_INC_LADD LCALL F_READ_A_BYTE MOV F_CHIP_ID_BYTE2,A LCALL F_CHIP_RESET POP DPL POP DPH RET ;========================================================== ;其他的FLASH操作子程序 ;------------------------------------- ;等待字节的写操作完毕 ;入口:[DPTR] ;出口:[C=0 成功, =1 出错] ;使用:[Acc,B,C,R6,DPTR] ;------------------------------------- F_WAIT_WR_END: MOV R6,#5 FWRE_NEXT: MOVX A,@DPTR ;2 MOV B,A ;1 MOVX A,@DPTR ;2 XRL A,B ;1 ANL A,#40H ;1 JB ACC.6,FWRE_JUDGE ;2 CLR C RET FWRE_JUDGE: DJNZ R6,FWRE_NEXT ;2 SETB C RET ;------------------------------------- ;进行软件数据保护SDP ;入口:[无] ;出口:[无] ;使用:[LADD_H3BIT,LADD_8TF,LADD_0T7] ;------------------------------------- F_SDP: PUSH LADD_H3BIT PUSH LADD_8TF PUSH LADD_0T7 MOV LADD_H3BIT,#0 MOV LADD_8TF,#18H MOV LADD_0T7,#23H LCALL F_READ_A_BYTE MOV LADD_0T7,#20H LCALL F_READ_A_BYTE MOV LADD_0T7,#22H LCALL F_READ_A_BYTE MOV LADD_8TF,#04H MOV LADD_0T7,#18H LCALL F_READ_A_BYTE MOV LADD_0T7,#1BH LCALL F_READ_A_BYTE MOV LADD_0T7,#19H LCALL F_READ_A_BYTE MOV LADD_0T7,#0AH LCALL F_READ_A_BYTE POP LADD_0T7 POP LADD_8TF POP LADD_H3BIT RET ;------------------------------------- ;解除软件数据保护SDUP ;入口:[无] ;出口:[无] ;使用:[LADD_H3BIT,LADD_8TF,LADD_0T7] ;------------------------------------- F_SDUP: PUSH LADD_H3BIT PUSH LADD_8TF PUSH LADD_0T7 MOV LADD_H3BIT,#0 MOV LADD_8TF,#18H MOV LADD_0T7,#23H LCALL F_READ_A_BYTE MOV LADD_0T7,#20H LCALL F_READ_A_BYTE MOV LADD_0T7,#22H LCALL F_READ_A_BYTE MOV LADD_8TF,#04H MOV LADD_0T7,#18H LCALL F_READ_A_BYTE MOV LADD_0T7,#1BH LCALL F_READ_A_BYTE MOV LADD_0T7,#19H LCALL F_READ_A_BYTE MOV LADD_0T7,#1AH LCALL F_READ_A_BYTE POP LADD_0T7 POP LADD_8TF POP LADD_H3BIT RET ;------------------------------------- ;进行28SF040的复位 ;入口:[无] ;出口:[无] ;使用:[ACC,DPTR,HD_SELECT_XRAM] ;------------------------------------- F_CHIP_RESET: PUSH DPH PUSH DPL MOV DPTR,#FLASH_START_ADD MOV A,#0FFH MOVX @DPTR,A LCALL HD_SELECT_XRAM POP DPL POP DPH RET ;------------------------------------- ;命令程序的跳转 ;入口:[R2命令代码0...8] ;出口:[无] ;使用:[Acc,R2,R3,DPTR] ;------------------------------------- PUB_GO_SUB: MOV DPTR,#CMD_TABLE MOV A,R2 ADD A,R2 MOV R3,A MOVC A,@A+DPTR XCH A,R3 INC A MOVC A,@A+DPTR MOV DPL,A MOV DPH,R3 CLR A JMP @A+DPTR CMD_TABLE: DW CMD_READ_CHIP_ID ;0 DW CMD_CHIP_ERASE DW CMD_SECTOR_ERASE DW CMD_SECTOR_READ ;3 DW CMD_BYTE_READ DW CMD_SECTOR_WRITE DW CMD_BYTE_WRITE ;6 DW CMD_CHIP_BCHECK DW CMD_SECTOR_BCHECK ;------------------------------------- ;第一命令字节的接收和分解 ;入口:[无] ;出口:[R2命令代码0...8,C=0 合法命令, C=1 非法命令] ;使用:[Acc,R2] ;------------------------------------- PUB_RECV_A_CMD: LCALL COM_RECV_BYTE JC PUB_RECV_A_CMD PRAC_1: CJNE A,#CONST_CMD_CHIP_READ_ID,PRAC_3 MOV R2,#0 RET PRAC_3: CJNE A,#CONST_CMD_ERASE_CHIP,PRAC_6 MOV R2,#1 RET PRAC_6: CJNE A,#CONSR_CMD_ERASE_SECTOR,PRAC_9 MOV R2,#2 RET PRAC_9: CJNE A,#CONSR_CMD_READ_SECTOR,PRAC_12 MOV R2,#3 RET PRAC_12: CJNE A,#CONSR_CMD_READ_BYTE,PRAC_15 MOV R2,#4 RET PRAC_15: CJNE A,#CONSR_CMD_WRITE_SECTOR,PRAC_18 MOV R2,#5 RET PRAC_18: CJNE A,#CONSR_CMD_WRITE_BYTE,PRAC_21 MOV R2,#6 RET PRAC_21: CJNE A,#CONSR_CMD_BCHECK_CHIP,PRAC_24 MOV R2,#7 RET PRAC_24: CJNE A,#CONSR_CMD_BCHECK_SECTOR,PRAC_27 MOV R2,#8 RET PRAC_27: SETB C RET ;=============== END ;===============