⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 5045.asm

📁 Small RTOS51是为51系列单片机而编写的。它是完全免费的、源代码公开的多任务实时操作系统。它可在无任何外部数据存储器的单片80C51系统上运行
💻 ASM
字号:
;**************************************************
;    平凡单片机工作室
;  HTTP://WWW.MCUSTUDIO.COM
;   (C) COPYRIGHT 2003 PINGFAN'S MCUSTUDIO
;    ALL RIGHTS RESERVED
;205.ASM
;作者:周坚   
;功能描述:按平台模式写的X5045驱动程序
;**************************************************
;以下是一些常量,不需要更改
    WREN_INST   EQU     06H ;写允许命令字(WREN)
    WRDI_INST   EQU     04H ;写禁止命令字(WRDI)
    WRSR_INST   EQU     01H ;写状态寄存器命令字(WRSR)
    RDSR_INST   EQU     05H ;读状态寄存器命令字(RDSR)
    WRITE_INST  EQU     02H ;写存储器命令字 (WRITE)
    READ_INST   EQU     03H ;读存储器命令字 (READ)
    MAX_POLL    EQU     99H ;测试的最大次数
        
    WDT200      EQU     90H ;WD1 WD0=01
    WDT600      EQU     0A0H;WD1 WD0=10
    WDT1400     EQU     80H ;如果最高位是1代表设置看门狗WD1 WD0 =00
    NOWDT       EQU     0B0H;WD1 WD0=11
    PROQTR      EQU     04H ;BL1 BL0=01保护区域为高128字节
    PROHALF     EQU     08H ;BL1 BL0=10写保护区域为高256字节
    PROALL      EQU     0CH ;BL1 BL0=11写保护区域为整个存储器
    NOPRO       EQU     00H ;如果最高位是0,代表设置保护区域 BL1 BL0=00,不写保护
;以下引脚定义,根据实际情况更改
    SI      BIT     P2.2    ; 
    SCK     BIT     P2.3    ; 
    SO      BIT     P2.0    ; 
    WP      BIT     P2.1    ;
    CS      BIT     P2.4    ; 
;以下是一些单元定义,根据实际情况更改
    MTD         EQU 30H ;发送数据缓冲区
    MRD         EQU 30H ;接收数据缓冲区
    NUMBYT      EQU 2FH ;传送字节数存放单元
    STATBYT     EQU 2FH ;状态字节存放单元
    DATAADDR    EQU 2DH ;该单元及DATAADDR+1是待操作的EEPROM的地址单元,该位存入高1位地址,ADDRDATA+1单元存入低8位地址

;******************************************************************************************
;名称:写数据,将数据缓冲区的数据写入指定的地址
;描述:MTD指定数据缓冲区首地址,NUMBYT指定字节数,DATAADDR及DATAADDR+1指定被写器件地址
;不允许跨页
;使用资源:R0,R1,A,B
;数据写完,全部存储单元处于保护状V态
;******************************************************************************************
WRITE_DATA:
    MOV     R0,#DATAADDR    ;地址单元的高8位
    MOV     A,@R0
    MOV     DPH,A
    INC     R0
    MOV     A,@R0
    MOV     DPL,A
    MOV     R1,NUMBYT   ;从传送字节数存元中获取待写字节数   
    MOV     R0,#MTD     ;待写数据缓冲区
W_L:
    SETB    WP;
    CALL    WREN_CMD    ;写允许
    CLR     SCK         ;将SCK拉低
    CLR     CS          ;将/CS拉低
    MOV     A, #WRITE_INST
    MOV     B, DPH
    MOV     C, B.0
    MOV     ACC.3, C
    LCALL   OUTBYT      ;送出含有地址最高位的写指令
    MOV     A, DPL
    LCALL   OUTBYT      ;送出地址的低8位
    MOV     A, @R0
    LCALL   OUTBYT      ;送出数据
    CLR     SCK         ;将SCK拉低
    SETB    CS          ;升高/CS
    LCALL   WIP_POLL    ;测试是否已器件内部是否写完
    INC     DPL
    INC     R0
    DJNZ    R1,W_L
    MOV     STATBYT,#PROALL ;状态存放单元
    CALL    SET_STATUS  ;整个存储器均被保护
    RET

;******************************************************************************************
;名称:读数据,把指定地址单元中的数据读入数据缓冲区
;描述:MRD指定数据缓冲区首地址,NUMBYT指定字节数,DATAADDR及DATAADDR+1指定被写器件地址
;使用资源:B,R0,DPTR
;不允许跨页
;******************************************************************************************
READ_DATA:
    MOV     R0,#DATAADDR    ;地址单元的高8位
    MOV     A,@R0
    MOV     DPH,A
    INC     R0
    MOV     A,@R0
    MOV     DPL,A
    MOV     R1,NUMBYT   ;从传送字节数存元中获取待写字节数   
    MOV     R0,#MRD     ;待读数据缓冲区
R_L:    
    CLR     SCK         ; 将SCK拉低
    CLR     CS          ; 将/CS拉低
    MOV     A, #READ_INST
    MOV     B, DPH
    MOV     C, B.0
    MOV     ACC.3, C
    LCALL   OUTBYT      ; 送出含有地址最高位的读指令
    MOV     A, DPL
    LCALL   OUTBYT      ;送出低8位地址
    LCALL   INBYT       ; 读数据
    CLR     SCK         ; 将SCK拉低
    SETB    CS          ;升高/CS
    MOV     @R0,A
    INC     R0
    INC     DPL
    DJNZ    R1,R_L
    RET

;*******************************************************************************************
;名称;SET_STATUS  
;7  6   5   4   3   2   1   0
;0  0   WD1 WD0 BL1 BL0 WEL WIP
;如果需要设置保护和看门狗,需分两次进行
;STATBYT传递参数,共8个预定义常量
;资源使用:R0,R1,A,B
;*******************************************************************************************
SET_STATUS:
    CALL    RDSR_CMD    ;读当前寄存器的状态,在A中
    MOV     B,A     ;存入B
    MOV     A,STATBYT   ;读入参数
    JB      ACC.7,SET_WDT   ;如果最高位是1则转设置看门狗
    MOV     C,ACC.2     ;否则是设置保护区域
    MOV     B.2,C
    MOV     C,ACC.3
    MOV     B.3,C
    JMP     WRITE_STATUS
SET_WDT:
    MOV     C,ACC.4
    MOV     B.4,C
    MOV     C,ACC.5
    MOV     B.5,C
WRITE_STATUS:       
    CLR     SCK         ;将SCK拉低
    CLR     CS          ;将/CS拉低
    MOV     A, #WRSR_INST
    LCALL   OUTBYT      ;送出 WRSR 指令
    MOV     A, B
    LCALL   OUTBYT      ;送出状态寄存器的状态
    CLR     SCK         ;将SCK拉低
    SETB    CS          ;升高/CS
    LCALL   WIP_POLL    ;测试是否已器件内部是否写完
    RET

;*******************************************************************************************
;名称:WREN_CMD
;描述:写允许
;功能:这段程序发送命令允许写存储器单元和状态寄存器
;调用子程序: OUTBYT
;输入:没有
;输出:没有
;寄存器使用:A
;*******************************************************************************************
WREN_CMD:
    CLR     SCK     ;将SCK拉低
    CLR     CS      ;将 /CS 拉低
    MOV     A, #WREN_INST
    LCALL   OUTBYT  ;送出WREN_INST指令
    CLR     SCK     ;将SCK拉低
    SETB    CS      ;将 /CS 升高
    RET
;*******************************************************************************************
;名称:WRDI_CMD
;描述:写禁止
;功能:这段程序发送命令禁止对存储单元和状态寄存器写
;调用子程序:OUTBYT
;输入:无
;输出:无
;寄存器使用:A
;*******************************************************************************************
WRDI_CMD:
    CLR     SCK     ;将SCK拉低
    CLR     CS      ;将/CS拉低
    MOV     A, #WRDI_INST
    LCALL   OUTBYT  ;送出WRDI指令
    CLR     SCK     ;将SCK拉低
    SETB    CS      ;升高/CS
    RET
;*******************************************************************************************
;名称:RDSR_CMD
;描述:读状态寄存器
;功能:本程序发送命令用以读状态寄存器
;调用子程序:OUTBYT, INBYT
;输入:无
;输出:A= 状态寄存器
;寄存器使用:A
;*******************************************************************************************
RDSR_CMD:
    CLR     SCK         ;将SCK拉低
    CLR     CS          ;将/CS拉低
    MOV     A, #RDSR_INST
    LCALL   OUTBYT      ;发送 RDSR 指令
    LCALL   INBYT       ;读状态寄存器
    CLR     SCK         ;将SCK拉低
    SETB    CS          ;升高/CS
    RET
;*******************************************************************************************
;名称:RST_WDOG
;描述:复位看门狗定时器
;功能:这段程序用来复位看门狗定时器,不发送命令
;调用子程序:无
;输入:无
;输出:无
;寄存器使用:无
;*******************************************************************************************
RST_WDOG:
    CLR     CS      ;将 /CS 拉低
    SETB    CS      ;将 /CS 升高
RET
;*******************************************************************************************
;名称: WIP_POLL
;描述: 器件内部编程检查
;功能:本程序通过检查WIP位来确定X5045内部编程是否结束
;子程序调用: RDSR_CMD
;输入:无
;输出:无
;寄存器使用: R3, A
;*******************************************************************************************
WIP_POLL:
    MOV     R3, #MAX_POLL   ;设置用于偿试的最大次数
WIP_POLL1:
    LCALL   RDSR_CMD        ;读状态寄存器
    JNB     ACC.0, WIP_POLL2;如果WIP 位是 '0' 说明内部的写周期完成了
    DJNZ    R3, WIP_POLL1   ;如果WIP 位是 '1'说明内部写周期还没有完成
WIP_POLL2:
    RET
;*******************************************************************************************
;名称: OUTBYT
;描述:将一个字节送到EEPROM
;功能:本段程序移位送出一个字节,从最高位开始送PROM
;调用子程序:无
;输入:A = 待送的字节
;输出:无
;寄存器使用: R2, A
;*******************************************************************************************
OUTBYT:
    MOV     R2, #08     ;设置位计数(共8位)
OUTBYT1:
    CLR     SCK         ;将SCK拉低
    RLC     A           ;带进位位的左移位
    MOV     SI, C       ;送出进位位
    SETB    SCK         ;将 SCK 升高
    DJNZ    R2, OUTBYT1 ;循环8次
    CLR     SI          ;将SI置于已知的状态
    RET
;*******************************************************************************************
;名称: INBYT
;描述:从EEPROM中接收数据
;功能:这段程序从EEPROM中接收数据,高位在先
;调用子程序:无
;输入:无
;输出:A = 接收到的数据
;寄存器使用:R2, A
;*******************************************************************************************
INBYT:
    MOV     R2, #08     ;设置计数(共8位)
INBYT1:
    SETB    SCK         ;将 SCK 升高
    CLR     SCK         ;将SCK拉低
    MOV     C, SO       ;将输出线的状态读到进位位
    RLC     A           ;带进位位的循环左移
    DJNZ    R2, INBYT1  ;循环8次
    RET

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -