ELAN 78P301 与i2c 模拟通讯,怎么读出来全是22,请教各位大虾呀...T,.T
时间:10-02
整理:3721RD
点击:
include"02.h"
org 0x000
main:
R:
call I2C_INIT
CALL DELAY
CALL CLR_BANK
mov a,@0xaa
mov I2C_DATA,a
call I2C_WRITE_BYTE
call READBYTE
call I2C_PAGE_WRITE
call I2c_SequentialRead
nop
JMP R
ret
/*--------------------------------------------------------------
24C02送数据/命令程序
入口 : I2C_ADDR 地址
I2C_DATA 数据
出口 : 无
----------------------------------------------------------------*/
if I2C_SEQU_OP==1
I2C_PAGE_WRITE:
call I2c_Start ; write command
mov a,@0xa0
call SendByte
call I2C_CHACK__ACK
mov a,@0x10 ;从24c02的00地址开始写
call SendByte
call I2C_CHACK__ACK
;--------------------------------
mov a,@WRITE_NUM ; 连续写字节数量 3
mov I2C_CNT_NUM,a
mov a,@WRITE_BUF ; 缓冲区首地址 0x20
mov r4,a
I2C_PAGE_LOOP:
mov a,r0 ; 从缓存取一个数据
call SendByte
call I2C_CHACK__ACK
call I2c_StOP
inc r4 ; 缓存地址加一
djz I2C_CNT_NUM
jmp I2C_PAGE_LOOP
;--------------------------------
call delay
ret
endif
/*-----------------------------------------------------------
连续读取多个字节
入口: I2C_ADDR E2PROM开始地址
出口: I2C_DATA 数据
说明: 缓存的入口地址和读数据数量在头文件中宏定义
也可以用寄存器传递。
;-----------------------------------------------------------*/
if I2C_SEQU_OP==1
I2c_SequentialRead:
call I2c_Start ; COMMAND 先启动到 Random Read模式
mov a,@0xa0
call SendByte
call I2C_CHACK__ACK
mov a,@0X10 ;从24c02的00地址开始读
call SendByte
call I2C_CHACK__ACK
;-------------------------------- ; 连续读取指定个数据存到连续区域
mov a,@READ_NUM ;3
mov I2C_CNT_NUM,a ; 连续读READ_NUM个数据
mov a,@READ_BUF ;2
mov r4,a ; 数据存放的缓存地址
I2c_Sequential_loop:
call I2C_START ; CURRENT READ
mov a,@0xa1
call SendByte
call I2C_CHACK__ACK
call ReadByte ; 读取一个数据
; call I2c_Ack
call I2c_StOP
mov I2C_DATA,a
mov a,I2C_DATA
mov R0,a ; 保存
inc r4 ; 地址加一
djz I2C_CNT_NUM
jmp I2c_Sequential_loop
; call delay
; mov a,@0x00
; mov R4,a
ret
endif
/******************************************************/
I2C_WRITE_BYTE:
call I2C_START
mov a,@0XA0;写命令
call SENDBYTE
call I2C_CHACK__ACK
mov a,I2C_ADDR ;从24c02的00地址开始
call SENDBYTE
mov a,I2C_DATA ;写入数据
call SENDBYTE
call I2C_CHACK__ACK:
call I2C_STOP
RET
;----------------------------------------------
;----------------------------------------------
I2C_READ_BYTE:
call I2C_START
mov a,@0XA0;
call SENDBYTE
call I2C_CHACK__ACK:
mov a,I2C_ADDR
call SENDBYTE
call I2C_CHACK__ACK:
;--------------------------------
call I2C_START
mov a,@0XA1
call SENDBYTE
call I2C_CHACK__ACK:
call READBYTE
mov a,I2C_DATA
call SENDBYTE
call I2C_STOP
RET
;--------------------------------------
;--------------------------------------
I2C_CHACK__ACK:
clr temp0
;BS SDA
;------------------
mov A,@0x01
IOW PORT6
;
call delay
;BS SCL
; INC temp0 ; temp = 1 有响应, temp = 0 没有响应
weit:
;
JBS sda
jmp weit ;等待应答信号
call delay
BC SCL
;------------------
MOV A,@0X00
IOW PORT6
ret
;------------------------------------
;-------------------------------------
I2C_START:
MOV A,@0x00
IOW Port6
BS SDA
BS SCL
call delay
BC SDA
NOP
call delay
BC SCL
RET
;------------------------------------
;------------------------------------
I2C_STOP:
MOV A,@0x00
IOW Port6
BC SDA
BS SCL
NOP
call delay
BS SDA
NOP
call delay
Bc SCL
RET
;----------------------------------------
;----------------------------------------
I2C_ACK:
MOV A,@0x00
IOW Port6
BC SDA
call delay
BS SCL
call delay
BC SCL
RET
;----------------------------------------
;-----------------------------------------
I2C_NOACK:
MOV A,@0x00
IOW Port6
BS SDA
call delay
BS SCL
call delay
BC SCL
RET
;-------------------------------------------
;-------------------------------------------
SENDBYTE:
MOV A,@0x00
IOW Port6
mov temp0,a
mov a,@8
mov I2C_BYTE_CNT,a
bc scl
SEND_LOOP:
RLC temp0 ;MSB
JBS 0X03,0 ;状态标志位
JMP $+3
BS SDA
JMP $+2
BC SDA
call delay
BS SCL
call delay
BC SCL
call delay
DJZ I2C_BYTE_CNT
JMP SEND_LOOP
MOV A,@0x01
IOW Port6
BS SCL
call delay
RET
;---------------------------------------
;---------------------------------------
READBYTE:
;----------------------
mov A,@0X01
IOW PORT6
; clr I2C_DATA
mov a,@8
mov I2C_BYTE_CNT,a
; call delay
;bs sda
; call delay
READ_LOOP:
bs SCL
; call delay
rlc I2C_DATA
BC I2C_DATA,0
JBC SDA
BS I2C_DATA,0
; call delay
Bc SCL
; call delay
DJZ I2C_BYTE_CNT
JMP READ_LOOP
nop
;---------------------
mov A,@0x00
IOW PORT6
mov a,I2C_DATA
RET
;--------------------------------------------------
;--------------------------------------------------
I2C_INIT:
BS IOCS ;选择IOC51-IOCF1
MOV A,@0X0E ;4E: 上升沿触发,CE: 下降沿触发
BS IOCS ;选择IOC51-IOCF1 R3 (状态寄存器)IO控制寄存器段选择位 1: 选择段1 (IOC51 ~ IOCC1)
MOV A,@0X00
IOW P6HCR ;p6口内置上拉0x00 (下拉控制寄存器)
;
BC IOCS ;选择IOC50-IOCF0
MOV A,@0x00
IOW IOCC0 ;全部p6口开漏输出0xff (漏极开路控制寄存器)
;
MOV A,@0x00
IOW IOCD0 ;p5上拉0x00 (上拉控制寄存器)
;
MOV A,@0xff
IOW IOCB0 ;关闭P5下拉0xff (下拉控制寄存器)
;
MOV A,@0X00 ;0 输入
IOW IOC60
bc S_BANK
bank 0
mov a,@0x23
mov w_Dat1,a
mov a,@0x24
mov w_Dat2,a
mov a,@0x25
mov w_Dat3,a
mov a,@0X10
mov I2C_ADDR,a
RET
CLR_BANK:
MOV A,@0X10
MOV R4,A
CLR_BANK_LP:
CLR R0
INC R4
;
MOV A,R4
AND A,@0X3F
JBS Z
JMP CLR_BANK_LP
CLR R4
ret
;I2C_INIT:
; mov a,@0x01
; IOW SDA_PORT
;
; mov a,@0x00
; IOW SCL_PORT
;
; mov a,@0x0d
; IOW P5
; IOW P6
;RET
delay:
mov a, @0x22
mov temp0,a
B: djz temp0
jmp B
nop
clr temp0
ret
;-------------------------------------------------------
IOC50 ==0X05:IOPAGE 0
IOC60 ==0X06:IOPAGE 0
IOC70 ==0X07:IOPAGE 0
IOCB0 ==0X0B:IOPAGE 0
IOCC0 ==0X0C:IOPAGE 0
IOCD0 ==0X0D:IOPAGE 0
P5HCR ==0X0D:IOPAGE 0
IOCE0 ==0X0E:IOPAGE 0
IOCF0 ==0X0F:IOPAGE 0
IOC51 ==0X05:IOPAGE 1
HSCR1 ==0X05:IOPAGE 1
IOC61 ==0X06:IOPAGE 1
HSCR2 ==0X06:IOPAGE 1
IOC71 ==0X07:IOPAGE 1
HDCR1 ==0X07:IOPAGE 1
IOC81 ==0X08:IOPAGE 1
HDCR2 ==0X08:IOPAGE 1
IOCF1 ==0X0F:IOPAGE 1
P6HCR ==0X0F:IOPAGE 1
;---------------------------------------
;BANK0 SPECIAL REGISTER
;---------------------------------------
R0 ==0X00:rpage 0
TCC ==0X01:rpage 0
PC ==0X02:rpage 0
R3 ==0X03:rpage 0
STATUS ==0X03:rpage 0
;{
C ==STATUS.0
DC ==STATUS.1
Z ==STATUS.2
P ==STATUS.3
T ==STATUS.4
IOCS ==STATUS.6
RST ==STATUS.7
;}
R4 ==0X04:rpage 0
;{
S_BANK ==R4.7
;}
PORT5 ==0X05:rpage 0
;{
SCL EQU Port5.1
;}
PORT6 ==0X06:rpage 0
SDA EQU Port6.0
temp0 ==0x10
temp1 ==0x11
temp2 ==0x10
temp3 ==0x13
I2C_DATA == temp1
I2C_ADDR ==temp2
I2C_BYTE_CNT ==temp3
w_Dat1 == 0x20
w_Dat2 == 0x21
w_Dat3 == 0x22
r_Dat1 == 0x23
r_Dat2 == 0x24
r_Dat3 == 0x25
I2C_SEQU_OP == 1 ; 定义是否开启连续读写操作
if I2C_SEQU_OP==1
I2C_CNT_NUM == 0X14 ; 连续读写时候采用的计算器
READ_NUM == 9; 连续读N个数据
READ_BUF == 0x2B ; 连续读数据存放入口地址
WRITE_NUM == 3 ; 连续读N个数据,最多8个
WRITE_BUF == 0x20 ; 连续读数据存放入口地址
endif
org 0x000
main:
R:
call I2C_INIT
CALL DELAY
CALL CLR_BANK
mov a,@0xaa
mov I2C_DATA,a
call I2C_WRITE_BYTE
call READBYTE
call I2C_PAGE_WRITE
call I2c_SequentialRead
nop
JMP R
ret
/*--------------------------------------------------------------
24C02送数据/命令程序
入口 : I2C_ADDR 地址
I2C_DATA 数据
出口 : 无
----------------------------------------------------------------*/
if I2C_SEQU_OP==1
I2C_PAGE_WRITE:
call I2c_Start ; write command
mov a,@0xa0
call SendByte
call I2C_CHACK__ACK
mov a,@0x10 ;从24c02的00地址开始写
call SendByte
call I2C_CHACK__ACK
;--------------------------------
mov a,@WRITE_NUM ; 连续写字节数量 3
mov I2C_CNT_NUM,a
mov a,@WRITE_BUF ; 缓冲区首地址 0x20
mov r4,a
I2C_PAGE_LOOP:
mov a,r0 ; 从缓存取一个数据
call SendByte
call I2C_CHACK__ACK
call I2c_StOP
inc r4 ; 缓存地址加一
djz I2C_CNT_NUM
jmp I2C_PAGE_LOOP
;--------------------------------
call delay
ret
endif
/*-----------------------------------------------------------
连续读取多个字节
入口: I2C_ADDR E2PROM开始地址
出口: I2C_DATA 数据
说明: 缓存的入口地址和读数据数量在头文件中宏定义
也可以用寄存器传递。
;-----------------------------------------------------------*/
if I2C_SEQU_OP==1
I2c_SequentialRead:
call I2c_Start ; COMMAND 先启动到 Random Read模式
mov a,@0xa0
call SendByte
call I2C_CHACK__ACK
mov a,@0X10 ;从24c02的00地址开始读
call SendByte
call I2C_CHACK__ACK
;-------------------------------- ; 连续读取指定个数据存到连续区域
mov a,@READ_NUM ;3
mov I2C_CNT_NUM,a ; 连续读READ_NUM个数据
mov a,@READ_BUF ;2
mov r4,a ; 数据存放的缓存地址
I2c_Sequential_loop:
call I2C_START ; CURRENT READ
mov a,@0xa1
call SendByte
call I2C_CHACK__ACK
call ReadByte ; 读取一个数据
; call I2c_Ack
call I2c_StOP
mov I2C_DATA,a
mov a,I2C_DATA
mov R0,a ; 保存
inc r4 ; 地址加一
djz I2C_CNT_NUM
jmp I2c_Sequential_loop
; call delay
; mov a,@0x00
; mov R4,a
ret
endif
/******************************************************/
I2C_WRITE_BYTE:
call I2C_START
mov a,@0XA0;写命令
call SENDBYTE
call I2C_CHACK__ACK
mov a,I2C_ADDR ;从24c02的00地址开始
call SENDBYTE
mov a,I2C_DATA ;写入数据
call SENDBYTE
call I2C_CHACK__ACK:
call I2C_STOP
RET
;----------------------------------------------
;----------------------------------------------
I2C_READ_BYTE:
call I2C_START
mov a,@0XA0;
call SENDBYTE
call I2C_CHACK__ACK:
mov a,I2C_ADDR
call SENDBYTE
call I2C_CHACK__ACK:
;--------------------------------
call I2C_START
mov a,@0XA1
call SENDBYTE
call I2C_CHACK__ACK:
call READBYTE
mov a,I2C_DATA
call SENDBYTE
call I2C_STOP
RET
;--------------------------------------
;--------------------------------------
I2C_CHACK__ACK:
clr temp0
;BS SDA
;------------------
mov A,@0x01
IOW PORT6
;
call delay
;BS SCL
; INC temp0 ; temp = 1 有响应, temp = 0 没有响应
weit:
;
JBS sda
jmp weit ;等待应答信号
call delay
BC SCL
;------------------
MOV A,@0X00
IOW PORT6
ret
;------------------------------------
;-------------------------------------
I2C_START:
MOV A,@0x00
IOW Port6
BS SDA
BS SCL
call delay
BC SDA
NOP
call delay
BC SCL
RET
;------------------------------------
;------------------------------------
I2C_STOP:
MOV A,@0x00
IOW Port6
BC SDA
BS SCL
NOP
call delay
BS SDA
NOP
call delay
Bc SCL
RET
;----------------------------------------
;----------------------------------------
I2C_ACK:
MOV A,@0x00
IOW Port6
BC SDA
call delay
BS SCL
call delay
BC SCL
RET
;----------------------------------------
;-----------------------------------------
I2C_NOACK:
MOV A,@0x00
IOW Port6
BS SDA
call delay
BS SCL
call delay
BC SCL
RET
;-------------------------------------------
;-------------------------------------------
SENDBYTE:
MOV A,@0x00
IOW Port6
mov temp0,a
mov a,@8
mov I2C_BYTE_CNT,a
bc scl
SEND_LOOP:
RLC temp0 ;MSB
JBS 0X03,0 ;状态标志位
JMP $+3
BS SDA
JMP $+2
BC SDA
call delay
BS SCL
call delay
BC SCL
call delay
DJZ I2C_BYTE_CNT
JMP SEND_LOOP
MOV A,@0x01
IOW Port6
BS SCL
call delay
RET
;---------------------------------------
;---------------------------------------
READBYTE:
;----------------------
mov A,@0X01
IOW PORT6
; clr I2C_DATA
mov a,@8
mov I2C_BYTE_CNT,a
; call delay
;bs sda
; call delay
READ_LOOP:
bs SCL
; call delay
rlc I2C_DATA
BC I2C_DATA,0
JBC SDA
BS I2C_DATA,0
; call delay
Bc SCL
; call delay
DJZ I2C_BYTE_CNT
JMP READ_LOOP
nop
;---------------------
mov A,@0x00
IOW PORT6
mov a,I2C_DATA
RET
;--------------------------------------------------
;--------------------------------------------------
I2C_INIT:
BS IOCS ;选择IOC51-IOCF1
MOV A,@0X0E ;4E: 上升沿触发,CE: 下降沿触发
BS IOCS ;选择IOC51-IOCF1 R3 (状态寄存器)IO控制寄存器段选择位 1: 选择段1 (IOC51 ~ IOCC1)
MOV A,@0X00
IOW P6HCR ;p6口内置上拉0x00 (下拉控制寄存器)
;
BC IOCS ;选择IOC50-IOCF0
MOV A,@0x00
IOW IOCC0 ;全部p6口开漏输出0xff (漏极开路控制寄存器)
;
MOV A,@0x00
IOW IOCD0 ;p5上拉0x00 (上拉控制寄存器)
;
MOV A,@0xff
IOW IOCB0 ;关闭P5下拉0xff (下拉控制寄存器)
;
MOV A,@0X00 ;0 输入
IOW IOC60
bc S_BANK
bank 0
mov a,@0x23
mov w_Dat1,a
mov a,@0x24
mov w_Dat2,a
mov a,@0x25
mov w_Dat3,a
mov a,@0X10
mov I2C_ADDR,a
RET
CLR_BANK:
MOV A,@0X10
MOV R4,A
CLR_BANK_LP:
CLR R0
INC R4
;
MOV A,R4
AND A,@0X3F
JBS Z
JMP CLR_BANK_LP
CLR R4
ret
;I2C_INIT:
; mov a,@0x01
; IOW SDA_PORT
;
; mov a,@0x00
; IOW SCL_PORT
;
; mov a,@0x0d
; IOW P5
; IOW P6
;RET
delay:
mov a, @0x22
mov temp0,a
B: djz temp0
jmp B
nop
clr temp0
ret
;-------------------------------------------------------
IOC50 ==0X05:IOPAGE 0
IOC60 ==0X06:IOPAGE 0
IOC70 ==0X07:IOPAGE 0
IOCB0 ==0X0B:IOPAGE 0
IOCC0 ==0X0C:IOPAGE 0
IOCD0 ==0X0D:IOPAGE 0
P5HCR ==0X0D:IOPAGE 0
IOCE0 ==0X0E:IOPAGE 0
IOCF0 ==0X0F:IOPAGE 0
IOC51 ==0X05:IOPAGE 1
HSCR1 ==0X05:IOPAGE 1
IOC61 ==0X06:IOPAGE 1
HSCR2 ==0X06:IOPAGE 1
IOC71 ==0X07:IOPAGE 1
HDCR1 ==0X07:IOPAGE 1
IOC81 ==0X08:IOPAGE 1
HDCR2 ==0X08:IOPAGE 1
IOCF1 ==0X0F:IOPAGE 1
P6HCR ==0X0F:IOPAGE 1
;---------------------------------------
;BANK0 SPECIAL REGISTER
;---------------------------------------
R0 ==0X00:rpage 0
TCC ==0X01:rpage 0
PC ==0X02:rpage 0
R3 ==0X03:rpage 0
STATUS ==0X03:rpage 0
;{
C ==STATUS.0
DC ==STATUS.1
Z ==STATUS.2
P ==STATUS.3
T ==STATUS.4
IOCS ==STATUS.6
RST ==STATUS.7
;}
R4 ==0X04:rpage 0
;{
S_BANK ==R4.7
;}
PORT5 ==0X05:rpage 0
;{
SCL EQU Port5.1
;}
PORT6 ==0X06:rpage 0
SDA EQU Port6.0
temp0 ==0x10
temp1 ==0x11
temp2 ==0x10
temp3 ==0x13
I2C_DATA == temp1
I2C_ADDR ==temp2
I2C_BYTE_CNT ==temp3
w_Dat1 == 0x20
w_Dat2 == 0x21
w_Dat3 == 0x22
r_Dat1 == 0x23
r_Dat2 == 0x24
r_Dat3 == 0x25
I2C_SEQU_OP == 1 ; 定义是否开启连续读写操作
if I2C_SEQU_OP==1
I2C_CNT_NUM == 0X14 ; 连续读写时候采用的计算器
READ_NUM == 9; 连续读N个数据
READ_BUF == 0x2B ; 连续读数据存放入口地址
WRITE_NUM == 3 ; 连续读N个数据,最多8个
WRITE_BUF == 0x20 ; 连续读数据存放入口地址
endif
不会汇编的我路过
~(ㄒoㄒ)~ 我也不大懂好坑啊
~(ㄒoㄒ)~ 我也不大懂好坑啊
谢谢小编分享,赞一个
汇编,很高大上啊。