i2c poorten - MikroBasic

Bavelt

Golden Member

Met het gevaar dat het al ergens anders stond, toch maar een vraag over I2C:

Ik heb uit vorge posts en antwoorden begrepen dat bij I2C het beter is om de I2C-poorten als input te definiëren, omdat anders bij output er aan wordt getrokken en conlficten met de I2C zou kunnen opleveren.

Nu heb ik een PIC16F1847. Zijn I2C is poort voor SDA Poort B.1 en SCL Poort B.4

Dus dacht ik in mijn onschuld, dan definieer ik de TRIS als:

pic basic code:

TRISB = %00010010

Maar dit veroorzaakt juist dat de I2c niet meer werkt!

Het probleem zit in de SCL, als die als inpt wordt gedefinieerd dan stopt het.
Definieer ik de hele TRISB als output dan loopt het weer.

Zie ik iets verkeerd?

Fouten zijn het bewijs dat je het probeert..

Je mag bij I2C nooit een '1' driven op de bus. Een nul wel. Een '1' moet komen door de pull-up. Dus, je moet tussen '1' en '0' schakelen dmv het tris register. Als input dan kan de pull-up omhoog trekken (of een ander device naar gnd). Als output komt de '0' naar buiten die je op de output poort hebt staan, continue, altijd.

"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein
Bavelt

Golden Member

Ok, maar met TRIS geef je toch enkel aan of de poort Input of Output is?

Ik stuur zelf geen waarde naar de poorten, omdat ik gebruik maak van de hardware matige I2C van de PIC.

Ik had ergens begrepen dat je deze SCL en SDA nooit als output mag definiëren.

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Ik zet ze altijd als input, nooit problemen...

pic basic code:

  TRISB         = %00010010                                                 
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Tja, ik had het ook zo neergezet.
Maar dan werkt de I2C niet meer.

In Onderstaande routine gaat het fout, en de processor blijft wachten.

pic basic code:

'===============================================================================
Sub procedure Read_DS3231()                         'Read Date in RTC registers
'===============================================================================
  i2c1_Start()
  i2c1_Wr(0xD0)
  i2c1_Wr(0x00)
  i2c1_Repeated_Start()
  i2c1_Wr(0xD1)
  Time[0] = i2c1_Rd(1)
  Time[1] = i2c1_Rd(1)
  Time[2] = i2c1_Rd(1)
  Time[3] = i2c1_Rd(1)
  Time[4] = i2c1_Rd(1)
  Time[5] = i2c1_Rd(1)
  Time[6] = i2c1_Rd(0)
  i2c1_Stop()
End Sub 

Weghalen van de input/instelling van de SCL biedt dan wél resultaat.

De SDA mag wel als input worden gedefinièerd.

Dus

pic basic code:

TRISB = %00000010 

gaat wel goed.

pic basic code:

TRISB = %00010010 

niet.
Vreemd

Fouten zijn het bewijs dat je het probeert..

Op 9 februari 2020 13:06:05 schreef Bavelt:
Ok, maar met TRIS geef je toch enkel aan of de poort Input of Output is?

Ja, normaal wel. Maar bij I2C mag je dus geen '1' driven, dus als je een '1' wilt op de bus, dan moet ie naar tristate, en dat krijg je als de poort input is. Voor een '0' moet je wel hard sturen, dus dan moet het een output zijn. Het is een trucje. Nu gebruik jij een library, die zou dat moeten doen.
Wb die SCL, zit er wel een pull-up op de SCL lijn, op je hardware? Dat zou verklaren waarom je die output moet hebben (kan ook prima trouwens).

"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein
Arco

Special Member

Het hoort toch echt zo hoor, uit de 1847 datasheet:

Als je ze als output zet, gaan de 'gewone' pindrivers touwtrekken met de open-drain i2c drivers...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Programma helemaal opgeschoond, en nu werkt het dus wel. ;)

Fouten zijn het bewijs dat je het probeert..