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

📄 csi24.asm

📁 用于CSI24串行EEPROM的读写通信子程序
💻 ASM
字号:
;*************************************************
 ACK BIT 10H ;应答标志位
 SLA DATA 50H ;器件从地址
 SUBA DATA 51H ;器件子地址
 NUMBYTE DATA 52H ;读写的字节数
;使用前定义常量
SDA EQU P3.3
SCL EQU P3.4
MTD EQU 40H ;发送数据缓冲区首址
MRD EQU 30H ;接收数据缓冲区首址(缓冲区30 3FH)
CSI24C021 EQU 0A0H ;定义器件地址
WRADR EQU 13H ;定义写入地址
WRDATA EQU 0F0H ;定义写入数据
RPCF8563 EQU 0A3H ;读从地址
WPCF8563 EQU 0A2H ;写从地址 
INT_R1 EQU 10H
INT_R0 EQU 11H
INT_R2 EQU 12H
VRXD  BIT P1.2
VTXD  BIT P1.1 
;*************************************************
        ORG     0000H
        LJMP    L0030
        ORG     0003H
        LJMP    INT0
        ORG     000BH
        LJMP    TIME0
        ORG     0023H
        LJMP    SEND
        ORG     0030H
L0030:  MOV     SP,#60H
L0035:  MOV     R1,#MTD
        MOV     40H,#02H
        MOV     41H,#03H
        MOV     42H,#04H
        MOV     43H,#05H
        MOV     44H,#06H
        MOV     45H,#07H
        MOV     46H,#08H
        MOV     47H,#09H
        MOV     48H,#02H
        MOV     R7,#08H
        MOV     R0,#MTD
        LCALL   MSIO
L0038:  LCALL   T1S
        LJMP    L0035
        RET
  T1S: MOV INT_R1,#0FFH 
 TSM3: MOV INT_R0,#0FFH
 TSM4: DJNZ INT_R0,TSM4
       DJNZ INT_R1,TSM3
       RET
T500mS: MOV INT_R2,#04H 
 TSM8: MOV INT_R1,#0FFH
 TSM5: MOV INT_R0,#0F0H
 TSM7: DJNZ INT_R0,TSM7
       DJNZ INT_R1,TSM5
       DJNZ INT_R2,TSM8
       RET
  T5S: MOV INT_R2,#01FH 
 TSM9: MOV INT_R1,#0FFH
 TSMA: MOV INT_R0,#0FFH
 TSMB: DJNZ INT_R0,TSMB
       DJNZ INT_R1,TSMA
       DJNZ INT_R2,TSM9
       RET
  T88: MOV INT_R1,#42H 
 TSM0: MOV INT_R0,#0FH
 TSM1: DJNZ INT_R0,TSM1
       DJNZ INT_R1,TSM0
       RET
T12mS: MOV INT_R1,#18H 
  TSM: MOV INT_R0,#0FFH
 TSM6: DJNZ INT_R0,TSM6
       DJNZ INT_R1,TSM
       RET
  INT0:  CLR   TR0
         MOV   TH0,#77H
         MOV   TL0,#88H
         SETB  TR0
         RETI
 TIME0:  CLR   TR0
         MOV   TH0,#77H
         MOV   TL0,#88H
         SETB  TR0
         SETB  00H
         RETI
  SEND:  CLR   RI
         RETI         
   MSIO: MOV R5,#09H
   XMIN: MOV A,@R0
    TX1: SETB VRXD       ;P2.5 置高
     TX: LCALL OUTPUT    ;调用发送子程序,将寄存器A 中内容发给2051
         INC  R0
         DJNZ R5,XMIN
         SETB VTXD       ;P2.4 置高
         RET
    XRX: MOV R0,#40H
     RX: LCALL  INPUT    ;调用接收子程序,将接收的N个数据存放在以40H开始的地址中
         MOV @R0,A
         INC R0
         DJNZ R5, RX     ;N 个数据接收结束,则等待,否则转RX 继续接收
         AJMP $
         RET
 DEL833: MOV R6 ,#03H
   MS11: DJNZ R6,MS11
         NOP
         RET
 OUTPUT: CLR C
         MOV VTXD,C         ;发送起始位
         LCALL DEL833      ;延时
         NOP
         MOV R3,#08H
    REP: RRC A
         MOV VTXD,C
         LCALL DEL833
         DJNZ R3,REP       ;发送8位数据
         SETB C            ;发送停止位
         MOV VTXD,C
         LCALL DEL833
         NOP
         NOP
         NOP
         RET
  INPUT: JB VRXD, $         ;判断是否有起始位出现
         LCALL DEL833
         MOV R3,#8
    OUT: MOV C,VRXD
         RRC A
         LCALL DEL833
         DJNZ R3,OUT       ;接收8位数据
         JNB VRXD,$        ;判断是否有停止位出现
         RET
