📄 i2c.asm
字号:
;I2C 读写程序
;BYTE WRITR AND RANDOM READ (字节写,任意读)
;用来写一个指定的数据到一个指定的地址,或用来读一个指定的地址的数据。
;晶振4MHZ,HT46R47
#include ht46r47.inc
data .section 'data'
WORD_ADDRESS EQU [071H] ;写入或读出数据的存储器地址
WRITE_IN EQU [072H] ;写入存储中的数据暂存器
READ_OUT EQU [073H] ;读出存储器中的数据暂存器
DATA_8 EQU [074H] ;移位用临时变量
COUNT1 EQU [075H] ;定时用临时变量
COUNT2 EQU [076H] ;定时用临时变量
TIME_6US MACRO ;宏延迟6US,
NOP
NOP
NOP
NOP
NOP
NOP
ENDM
;-----------------------------------------------
code .section at 0 'code'
SCL EQU PA.0 ;存储器CLK
SCL_C EQU PAC.0
SDA EQU PB.3 ;存储器DATA
SDA_C EQU PBC.3
org 00h
nop
nop
nop
jmp star
org 04h ;外部中断
RETI
org 08h
reti ;定时/计数中断
ORG 0CH
RETI ;AD中断
star:
clr intc ;清除中断控制寄存器
clr tmrc ;清除定时/计数控制寄存器
clr tmr ;清除定时/计数器
CLR STATUS
clr pac ;将PA口设为输出,防止输入悬空
clr pbc ;将PB口设为输出,防止输入悬空
clr pdc ;将PD口设为输出,防止输入悬空
clr pa ;将PA口设为L,
clr pb ;将PB口设为L
CLR PD
MAIN:
MOV A,02EH
MOV WRITE_IN,A ;要写入的数据
MOV A,001H
MOV WORD_ADDRESS,A ;要将数据存入的地址位置,或要从那地址读数据
CALL WRITE_ROM
CALL READ_ROM
nop
MOV A,READ_OUT ;检验写数据是否正确
NOP
JMP MAIN
;--------------------------------------------------------------------------
WRITE_ROM:
;写ROM;
;MOV A,001H
;MOV WRITE_IN,A ;要写入的数据
;MOV A,001H
;MOV WORD_ADDRESS,A ;要把数据写在ROM的什么位置
;START......ACK......写地址......ACK......写数据......ACK......STOP (5MS--24LC02B)写数据时间
;START......ACK......写地址......ACK......写数据1......ACK......写数据2......STOP (5MS--24LC02B)写数据时间
CLR SDA_C ;设SDA为输出
CLR SCL_C ;设SCL为输出
SET SDA
SET SCL
TIME_6US
CLR SDA ;START
TIME_6US
CLR SCL
SET SDA ;1
TIME_6US
SET SCL
TIME_6US
CLR SCL
CLR SDA ;0
TIME_6US
SET SCL
TIME_6US
CLR SCL
SET SDA ;1
TIME_6US
SET SCL
TIME_6US
CLR SCL
CLR SDA ;0
TIME_6US
SET SCL
TIME_6US
CLR SCL
CLR SDA ;A2=0
TIME_6US ;为零时可不用
SET SCL
TIME_6US
CLR SCL
CLR SDA ;A1=0
TIME_6US ;为零时可不用
SET SCL
TIME_6US
CLR SCL
CLR SDA ;A0=0
TIME_6US ;为零时可不用
SET SCL
TIME_6US
CLR SCL
CLR SDA ;0 写模式
TIME_6US ;可不用
SET SCL
TIME_6US
CLR SCL
SET SDA_C ;设IC地址ACK ;设SDA为输入模式 ;之前地址对会自动为零,若不对会马上为高,后面程序执行不下去
SET SCL
IC_ADDRESS_ACK: ;等待应答信号,确认IC地址是否正确 ;判断地址对不对,对-过关,不对-死机
SZ SDA
JMP IC_ADDRESS_ACK
CLR SCL ; 此语句之后,SDA会很快的自动产生一个上升沿
CLR SDA_C ;设输出为L SDA产生下降沿
MOV A,08H ;设传输数据长度
MOV DATA_8,A
WRITE_ADDRESS_IN: ;输入写入地址 ;写地址
CLR SDA
SZ WORD_ADDRESS.7
SET SDA
TIME_6US
SET SCL
TIME_6US
CLR SCL
RL WORD_ADDRESS
SDZ DATA_8
JMP WRITE_ADDRESS_IN
SET SDA_C ;设写地址ACK ;设SDA为输入模式
SET SCL
WRITE_ADDRESS_ACK: ;确认写地址是否正确;等待应答信号
SZ SDA
JMP WRITE_ADDRESS_ACK
CLR SCL
CLR SDA_C ;设输出为L
MOV A,08H ;设传输数据长度
MOV DATA_8,A
WRITE_DATA_IN: ;写数据
CLR SDA
SZ WRITE_IN.7
SET SDA
TIME_6US
SET SCL
TIME_6US
CLR SCL
RL WRITE_IN
SDZ DATA_8
JMP WRITE_DATA_IN
SET SDA_C ;设写数据ACK ;设SDA为输入模式
SET SCL
WRITE_DATA_ACK: ;确认写数据是否正确;等待应答信号
SZ SDA
JMP WRITE_DATA_ACK
CLR SCL
CLR SDA_C
CLR SDA
SET SCL
TIME_6US
SET SDA ;STOP
TIME_6US
CLR SCL ;为了结束置低
CLR SDA ;为了结束置低
;DELAY5MS: ;为了给写足够的时间,24LC02B=5MS ;延时 (2*R2+3)*R1+2=(2*27+3)*98+2=6000us 约6ms
mov a,27
mov count1,a
ROM_D1:
mov a,98
mov count2,a
ROM_D2:
sdz count2
jmp ROM_D2
sdz count1
jmp ROM_D1
RET
;---------------------------------------------------------
READ_ROM:
;读ROM
;MOV A,001H
;MOV WORD_ADDRESS,A ;读地址
; START...IC认证...ACK...写地址......ACK...START...IC认证...ACK...读数据......STOP
CLR SDA_C ;设SDA为输出
CLR SCL_C ;设SCL为输出
SET SDA
SET SCL
TIME_6US
CLR SDA ;START
TIME_6US
CLR SCL
SET SDA ;1
TIME_6US
SET SCL
TIME_6US
CLR SCL
CLR SDA ;0
TIME_6US ;可不用(24AA02工作在2.5V以下时要用)以下同
SET SCL
TIME_6US
CLR SCL
SET SDA ;1
TIME_6US
SET SCL
TIME_6US
CLR SCL
CLR SDA ;0
TIME_6US ;可不用
SET SCL
TIME_6US
CLR SCL
; CLR SDA ;A2=0 ;可以不用,已经为L
TIME_6US ;可不用
SET SCL
TIME_6US
CLR SCL
; CLR SDA ;A1=0
TIME_6US ;可不用
SET SCL
TIME_6US
CLR SCL
; CLR SDA ;A0=0
TIME_6US ;可不用
SET SCL
TIME_6US
CLR SCL
CLR SDA ;0 写模式
TIME_6US ;可不用
SET SCL
TIME_6US
CLR SCL
SET SDA_C ;设IC地址ACK ;设SDA为输入模式
;TIME_6US
SET SCL
;TIME_6US
R_IC_ACK: ;等待ACK应答信号,确认IC地址是否正确
SZ SDA
JMP R_IC_ACK
CLR SCL
CLR SDA_C ;设输出为L
MOV A,08H ;设传输数据长度
MOV DATA_8,A
READ_ADDRESS_IN: ;读入地址 ;读地址
CLR SDA
SZ WORD_ADDRESS.7
SET SDA
TIME_6US
SET SCL
TIME_6US
CLR SCL
RL WORD_ADDRESS
SDZ DATA_8
JMP READ_ADDRESS_IN
SET SDA_C ;设输入
SET SCL
R_ADDRESS_ACK:
SZ SDA ;等待ACK应答信号,确认读地址是否正确 SZ SDA
JMP R_ADDRESS_ACK
CLR SCL
CLR SDA_C ;设SDA为输出
REREADROM:
SET SDA
SET SCL
TIME_6US
CLR SDA ;START
TIME_6US
CLR SCL
SET SDA ;1
TIME_6US
SET SCL
TIME_6US
CLR SCL
CLR SDA ;0
TIME_6US ;可不用
SET SCL
TIME_6US
CLR SCL
SET SDA ;1
TIME_6US
SET SCL
TIME_6US
CLR SCL
CLR SDA ;0
TIME_6US ;可不用
SET SCL
TIME_6US
CLR SCL
;CLR SDA ;A2=0
TIME_6US ;可不用
SET SCL
TIME_6US
CLR SCL
;CLR SDA ;A1=0
TIME_6US ;可不用
SET SCL
TIME_6US
CLR SCL
;CLR SDA ;A0=0
TIME_6US ;可不用
SET SCL
TIME_6US
CLR SCL
SET SDA ;1 读模式
TIME_6US
SET SCL
TIME_6US
CLR SCL
SET SDA_C ;设IC地址ACK ;设SDA为输入模式
SET SCL
RE_IC_ACK:
SZ SDA ;等待ACK应答信号,确认IC地址是否正确
JMP RE_IC_ACK
MOV A,08H
MOV DATA_8,A
RE_DATA_OUT: ;读数据输出
CLR SCL
TIME_6US
CLR READ_OUT.7
SZ SDA
SET READ_OUT.7
TIME_6US
SET SCL
TIME_6US
RL READ_OUT
SDZ DATA_8
JMP RE_DATA_OUT
CLR SCL
CLR SDA_C
CLR SDA
SET SCL
TIME_6US
SET SDA ;STOP
TIME_6US
CLR SCL ;为了结束置低
CLR SDA ;为了结束置低
RET
;---------------------------------------
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -