| ??? 03/22/12 17:54 Read: times |
#186817 - i2c master mean |
Hi,
I need some advice on using my ADuC842 i2c bus. I have gotten quite good at using it over the past few weeks but now with greater utilisation comes a need for better understanding. In the code bellow you can see a i2c “bit bang” transmission subroutine. The code works perfectly and does exactly what I want it to do unless I remove the CALL SENDVAL from I2C PCF DATASEND, in which case it send the address byte in 500u seconds and the data byte in 2250u seconds. So does anyone know why my could would do that??? Using the same routine with no CALL SENDVAL it will send the data byte at 1/5 the speed that it sends the address byte. I am using uVission4 MOD842
;__________________________________________________________________________
; I2C PCF DATASEND
I2CPCF:
; Send all the sequence to the PCF (address byte+data byte)
;!!!****!!!R0nan!!!===> I put a CALL SENDVAL command into this subrouteen to make it work.
CALL STARTBIT ; send start bit
MOV A, R_DAC_ADR ; send PCF address, PCF1 0x44 and PCF2 0x46
CALL SENDBYTE ; sets fI2C_NOACK if NACK received
JB fI2C_NOACK, STP_SND1 ; if no acknowledge send stop
MOV A, R_DAC_LSB ; send DAC LS-byte
;-----------------------*****(R0nan)******---------------------------
CALL SENDVAL ; I don't know how or why, but this makes it work...?
;-----------------------*****(R0nan)******---------------------------
CALL SENDBYTE ; sets fI2C_NOACK if NACK received
STP_SND1:
CALL STOPBIT ; sends stop bit
JNB fI2C_NOACK, SND_RET1 ; if slave sends no-acknowedge send error
SETB fI2C_ERR ; sets the error flag
SETB I2CRS ; this resets the I2C interface
SND_RET1:
RET
;______________________________________________________________________________________
;____________________________________________________________________
; I2C SENDBYTE
SENDBYTE:
; Send 8-bits in ACC to the slave
MOV R_BITCNT,#8 ; 8 bits in a byte
SETB MDE ; to enable SDATA pin as an output
CLR MCO ; make sure that the clock line is low
SENDBIT:
RLC A ; put data bit to be sent into carry
CALL DELAY5 ; delay 5uSec
MOV MDO,C ; put data bit on SDATA line
;-----------------------*****(R0nan)******---------------------------
CALL DELAY50 ; delay 50uSec
;-----------------------*****(R0nan)******---------------------------
SETB MCO ; clock to send bit
CALL DELAY5 ; delay 5uSec
CALL DELAY5 ; delay 5uSec
CLR MCO ; clear clock
DJNZ R_BITCNT,SENDBIT ; jump back and send all eight bits
CLR MDE ; release data line for acknowledge
CALL DELAY5 ; delay 5uSec
SETB MCO ; send clock for acknowledge
CALL DELAY5 ; delay 5uSec
CALL DELAY5
JNB MDI,NEXT ; this is a check for acknowledge
SETB fI2C_NOACK ; no acknowledge, set flag
NEXT:
CLR MCO ; clear clock
RET
;____________________________________________________________________
;____________________________________________________________________
; I2C STARTBIT
STARTBIT:
; Sends the start bit to initiate an I2C communication
SETB MDE ; enable SDATA pin as an output
CLR fI2C_NOACK
CLR MDO ; low O/P on SDATA
CALL DELAY5 ; delay 5 uSec
CLR MCO ; start bit
RET
;____________________________________________________________________
;____________________________________________________________________
; I2C STOPBIT
STOPBIT:
; Sends the stop bit to end an I2C transmission
SETB MDE ; to enable SDATA pin as an output
CLR MDO ; get SDATA ready for stop
CALL DELAY5 ; delay 5uSec
SETB MCO ; set clock for stop
CALL DELAY5 ; delay 5uSec
SETB MDO ; this is the stop bit
CALL DELAY5 ; *(R0nan)*
RET
;____________________________________________________________________
;____________________________________________________________________
; DELAY5
DELAY5:
; 5 uSec delay
PUSH ACC
MOV A,#0Eh
DJNZ ACC,$
POP ACC
RET
;____________________________________________________________________
;-----------------------*****(R0nan)******---------------------------
; ; DELAY50
DELAY50:
; 50 uSec delay
PUSH B
PUSH ACC
MOV B, #0x0A
DEL_50:
MOV A, #0x0E
DJNZ ACC, $
DJNZ B, DEL_50
POP ACC
POP B
RET
;-----------------------*****(R0nan)******---------------------------
SET_GAIN:
MOV R_DAC_ADR, #cb_PCF_1 ; Selecting the address of the 1st PCF i2c expander
MOV R_DAC_LSB, R_GAIN_1 ; Loading data for multiplexer M1, M2, M3
CALL I2CPCF ; output the values
;-----------------------*****(R0nan)******---------------------------
JB fI2C_ERR, SET_GAIN ; repeat i2c step *(R0nan)*
;-----------------------*****(R0nan)******---------------------------
;=========== transmitting PCF value via RS232
JNB TI,$ ; 3 4 ; wait til present char gone
CLR TI ; 2 2 ; must clear TI
MOV SBUF,#'P'; 2 2
MOV A, R_DAC_ADR ; 1st PCF address in A
CALL SENDVAL
MOV A, R_DAC_LSB ;; DAC LSB in A data for multiplexer M1, M2, M3
CALL SENDVAL
JNB TI,$ ; 3 4 ; wait til present char gone
CLR TI ; 2 2 ; must clear TI
MOV SBUF,#','; 2 2
;======end of the message
;-----------------------*****(R0nan)******---------------------------
SET_GAIN_2: ; *(R0nan)*
;-----------------------*****(R0nan)******---------------------------
MOV R_DAC_ADR, #cb_PCF_2 ; Selecting the address of the 2st PCF i2c expander
MOV R_DAC_LSB, R_GAIN_2 ; Loading data for multiplexer M1, M2, M3 Unit Gain
CALL I2CPCF ; output the values
;-----------------------*****(R0nan)******---------------------------
JB fI2C_ERR, SET_GAIN_2 ; repeat i2c step *(R0nan)*
;-----------------------*****(R0nan)******---------------------------
;=========== transmitting PCF value via RS232
JNB TI,$ ; 3 4 ; wait til present char gone
CLR TI ; 2 2 ; must clear TI
MOV SBUF,#'P'; 2 2
MOV A, R_DAC_ADR ; 2nd PCF address in A
CALL SENDVAL
MOV A, R_DAC_LSB ;; DAC LSB in A data for multiplexer M1, M2, M3
CALL SENDVAL
JNB TI,$ ; 3 4 ; wait til present char gone
CLR TI ; 2 2 ; must clear TI
MOV SBUF,#','; 2 2
;======end of the message
|