NARD24C021:        ;立即地址读CSI24C021
          MOV SLA,#CSI24C021
          LCALL IRDBYTE ;读出值在ACC
          RET
RD24C021:          ;随机地址读CSI24C021
          MOV SLA,#CSI24C021
          MOV SUBA,#WRADR ;指定单元地址
          MOV NUMBYTE,#01H ;读出一字节数据
          LCALL IRDNBYTE
          MOV A,MRD
          RET
RDNB24C021:         ;连续读
          MOV SLA,#CSI24C021
          MOV SUBA,#10H ;指定起始地址10H
          MOV NUMBYTE,#20H ;读出32 字节数据
          LCALL IRDNBYTE ;读出数据依次放在接收缓冲区MRD
          RET
WRB24C021:        ;字节写CSI24C021
          MOV SLA,#CSI24C021 ;指定地址写单字节
          MOV SUBA,#WRADR ;指定单元地址
          MOV NUMBYTE,#01H ;写一字节数据
          MOV MTD,#WRDATA
          LCALL IWRNBYTE
          RET
WRNB24C021:         ;页写
          MOV R0,#MTD ;从地址00H 起写入16 个数据0
          MOV R4,#16
          CLR A
PWLOOP1:
          MOV @R0,A ;数据装载到发送缓冲区MTD
          INC R0
          INC A    
          DJNZ R4,PWLOOP1
          MOV SLA,#CSI24C021 ;指定地址写多字节
          MOV SUBA,#00 ;指定单元地址
          MOV NUMBYTE,#16 ;写入一页数据
          LCALL IWRNBYTE
          RET
RSTWDT:         ;复位看门狗
          CLR SDA ;喂狗脉冲
          NOP
          SETB SDA
          RET
START: SETB SDA  ;启动I2C 总线子程序
       NOP
       SETB SCL ;起始条件建立时间大于4.7us
       NOP
       NOP
       NOP
       NOP
       NOP
       CLR SDA
       NOP      ;起始条件锁定时大于4us
       NOP
       NOP
       NOP
       NOP
       CLR SCL  ;钳住总线准备发数据
       NOP
       RET
STOP:  CLR SDA   ;结束总线子程序
       NOP
       SETB SCL ;发送结束条件的时钟信号
       NOP      ;结束总线时间大于4us
       NOP
       NOP
       NOP
       NOP
       SETB SDA ;结束总线
       NOP;保证一个终止信号和起始信号的空闲时间大于4.7us
       NOP
       NOP
       NOP
       RET
MACK:  CLR SDA    ;发送应答信号子程序,将SDA 置0
       NOP
       NOP
       SETB SCL
       NOP        ;保持数据时间即SCL 为高时间大于4.7us
       NOP
       NOP
       NOP
       NOP
       CLR SCL
       NOP
       NOP
       RET
MNACK: SETB SDA   ;发送非应答信号,将SDA 置1
       NOP
       NOP
       SETB SCL
       NOP
       NOP       ;保持数据时间即SCL 为高时间大于4.7us
       NOP
       NOP
       NOP
       CLR SCL
       NOP
       NOP
       RET
CACK:  SETB SDA;检查应答位子程序,返回值ACK=1 时表示有应答
       NOP
       NOP
       SETB SCL
       CLR ACK
       NOP
       NOP
       MOV C,SDA
       JC CEND
       SETB ACK ;判断应答位
       CEND: NOP
       CLR SCL
       NOP
       RET
WRBYTE: MOV R0,#08H  ;发送字节子程序,字节数据放入ACC,
                     ;每发送一字节要调用一次CACK 子程序取应答位
  WLP: RLC A         ;取数据位
       JC WR1
       SJMP WR0      ;判断数据位
 WLP1: DJNZ R0,WLP
       NOP
       RET
  WR1: SETB SDA      ;发送1
       NOP
       SETB SCL
       NOP
       NOP
       NOP
       NOP
       NOP
       CLR SCL
       SJMP WLP1
  WR0: CLR SDA     ;发送0
       NOP
       SETB SCL
       NOP
       NOP
       NOP
       NOP
       NOP
       CLR SCL
       SJMP WLP1
RDBYTE: MOV R0,#08H
   RLP: SETB SDA
        NOP
        SETB SCL      ;时钟线为高接收数据位
        NOP
        NOP
        MOV C,SDA     ;读取数据位
        MOV A,R2
        CLR SCL       ;将SCL 拉低时间大于4.7us
        RLC A ;进行数据位的处理
        MOV R2,A
        NOP
        NOP
        NOP
        DJNZ R0,RLP ;未够8 位再来一次
        RET
IWRBYTE: PUSH ACC
IWBLOOP: LCALL START ;起动总线
         MOV A,SLA
         LCALL WRBYTE ;发送器件从地址
         LCALL CACK
         JNB ACK,RETWRB ;无应答则跳转
         POP ACC ;写数据
         LCALL WRBYTE
         LCALL CACK
         LCALL STOP
         RET
 RETWRB: POP ACC
         LCALL STOP
         RET
