📄 24c02.asm
字号:
INCLUDE HT48R30A-1.INC
SCL EQU PC.0 ;时钟线
SDA EQU PC.1 ;数据线
SLVADR EQU 0A0H ;器件24C02地址
RCVDAT EQU 030H ;从24C02读数据数据首地址
XMTDAT EQU 040H ;往24C02写数据数据首地址
FLAG0 EQU [20H]
F0 EQU FLAG0.0
ACK EQU FLAG0.1
BITCNT EQU [21H] ;位数寄存器
BYTECNT EQU [22H] ;数据字节数
SUBADR EQU [23H] ;24C02访问地址
WRITEBYTE EQU [24H] ;写数据寄存器
READBYTE EQU [25H] ;读数据寄存器
ORG 000H ;芯片复位从 00 开始
JMP RESET ;程序上电跳转到初始化
ORG 004H ;外部中断入口
RETI
ORG 008H ;定时/计数器中断入口
reti
ORG 020H ;主程序从ROM 20H 地址开始存储
RESET: CLR PCC ;设置PC1\PC0输出
CLR PC ;PC口清零
;************************************************
; CLRMEM 将RAM区清零
;************************************************
; MOV A,20H
; MOV MP0,A
;CLR_RAM: CLR R0
; INC MP0
; MOV A,MP0
; SUB A,80H
; SNZ Z
; JMP CLR_RAM
MAIN: MOV A,10H
MOV SUBADR,A
MOV A,5
MOV BYTECNT,A
CALL SENDDAT
NOP
NOP
MOV A,10H
MOV SUBADR,A
MOV A,5
MOV BYTECNT,A
CALL RCVDATA
LOOP: JMP LOOP
;24C021操作子程序
START: SET SDA ;发送起始条件的数据信号
NOP
NOP
SET SCL ;发送起始条件的时钟信号
NOP ;起始条件建立时间大于4.7US
NOP
NOP
NOP
NOP
NOP
NOP
CLR SDA ;发送起始信号
NOP ;起始条件所定时间大于4US
NOP
NOP
NOP
NOP
NOP
NOP
CLR SCL ;钳住I2C总线,准备发送或接收数据
RET
STOP: CLR SDA ;发送停止条件的数据信号
NOP
NOP
SET SCL ;发送停止条件的时钟信号
NOP ;起始条件建立时间大于4US
NOP
NOP
NOP
NOP
NOP
NOP
SET SDA ;发送I2C总线停止信号
RET
;发送字节子程序
SDBYTE: MOV A,8
MOV BITCNT,A ;要传送的数据长度为8位
SENDB: RLC WRITEBYTE ;要发送的数据左移,发送位入C
SZ C ;发送位为"1"转发送数据位"1"
JMP SENDB1
CLR SDA
JMP SEND
SENDB1: SET SDA ;发送数据位"1"
SEND: NOP
NOP
NOP
NOP
SET SCL ;置时钟线为高,通知被控器开始接收数据位
NOP ;保证时钟高周期大于4US
NOP
NOP
NOP
NOP
NOP
NOP
CLR SCL
SDZ BITCNT
JMP SENDB ;8位没发送完继续发送
NOP
NOP
SET SDA ;8位发送完后释放数据线,准备收应答位
NOP
NOP
SET SCL ;开始接受应答位
NOP
NOP
CLR F0 ;预先清发送数据出错标志
SET PCC.1 ;INPUT
NOP
NOP
NOP
NOP
SZ SDA ;判断是否接受到应答信号,正常转ACKEND
SET F0 ;未收到应答,置位错误标志
ACKEND: NOP
NOP
CLR PCC.1 ;OUTPUT
CLR SCL ;发送结束钳住总线,准备下一步发送或接收数据或进行其他处理
RET
;接收字节子程序
RCVBYTE: SET PCC.1 ;置数据线为输入方式
MOV A,8
MOV BITCNT,A ;要传送的数据长度为8位
RCV: NOP
NOP
CLR SCL ;置时钟线为低,准备接收数据位
NOP ;时钟低周期大于4US
NOP
NOP
NOP
NOP
NOP
NOP
SET SCL ;置时钟线为高使数据线上数据有效
NOP
NOP
CLR C ;准备将接受的数据位放入ACC中
SZ SDA ;读数据位,若为"0"则置C=0并转RCV0接收数据位
SET C ;读数据位,若为"1"则置C=1
RLC READBYTE ;接收的数据位放入
NOP
NOP
NOP
NOP
SDZ BITCNT
JMP RCV ;8位没收完继续接收
CLR SCL ;8位接收完置时钟线为低准备发送应答或非应答信号
NOP
NOP
CLR PCC.1 ;OUTPUT
NOP
NOP
CLR SDA ;判断是否需要继续接收字节数据,若需要则转SDACKB发送应答位
SZ ACK
SET SDA ;发送非应答位
SDACKB: NOP
NOP
NOP
SET SCL ;置时钟线为高使应答位有效
NOP ;时钟周期大于4US
NOP
NOP
NOP
NOP
NOP
NOP
CLR SCL ;清时钟线钳住I2C总线以便继续接收字节数据或发送停止条件
CLR ACK ;清接收非应答标志
RET
;接收数据子程序
RCVDATA: CALL START ;发送I2C总线起始条件
MOV A,SLVADR ;取被控器总线地址
MOV WRITEBYTE,A
CALL SDBYTE ;发送被控器总线地址
SZ F0
JMP RCVRETURN ;出错返回
MOV A,SUBADR ;取单元地址
MOV WRITEBYTE,A
CALL SDBYTE ;发送单元地址
SZ F0
JMP RCVRETURN ;出错返回
CALL START ;发送I2C总线重复起始条件
MOV A,SLVADR ;取被控器总线地址
SET ACC.0 ;取总线读操作位
MOV WRITEBYTE,A
CALL SDBYTE ;发送被控器总线地址
SZ F0
JMP RCVRETURN ;出错返回
CLR ACK ;清接收非应答标志,准备接收数据
MOV A,RCVDAT
MOV MP0,A ;取接收数据缓冲区首址
SDZ BYTECNT ;如果还未接收数据则转去接收前(BYTECNT)-1个数据
JMP RCVNEXT
JMP RCVLAST ;只剩最后一个数据未接收转去接收最后一个数据
RCVNEXT: CALL RCVBYTE ;接收数据
MOV A,READBYTE
MOV R0,A ;将接收数据放入接收缓冲区中
INC MP0 ;指向下一个缓冲区地址
SDZ BYTECNT
JMP RCVNEXT ;重复操作直到剩下最后一个数据
RCVLAST: SET ACK ;置接收非应答标志,准备在接受万最后一个数据后发出非应答信号以停止接收数据
CALL RCVBYTE ;接收最后一个数据
MOV A,READBYTE
MOV R0,A ;将最后一个数据放入接收缓冲区中
CALL STOP ;发送I2C总线停止条件
RCVRETURN: RET
;发送数据子程序
SENDDAT: CALL START ;发送I2C总线起始条件
MOV A,SLVADR ;取被控器总线地址
MOV WRITEBYTE,A
CALL SDBYTE ;发送被控器总线地址
SZ F0
JMP SENDRETURN ;出错返回
MOV A,SUBADR ;取单元地址
MOV WRITEBYTE,A
CALL SDBYTE ;发送单元地址
SZ F0
JMP SENDRETURN ;出错返回
MOV A,XMTDAT
MOV MP0,A ;取发送数据缓冲区首址
SENDNEXT: MOV A,R0
MOV WRITEBYTE,A
CALL SDBYTE ;发送一次数据
SZ F0
JMP SENDRETURN ;出错返回
INC MP0 ;取下一数据
SDZ BYTECNT
JMP SENDNEXT ;重复操作直到发送完最后一个数据
CALL STOP ;发送I2C总线停止条件
SENDRETURN: RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -