PDA

View Full Version : I2CWrite Problem



nuno106
- 16th March 2023, 15:46
Hi everyone,

I'm trying to send a simple 16 bits of data with the !2CWrite, but in Proteus I2C Debugger, i see the message separated.
The odd thing is when the Device ID is $78, it works, with other value, it simple break the message...

Can anyone understand what's going on?


ASM
__CONFIG _CONFIG1L, _PLLDIV_5_1L & _CPUDIV_OSC1_PLL2_1L
__CONFIG _CONFIG1H, _FOSC_INTOSCIO_EC_1H
__CONFIG _CONFIG2L, _PWRT_OFF_2L & _BOR_OFF_2L & _BORV_2_2L & _VREGEN_OFF_2L
__CONFIG _CONFIG2H, _WDT_OFF_2H & _WDTPS_512_2H
__CONFIG _CONFIG3H, _MCLRE_OFF_3H & _PBADEN_OFF_3H
__CONFIG _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L
ENDASM


DEFINE OSC 8 ' Velocidade padrão do 18F2550 qd em Internal Oscilator

'################################################# ##############################
' Default HSEROUT/IN do PIC #
'################################################# ##############################

'------------------------------ Time Variables ------------------------------

I2C_Address VAR Byte ' I2C - Comandos
Address_To Var Byte ' I2C - Comandos
Command var Byte ' I2C - Comandos
Command_2 var Byte ' I2C - Comandos


SDA VAR PortB.6
SCL VAR PortB.7


'----------------------------- Initial Settings --------------------------------

UCON.3 = 0 ' USB Disable, RC4 e RC5 Digital Input Only
UCFG.3 = 1 ' USB On-chip transceiver disabled

ADCON1 = %00001110 ' (5) Vss Referência, (4) Vdd Referência, (3-0) AN0 = Analog, restantes ANx Digitais
ADCON0 = %00000000 ' (5-2) An0 Selected, (0) A/D Module Off
ADCON2 = %10000000 ' (7) Right Justified, (5-3) A/D Acquisition Time - 0 Tad, (2-0) A/D Clock - FOSC/2

CMCON = 7 ' (2-0) 111-> Comparator Off
OSCCON = %01110000 ' (7) Enter Slepp Mode on Sleep Instruction, (6-4) 8 MHz, (1-0) 1x--> Internal Oscilator 00--> Primary Oscilator ???
' OSCTUNE = %00011111 ' Serve para fazer uma pequena afinação da velocidade do Clock do Processador

IntCon = %10010000 ' (7) Global Int Enabled, (4) Int0 - Enabled
IntCon2 = %00000000 ' (7) Pull_Ups Enabled, (6) Int0 - On Falling, (5) Int1 - On Falling, (4) Int2 - On Falling
IntCon3 = %00011000 ' Int1 - Priority Bit Off, (3) Int1 Enabled, (4) Int2 Enabled

TRISA = %00000001
TRISB = %00001111
TRISC = %10110000 ' O C.2 é definido como In, só qd é ligada a rega (PWM On), é q passa a Out.


'################################################# ##############################
'# Setup's #
'################################################# ##############################

Pause 500 ' Delay p PowerUp de todos os Devices
I2C_Address = $76
Address_To = $02
Command = $54
Command_2 = $70

Menu:
I2C_Address = I2C_Address +1

I2cWrite SDA,SCL,I2C_Address,Address_To,[Command,Command_2]
Pause 500

goto Menu


end


Thanks,
Nuno


9341

richard
- 17th March 2023, 00:20
I2C_Address = I2C_Address +1
makes no sense at all, in pbp i2c address are 7 bits + r/w bit at bit0
so i2c write to $76 and to $77 are writes to the exact same address

I2C_Address = I2C_Address +2
will get a "NEW" address

nuno106
- 17th March 2023, 08:40
Hi Richard and thanks for the reply.

The I2C_Address = I2C_Address +1 is only to show that 16 bits of data work when I2C_Address is equal to $78, in other cases, it don't work.

Thanks,
Nuno

richard
- 17th March 2023, 09:53
still makes zero sense .

if no slave device responds with an ack then the pbp code will terminate the transaction
sending data to random or incorrect address' will achieve and prove nothing at all

what are you really doing and what is the slave device , how is connected

tumbleweed
- 18th March 2023, 21:54
if no slave device responds with an ack then the pbp code will terminate the transaction
richard's correct in that if I2CWRITE doesn't get an ACK in response to writing a byte it immediately sends a STOP and returns with the CARRY flag set.
Unfortunately, it never checks the return value so it continues on with the rest of the bytes in the I2CWRITE statement (here you have four of them).

Since it just sent a STOP, it sends a START again, the next byte in the statement (which is now treated as a slave address), gets another NACK, sends STOP, etc, etc until all the bytes are sent.

It should really terminate the entire I2CWRITE statement when it gets a NACK to the the first byte (the slave address), but it doesn't... it just erroneously continues on writing what amounts to garbage to whatever "address" it runs across.

richard
- 19th March 2023, 05:21
Unfortunately, it never checks the return value so it continues on with the rest of the bytes in the I2CWRITE statement (here you have four of them).

Not what i find . it may vary by pic18/16 and/or pbp version
i my test the transaction terminates at the first nak and is followed by a "funny start" dud transaction , the data in the sq brackets is never sent

9342



pic18f45k80



'OSCTUNE.6 = 1 ; Enable 4x PLL
OSCCON = 110000




TRISD=000110 'set PORTD


define OSC 16
DEFINE I2C_SLOW 1
ADR VAR BYTE
ADR2 VAR BYTE
CMD VAR BYTE
ADR=$48
ADR2=$70


SDA VAR PORTD.3
SCL VAR PORTD.2




CMD= $48


FEDO:
I2CWRITE SDA,SCL,ADR,[5]
I2CWRITE SDA,SCL,ADR2,CMD,[3,4]
PAUSE 250
I2CWRITE SDA,SCL,ADR,[0]
I2CWRITE SDA,SCL,ADR2,$48,[2,7]
PAUSE 250
GOTO FEDO

edit
might be a proteus artifact also, i have not scoped it

tumbleweed
- 19th March 2023, 12:35
That produces a slightly different result, but it's still wrong... there are extra transactions after getting a NACK to the first byte (slave address).
"S 02 N P" shouldn't be there, and I have a hunch that if you change "ADR2=$70" to something else you'll find that is wrong too.
I didn't bother trying to figure out exactly what it's sending, but it's not really what's in the remaining I2CWRITE statement.

I looked at the asm code in both cases and there's nothing I see to look at the ack/nack result of sending a byte, except to send a STOP and reset the internal state so the next byte starts a new transaction. There's nothing to "skip over sending the remaining bytes" in the I2CWRITE.