??? 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 |