IRDBYTE: LCALL START
         MOV A,SLA ;发送器件从地址
         INC A
         LCALL WRBYTE
         LCALL CACK   
         JNB ACK,RETRDB
         LCALL RDBYTE ;进行读字节操作
         LCALL MNACK ;发送非应信号
 RETRDB: LCALL STOP ;结束总线
         RET
IWRNBYTE: MOV A,NUMBYTE
          MOV R3,A
          LCALL START         ;起动总线
          MOV A,SLA
          LCALL WRBYTE        ;发送器件从地址
          LCALL CACK
          JNB ACK,RETWRN      ;无应答则退出
          MOV A,SUBA          ;指定子地址
          LCALL WRBYTE
          LCALL CACK
          MOV R1,#MTD
    WRDA: MOV A,@R1
          LCALL WRBYTE        ;开始写入数据
          LCALL CACK
          JNB ACK,IWRNBYTE
          INC R1
          DJNZ R3,WRDA        ;判断写完没有
  RETWRN: LCALL STOP
          RET
IRDNBYTE: MOV R3,NUMBYTE
          LCALL START
          MOV A,SLA
          LCALL WRBYTE ;发送器件从地址
          LCALL CACK
          JNB ACK,RETRDN
          MOV A,SUBA ;指定子地址
          LCALL WRBYTE
          LCALL CACK
          LCALL START ;重新起动总线
          MOV A,SLA
          INC A ;准备进行读操作
          LCALL WRBYTE
          LCALL CACK
          JNB ACK,IRDNBYTE
          MOV R1,#MRD
    RDN1: LCALL RDBYTE ;读操作开始
          MOV @R1,A
          DJNZ R3,SACK
          LCALL MNACK ;最后一字节发非应答位
  RETRDN: LCALL STOP ;并结束总线
          RET
    SACK: LCALL MACK
          INC R1
          SJMP RDN1
          END
;软件包定义变量
      ACK BIT 10H ;应答标志位
      SLA DATA 50H ;器件从地址
      SUBA DATA 51H ;器件子地址
      NUMBYTE DATA 52H ;读写的字节数
;使用前定义常量
      SDA EQU P1.3
      SCL EQU P1.2
      MTD EQU 30H ;发送数据缓冲区首址
      MRD EQU 40H ;接收数据缓冲区首址(缓冲区40 4FH)
CSI24C021 EQU 0A0H ;定义器件地址
    WRADR EQU 13H ;定义写入地址
   WRDATA EQU 0F0H ;定义定入数据
;--------------------------------------------------------
NARD24C021:        ;立即地址读CSI24C021
          MOV SLA,#CSI24C021
          LCALL IRDBYTE ;读出值在ACC
          RET
;--------------------------------------------------------
RD24C021:          ;随机地址读CSI24C021
          MOV SLA,#CSI24C021
          MOV SUBA,#WRADR ;指定单元地址
          MOV NUMBYTE,#01H ;读出一字节数据
          LCALL IRDNBYTE
          MOV A,MRD
          RET
;-------------------------------------------------------
RDNB24C021         ;连续读
          MOV SLA,#CSI24C021
          MOV SUBA,#10H ;指定起始地址10H
          MOV NUMBYTE,#20H ;读出32 字节数据
          LCALL IRDNBYTE ;读出数据依次放在接收缓冲区MRD
          RET
;-------------------------------------------------------
WRB24C021:        ;字节写CSI24C021
          MOV SLA,#CSI24C021 ;指定地址写单字节
          MOV SUBA,#WRADR ;指定单元地址
          MOV NUMBYTE,#01H ;写一字节数据
          MOV MTD,#WRDATA
          LCALL IWRNBYTE
          RET
;-------------------------------------------------------
WRNB24C021         ;页写
          MOV R0,#MTD ;从地址00H 起写入16 个数据0
          MOV R4,#16
          CLR A
PWLOOP1:
          MOV @R0,A ;数据装载到发送缓冲区MTD
          INC R0
          INC A    
          DJNZ R4,PWLOOP1
          MOV SLA,#CSI24C021 ;指定地址写多字节
          MOV SUBA,#00 ;指定单元地址
          MOV NUMBYTE,#16 ;写入一页数据
          LCALL IWRNBYTE
          RET
;-------------------------------------------------------
RSTWDT:         ;复位看门狗
          CLR SDA ;喂狗脉冲
          NOP
          SETB SDA
          RET
          $INCLUDE (VI2C_ASM.ASM) ;包含VI2C 平台软件包
          $INCLUDE (REG51.INC) ;包含51 单片机头文件
          END
        MOV     SLA,#CSI24C021 ;指定地址写单字节
        MOV     SUBA,#00H ;指定单元地址
        MOV     NUMBYTE,#01H ;写一字节数据
        MOV     MTD,#WRDATA
        LCALL   IWRNBYTE

⌨️ 快捷键说明

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