📄 idwraci2c.asm
字号:
LDM PM2,#n_I2Cin
SET1 o_SCL
LDA #5
CALL !delay
LDA #1
CALL !delay
BBS o_SDA,pb ;/*if SDA at a high STAte ->pb*/
LDA #1
CALL !delay
BBS o_SDA,pb
LDA #1
CALL !delay
CLR1 o_SCL
BRA endf1
pb: SET1 I2C_SR2_AF ;/*set bit Acknowledge Failure*/
CLR1 I2C_SR1_ACK
BRA endf2
endf1: SET1 I2C_SR1_ACK ;/*ACK=1 : Acknowledge received*/
LDA #1
CALL !delay
endf2:
LDM PM2,#n_I2Cout ;DA2404 FOR OUTPUT
CLR1 o_SDA ;/*configure SDA as output*/
RET
;*-----------------------------------------------------------------------------
;ROUTINE NAME : I2C_nAck
;INPUT/OUTPUT : None.
;DESCRIPTION : Non acknoledge generation from now.
;COMMENTS : Transfer sequence = DATA, NACK.
;-----------------------------------------------------------------------------*/
I2C_nAck:
CLR1 I2C_SR1_ACK ;/* Non acknowledge after the next received data byte.*/
RET
;*-----------------------------------------------------------------------------
;ROUTINE NAME : I2Cm_TxData
;INPUT/OUTPUT : data byte to be transfered(MSB first) / None.
;DESCRIPTION : Transmits a data byte.
;COMMENTS : Transfer sequence = DATA, ACK, ...
;-----------------------------------------------------------------------------*/
I2Cm_TxData:
CLR1 o_SCL
CMP I2C_SR2,#0 ;/* Check the communication error STAtus.*/
BEQ go ;/* Communication error check */
INC err_STAtus
INC t_count_err
BNE ENDB
INC t_count_err
BRA ENDB
go: MOV A,I2C_DR
ROL A,1
MOV I2C_DR,A
; ROL I2C_DR ;/*send data bit per bit, MSB first*/
BCS send_one
CLR1 o_SDA ;/*send a zero*/
BRA ENDB
send_one:
SET1 o_SDA ;/*send a one*/
ENDB:
nop
SET1 o_SCL
LDA #2 ;10 [test]
CALL !delay ;/*high STAte on SCL*/
RET
;*-----------------------------------------------------------------------------
;ROUTINE NAME : I2Cm_RxData
;INPUT/OUTPUT : Last byte to receive flag (active high) / Received data byte.
;DESCRIPTION : Receive a data byte.
;COMMENTS : Transfer sequence = DATA, ACK...
;-----------------------------------------------------------------------------*/
I2Cm_RxData:
CMP I2C_SR2,#0 ;/* Check the communication error STAtus.*/
BEQ go1 ;/* Communication error check.*/
INC r_count_err
BRA enda
go1:
MOV A,BUFF
ROL A,1
MOV BUFF,A
CLR1 CY
; ROL BUFF ;/*shift I2C_DR to receive next bit*/
nop
nop
nop
SET1 o_SCL
nop
nop
LDA BUFF
BBC o_SDA,rec_0
OR A,#1
; BRA go3 ;/*the received bit is 1*/
rec_0:
; OR A,#0 ;/*the received bit is 0*/
go3:
STA BUFF
LDA #10H
CALL !delay
CLR1 o_SCL ;/*SCL at a low level*/
enda:
RET
;*-----------------------------------------------------------------------------
;ROUTINE NAME : I2C_Ack
;INPUT/OUTPUT : None.
;DESCRIPTION : Send Ack to the slave.
;COMMENTS :
;-----------------------------------------------------------------------------*/
I2C_Ack:
CLR1 o_SDA
; SET1 PADDR,#SDA ;/*the master pulls the SDA line low*/ /*SDA as output to give an ACK*/
LDA #10
CALL !delay
SET1 o_SCL ;/*waits the master takes the control of SDA*/
LDA #10
CALL !delay
CLR1 o_SCL
LDA #5
CALL !delay
SET1 o_SDA
SET1 I2C_SR1_ACK ;/*ACK=1: acknowledge sent by the master*/
end2: RET
;*-----------------------------------------------------------------------------
;ROUTINE NAME : I2Cm_Tx
;INPUT/OUTPUT : send_tab / None.
;DESCRIPTION : Transmit data BUFFer via I2C.
;COMMENTS : Most significant bytes first.
;-----------------------------------------------------------------------------*/
I2Cm_Tx:
LDM PM2,#n_I2Cout ;DA2404 FOR OUTPUT
CALL !I2Cm_Start
CALL !I2Cm_WRITE
CALL !wait_Ack
BBC I2C_SR1_ACK,pb1
CALL !I2Cm_ADDR
CALL !wait_Ack
BBC I2C_SR1_ACK,pb1
again4:
LD A,D_I2Cnum
MOV B,A
MOVW AX,D_WORK
MOVW HL,AX
again1:
LD A,[HL]
STA I2C_DR
call !I2Cm_Tb ;/* sent 8 byte to I2C*/
CALL !wait_Ack
BBC I2C_SR1_ACK,pb1
INCW HL
DEC B
BNE again1
BRA endf
pb1: SET1 I2C_SR2_AF
endf: RET
;*-----------------------------------------------------------------------------
;ROUTINE NAME : I2Cm_WRITE
;INPUT/OUTPUT : data 8 byte to sent.
;DESCRIPTION : sent 8 bit in I2C_DR
;COMMENTS : Most significant bytes first.
;-----------------------------------------------------------------------------*/
I2Cm_WRITE:
LDM I2C_DR,#0A0H
CALL !I2Cm_Tb
RET
;*-----------------------------------------------------------------------------
;ROUTINE NAME : I2Cm_READ
;INPUT/OUTPUT : data 8 byte to sent.
;DESCRIPTION : sent 8 bit in I2C_DR
;COMMENTS : Most significant bytes first.
;-----------------------------------------------------------------------------*/
I2Cm_READ:
LDA #0A1H
STA I2C_DR
CALL !I2Cm_Tb
RET
;*-----------------------------------------------------------------------------
;ROUTINE NAME : I2Cm_ADDR
;INPUT/OUTPUT : data 8 byte to sent.
;DESCRIPTION : sent 8 bit in I2C_DR
;COMMENTS : Most significant bytes first.
;-----------------------------------------------------------------------------*/
I2Cm_ADDR:
LDA D_I2Caddr
STA I2C_DR
CALL !I2Cm_Tb
RET
;*-----------------------------------------------------------------------------
;ROUTINE NAME : I2Cm_Tb
;INPUT/OUTPUT : data 8 byte to sent.
;DESCRIPTION : sent 8 bit in I2C_DR
;COMMENTS : Most significant bytes first.
;-----------------------------------------------------------------------------*/
I2Cm_Tb:
LDM count,#1
again2:
CALL !I2Cm_TxData ;sent 8 bit in I2C_DR
MOV A,count ;
ROL A,1
MOV count,A
BCS $+2+2 ;
BRA again2 ;
ret
;*-----------------------------------------------------------------------------
;ROUTINE NAME : I2Cm_Rx
;INPUT/OUTPUT : data byte to receive/ None.
;DESCRIPTION : Receive in data BUFFer via I2C.
;COMMENTS : Most significant bytes first.
;-----------------------------------------------------------------------------*/
I2Cm_Rx:
SET1 I2C_SR1_RCPT ;/*master in receiver mode*/
CALL !I2Cm_Stop
CALL !I2Cm_Start
CALL !I2Cm_WRITE
CALL !wait_Ack
BBC I2C_SR1_ACK,pb2
CALL !I2Cm_ADDR
CALL !wait_Ack
BBC I2C_SR1_ACK,pb2
CALL !I2Cm_Start
CALL !I2Cm_READ
BBC I2C_SR1_ACK,pb2
CALL !wait_Ack
BBC I2C_SR1_ACK,pb2
LDA D_I2Cnum
MOV B,A
MOVW AX,D_WORK
MOVW HL,AX
cont1:
LDM PM2,#n_I2Cin ;DA2404 FOR input
call !I2Cm_Rb
LDA BUFF
STA I2C_DR
MOV A,B
CMP A,#0
BEQ non_ack ;/*non acknowledge to make the master generate the STOP*/
; CLR1 o_SDA ;/*configure SDA as output*/
LDM PM2,#n_I2Cout ;DA2404 FOR OUTPUT
CLR1 o_SDA
CALL !I2C_Ack
BBS I2C_SR2_AF,end_final ;/*if AF -> go back to main and reSTArt the reception*/
cont2:
LDA I2C_DR
MOV [HL],A ;/*store received data into BUFFin*/
INCW HL
DEC B
BNE cont1
BRA end_final
non_ack:
CALL !I2C_nAck
BRA cont2
pb2: SET1 I2C_SR2_AF
end_final:
RET
;*-----------------------------------------------------------------------------
;ROUTINE NAME : I2Cm_Rb
;INPUT/OUTPUT : data byte to receive/ None.
;DESCRIPTION : Receive in data BUFFer via I2C.
;COMMENTS : Most significant bytes first.
;------------------------------------------------------------------------
I2Cm_Rb:
; PUSH A
LDM count,#1
LDM BUFF,#0
cont:
CALL !I2Cm_RxData
MOV A,count
ROL A,1
MOV count,A
BC $$+2+2
BRA cont
; POP A
RET
;------------------------------------------------------------------------
trans:
LDM PM2,#n_I2Cout ;DA2404 FOR OUTPUT
CALL !I2Cm_Stop
; CLR1 Pin_WP
; CLR1 o_I2Cwp
; CALL wait_1ms
CLR1 I2C_SR1_RCPT
CALL !I2Cm_Tx
BBS I2C_SR2_AF,pb_t
CALL !I2Cm_Stop
; CALL wait_1ms
; CALL wait_1ms
; SET1 Pin_WP
;CALL ADintit0
RET
recept:
CALL !I2Cm_Rx
BBS I2C_SR2_AF,pb_r
CALL !I2Cm_Stop
RET
pb_t:
CLR1 I2C_SR2_AF
INC t_count_err
RET
pb_r:
CLR1 I2C_SR2_AF
INC r_count_err
RET
; This last line refers to the first line.
; It used by the compiler/linker to determine code zone
; END ; Be aware of the fact that the END directive should not
; STAnd on the left of the page like the labels's names.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -