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

📄 holtek 从i2c的程序.txt

📁 I2C总集--24C256读写程序,X5043读写程序,24C02读写程序
💻 TXT
字号:
  HOLTEK 从I2C的程序

; 芯片:        HT46R47
; 频率:        3.5795454M 赫兹

;---------------------------
;    IO口 Input / Output 定义
;---------------------------
SCL            EQU    PA.0        ; IO 
PSCL        EQU    PAC.0        ; IO<-> 0-> 1<-
SDA            EQU    PA.5        ; SDA 接到#INT
PSDA        EQU    PAC.5        ; IO<-> 0-> 1<-


;---------------------------
;    I2C Slave Int 外部中断
;---------------------------
I2CSlave:
    SNZ      SCL              ; while SCL=1 SDA=0 Start
    RETI
    NULL_Instruction        ; 保留部分,用于程序改变
    NULL_Instruction        ; 保留部分,用于程序改变
    MOV     Tmp2ACC,A        ;保存累加器
    MOV     A,status        ;保存状态寄存器
    MOV     Tmp2PSW,A        ;
    MOV     A,MP
    MOV     Tmp2MP,A           ; Save MP
    MOV     A,08h            ;
    MOV     I2CTOver,A        ;
    CLR     EEI                ; 除能外部中断
I2CSlave05:
    SNZ     SCL                ; While SCL 1 
    JMP        I2CSlave10        ; SCL 1->0 
    SNZ      SDA                ; SDA 0->1
    JMP     I2CSlave05        ; SDA=0,Wait SCL->0
    SNZ      SCL             ; SCL=1 SDA=1 最后需要跳出
    JMP     I2CSlave10        ; SCL=0 防止错判为Stop
    SDZ     I2CTOver        ;
    JMP     I2CSlave05        ; while SCL=1 SDA=1 Stop
    JMP     I2CSlave99        ;
    
I2CSlave10:
    NULL_Instruction        ; 保留部分,用于程序改变
    NULL_Instruction        ; 保留部分,用于程序改变
    MOV     A,0FFh            ;
    MOV     I2CTOver,A        ;
    MOV     A,8
    MOV     BitCnt,A
    CLR     ACC

;--    接收地址+RW 字节    ----
I2CSlave12:
    RL      ACC                ; Data 先高后低
I2CSlave16:
    SNZ      SCL                ; Wait SCL 0->1
    JMP     I2CSlave16        ; SCL=0, Wait 
    SZ      SDA                ; if SDA=0
    ADD     A,01            ; if SDA=1,Data+1
I2CSlave18:
    SNZ      SCL                ; wait SCL 1->0
    JMP     I2CSlave20        ; SCL=1
    SDZ        I2CTOver        ;
    JMP        I2CSlave18        ;
    JMP     I2CSlave99        ; Jump Exit

I2CSlave20:
    SDZ        BitCnt            ; 
    JMP     I2CSlave12        ; Next
    MOV     I2CRWFlag,A        ; 
    XOR     A,MyADDr        ;
    CLR     ACC.0            ;
    SZ      ACC                ; 
    JMP     I2CSlave99        ; ADDress Not EQU ,Exit
    
;--    发送ACK信号    ------------
    CLR     PSDA            ; SDA -> OUTPUT
    CLR     SDA                ; (ACK) SDA = 0
I2CSlave22:
    SNZ      SCL              ; While SCL 0->1
    JMP     I2CSlave22        ; Wait SCL=0

    CLR     PSDA            ; SDA -> OUTPUT
    CLR     SDA                ; (ACK) SDA = 0
I2CSlave30:
    SNZ      SCL                ; Wait SCL=1
    JMP     I2CSlave32        ; While SCL 1->0
    SDZ        I2CTOver        ;
    JMP        I2CSlave30        ; 
    JMP      I2CSlave99        ; 
I2CSlave32:
    SET     PSDA            ; SDA -> INPUT
    SET     SDA                ; SDA = 1
    SZ      I2CRWFlag.0        ;
    JMP     I2CSlaveRD        ; ===Read JMP


;--    接收数据ADDr    --------
I2CSlave40:
    NULL_Instruction        ; 保留部分,用于程序改变
    NULL_Instruction        ; 保留部分,用于程序改变
    MOV     A,8
    MOV     BitCnt,A         ; 
    CLR     ACC                ;
    
I2CSlave42:
    RL      ACC                ; Data 先高后低
I2CSlave46:
    SNZ      SCL                ; Wait SCL 0->1
    JMP     I2CSlave46        ;
    SZ      SDA                ; if SDA=0
    ADD     A,01            ;
