📄 holtek 从i2c的程序.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 + -