I2CSlave48:
    SNZ      SCL                ; wait SCL 1->0
    JMP     I2CSlave50        ; Wait SCL 1->0
    SDZ     I2CTOver        ; While SCL=1
    JMP     I2CSlave48        ;
    JMP     I2CSlave99        ; Jump Exit

I2CSlave50:
    SDZ        BitCnt
    JMP     I2CSlave42        ; Next
    MOV     I2CADDr,A        ; ->I2CADDr

;--    发送ACK信号    ------------
    CLR     PSDA            ; SDA -> OUTPUT
    CLR     SDA                ; (ACK) SDA = 0
I2CSlave52:
    SNZ      SCL              ; While SCL 0->1
    JMP     I2CSlave52        ; Wait SCL=0
    MOV     A,0ffh            ;
    MOV     I2CTOver,A        ;
I2CSlave55:
    SNZ      SCL                ; Wait SCL=1
    JMP     I2CSlave58        ; While SCL 1->0
    SDZ        I2CTOver        ;
    JMP        I2CSlave55        ; 
    JMP      I2CSlave99        ; Jump Exit
I2CSlave58:
    SET     PSDA            ; SDA -> INPUT
    SET     SDA                ; SDA = 1
    MOV     A,I2CADDr        ; 
    MOV     MP,A            ; Point 初始化

;--    继续接收数据Data    --------
I2CSlave6L:
    NULL_Instruction        ; 保留部分,用于程序改变
    NULL_Instruction        ; 保留部分,用于程序改变
    MOV     A,8
    MOV     BitCnt,A
    CLR     ACC

;--    接收数据Data    --------
I2CSlave60:                    ; 
    RL      ACC                ; Data 先高后低
I2CSlave62:
    SNZ      SCL                ; While SCL 0->1
    JMP     I2CSlave62        ; Wait SCL=1

    SNZ     SDA                ; SDA=1
    JMP     I2CSlave66        ; if SDA=0 ?Stop
;--    SCL=1,SDA=1 判启动    --------
I2CSlave64:            
    SNZ     SCL                ; SCL=1
    JMP     I2CSlave68        ; while SCL 1->0
    SNZ      SDA                ; 
    JMP        I2CSlave80        ; Start == SDA 1->0 
    SDZ     I2CTOver        ; While SCL=1
    JMP     I2CSlave64        ; SDA=1 不变
    JMP     I2CSlave99        ; Jump Exit

;--    SCL=1,SDA=0    判结束--------
I2CSlave66:            
    SNZ     SCL                ; SCL=1
    JMP     I2CSlave70        ; While SCL 1->0
    SZ        SDA
    JMP     I2CSlave88        ; Stop == SDA 0->1
    SDZ     I2CTOver        ; While SCL=1
    JMP     I2CSlave66        ; SDA=0 不变
    JMP     I2CSlave99        ; Jump Exit

I2CSlave68:
    ADD     A,01            ; Data Bit=1
I2CSlave70:
    SDZ        BitCnt
    JMP     I2CSlave60        ; Next
    MOV     IAR,A           ; ->I2CADDr
    INC     MP                ; 

;--    发送ACK信号    ------------
    CLR     PSDA            ; SDA -> OUTPUT
    CLR     SDA                ; (ACK) SDA = 0
I2CSlave72:
    SNZ      SCL              ; While SCL 0->1
    JMP     I2CSlave72        ; Wait SCL=0
I2CSlave74:
    SNZ      SCL                ; Wait SCL=1
    JMP     I2CSlave76        ; While SCL 1->0
    SDZ        I2CTOver        ;
    JMP        I2CSlave74        ; 
    JMP      I2CSlave76        ; Jump Exit
I2CSlave76:
    SET     PSDA            ; SDA -> INPUT
    SET     SDA                ; SDA = 1
    MOV     A,0ffh            ;
    MOV     I2CTOver,A        ;
    JMP     I2CSlave6L        ;

;--    Read Data    ------------
I2CSlave80:
    NULL_Instruction        ; 保留部分,用于程序改变
    NULL_Instruction        ; 保留部分,用于程序改变
    SNZ     SCL                ; Wait SCL 1
    JMP        I2CSlave82        ; SCL 1->0 
    SNZ      SDA                ; SDA 0->1
    JMP     I2CSlave80        ;
    JMP     I2CSlave99        ; 
I2CSlave82:
    MOV     A,8
    MOV     BitCnt,A
    CLR     ACC

;--    接收地址+RW 字节    ----
I2CSlave84:
    RL      ACC                ; Data 先高后低
I2CSlave86:
    SNZ      SCL                ; Wait SCL 0->1
    JMP     I2CSlave86        ; SCL=0, Wait 
    SZ      SDA                ; if SDA=0
    ADD     A,01            ; if SDA=1,Data+1
I2CSlave87:
    SNZ      SCL                ; wait SCL=1
    JMP     I2CSlave89        ; While SCL 1->0
    SDZ        I2CTOver        ;
    JMP        I2CSlave87        ;
    JMP     I2CSlave99        ; Jump Exit

I2CSlave89:
    SDZ        BitCnt            ; 
    JMP     I2CSlave84        ; Next
    MOV     I2CRWFlag,A        ; 
    XOR     A,MyADDr        ;
    CLR     ACC.0            ; 
    SZ      ACC                ; 
    JMP     I2CSlave99        ; ADDress Not EQU ,Exit
    SNZ      I2CRWFlag.0        ; if Read ->
    JMP     I2CSlave99        ; W Exit

;--    发送ACK信号    ------------
    CLR     PSDA            ; SDA -> OUTPUT
    CLR     SDA                ; (ACK) SDA = 0
I2CSlave90:
    SNZ      SCL              ; While SCL 0->1
    JMP     I2CSlave90        ; Wait SCL=0
    MOV     A,I2CADDr        ;
    MOV     MP,A             ;

;--    发送Data数据    --------
I2CSlave92:
    CLR     PSDA
    MOV     A,8
    MOV     BitCnt,A         ;
    MOV     A,0FFH
    MOV     I2CTOver,A         ;
    MOV     A,IAR            ;

I2CSlave94:
    SNZ      SCL                ; Wait SCL=1
    JMP     I2CSlave96        ; While SCL 1->0
    SDZ        I2CTOver        ;
    JMP        I2CSlave94        ; 
    JMP      I2CSlave88        ; 
I2CSlave96:
    SNZ     ACC.MSB            ; =1
    JMP     I2CSlave97        ; =0
    SET     SDA                ; SDA = 1
    JMP     I2CSlave98        ;
I2CSlave97:
    CLR     SDA                ; SDA=0
I2CSlave98:
    SNZ      SCL                ; While SCL 0->1
    JMP     I2CSlave98        ; Wait SCL=0
    RL      ACC                ;
    SDZ      BitCnt            ; 8位数据
    JMP     I2CSlave94        ; 继续

;--    接收ACK 数据    --------
I2CSlave9A:
    SNZ      SCL                ; Wait SCL=1
    JMP     I2CSlave9B        ; While SCL 1->0
    SDZ        I2CTOver        ;
    JMP        I2CSlave9A        ; 
I2CSlave9B:
    SET     PSDA            ; 读取ACK前置方向为输入
    SET     SDA                ;
I2CSlave9C:
    SNZ      SCL                ; While SCL 0->1
    JMP     I2CSlave9C        ; Wait SCL=0
    SZ      SDA                ; SDA=0 ACK
    JMP     I2CSlave88        ; SDA=1 NO ACK RETurn
    INC     MP                ; Point + 1
    JMP     I2CSlave92        ; 继续

;--    读取当前数据    --------
I2CSlaveRD:
    NULL_Instruction        ; 保留部分,用于程序改变
    NULL_Instruction        ; 保留部分,用于程序改变
    MOV     A,I2CADDr        ;
    MOV     MP,A              ;
    MOV     A,8
    MOV     BitCnt,A         ;
    MOV     A,0FFH
    MOV     I2CTOver,A         ;
    MOV     A,IAR            ;
    JMP     I2CSlave94        ;
    
;--    退出前保存地址    --------
I2CSlave88:
    MOV     A,MP            ; 
    MOV     I2CADDr,A         ; 
    SET     PSDA            ; SDA -> INPUT
    SET     SDA                ; SDA = 1

;--    退出的入口,恢复数据    ----
I2CSlave99:
    NULL_Instruction        ; 保留部分,用于程序改变
    NULL_Instruction        ; 保留部分,用于程序改变
    SET     EEI                ; 使能外部中断
    MOV     A,Tmp2MP
    MOV     MP,A             ;
    MOV     A,Tmp2PSW
    MOV     status,A        ;恢复状态寄存器
    MOV     A,Tmp2ACC        ;恢复累加器
    CLR     EIF                ; 防止再次进入中断
    RETI

⌨️ 快捷键说明

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