PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Grundsatzfrage - I2C vs. 1Wire



m@rkus33
24.03.2007, 20:23
Ich schon wieder,

nachdem ich jetzt ewig mit i2c rumgetan habe und nicht richtig weitergekommen bin mal ne grunsätzliche frage.

Habe folgendes vor:

2 x M8, 1x M16/32

Die beiden M8 sollen dem M16/32 nach Aufforderung Daten bereitstellen. Dies sind aber nicht nur Bytes sondern auch Long Variablen.

Mit i2c krieg ich das mit den Bytearrays nicht geregelt.

So nun denke ich über 1Wire nach.

Ist das nun für meinen Fall besser geeignet? Ich habe mir die Bascom Hilfe angesehen und ich denke das ist einfacher über 1Wire zu machen. Da kann ich ohne Probs. Arrays hin und her schicken so wie ich es schon mit UART/RS232 gewohnt bin.

Liege ich da richtig, oder gibt es bei 1Wire auch so versch. Tücken?

Gruß

PicNick
25.03.2007, 10:06
Will den 1-wire nicht schlecht machen, aber ich find, wenn HW-TWI (I2C) vorhanden ist, ist ein kreuz-und-quer Betrieb damit schon recht gut zu lösen. Weiß nicht, was dein Problem mit byte-arrays ist ?

Ratber
25.03.2007, 13:12
........Liege ich da richtig, oder gibt es bei 1Wire auch so versch. Tücken?



Den "Erlkönig-Bus" gibt es (noch) nicht.
Irgendwo sind immer Fallstricke die Einarbeitung oder Aufwand erfordern.

m@rkus33
25.03.2007, 22:41
Hallo Ihr zwei,

war schon länger nicht mehr hier... ;)

Mir ist irgendwie der HW TWI auch lieber nur schnalle ich das nicht mit der Long/array geschichte.

Hier der Code. Mit dem einzelnen Byte gehts wunderbar, mit dem Array nicht.

Master


$regfile = "M8def.dat"
$crystal = 3686000
$baud = 9600

$lib "i2c_twi.lbx"

Config Timer1 = Timer, Prescale = 8
Const Timervorgabe = 19456
Config Lcd = 20 * 4
Config Lcdpin = Pin , E = Portd.3 , Rs = Portd.2 , Db7 = Portd.7 , Db6 = Portd.6 , Db5 = Portd.5 , Db4 = Portd.4

Config Scl = Portc.5
Config Sda = Portc.4

I2cinit

Config Twi = 100000


Declare Sub Datenholen
Declare Sub Zeittakttimer1



Dim B As Byte
Dim C As Byte
Dim D As Long
Dim Buf(4) as Byte
'***** geht nicht************
Dim Buf(4)as Byte at D overlay
'**************************

Dim Ttakt As Byte


Ttakt = 0
B = 0

Cls
Cursor Off

Enable Timer1
Enable Interrupts

On Timer1 Zeittakttimer1

Locate 1 , 1
Lcd "TWI master"

Do





If Ttakt = 5 Then Gosub Datenholen

Locate 2 , 1
Lcd "Startzeichen: " ; Chr(32) ; Chr(32) ; B ; Chr(32) ; Chr(32)

Locate 3 , 1
Lcd "Wert: " ; Chr(32) ; Chr(32) ; C ; Chr(32) ; Chr(32)
Locate 4 , 1
Lcd "Error : " ; Err

Incr B

Loop



Datenholen:

I2creceive &H40 , Buf(1) , 0 , 1
C = Buf(1)
B = 0
Ttakt = 0

'***das geht nicht***********
I2creceive &H40, Buf(4), 0, 4
C = Buf(1), 4
B=0
Ttakt =0
'*************************
Return

Zeittakttimer1:
Incr Ttakt
Timer1 = Timervorgabe
Return


End


Slave


$regfile = "m8def.dat"
$crystal = 7372800
' $baud = 9600
$lib "i2c_twi-slave.lbx"

Config Pinc.0 = Output 'LED1
Config Pinc.1 = Output 'LED2

Config Twislave = &H40, Btr = 2, Bitrate = 100000


Config Scl = Portc.5 ' Ports fuer IIC-Bus
Config Sda = Portc.4

Enable Interrupts

Dim C As Byte

'******geht nicht*******
Dim C as Long
Dim D(4) as Byte at C overlay
'*************************

C = 0
D=0

Do

Portc.1 = 1
Incr C
Incr D
Waitms 25
Portc.1 = 0
Waitms 25
Loop


'i2c Twi Sub
'--------------------------------
Twi_stop_rstart_received:

Return
'--------------------------------

Twi_addressed_goread:

Return
'--------------------------------

Twi_addressed_gowrite:
Portc.0 = 1
Twi = C
'*****geht nicht*****
Twi = D(1) , 4
'******************
Portc.0 = 0
Return
'--------------------------------

Twi_gotdata:

Return
'--------------------------------


Twi_master_needs_byte:

Return
'--------------------------------

Twi_master_need_nomore_byte:

Return





End


Habt Ihr zwei ne Idee?? Arbeite mit der neuesten Bascom Version und dr TWI-Slave lib.

Merci
Gruß

Ratber
25.03.2007, 23:04
So auf die Schnell hab ich das auch nicht exact im Kopf aber ich meine die Definition sollte andersrum sein.

Versuch mal



Dim Buf(4) as Byte
Dim D As Long At Buf Overlay

Hanni
25.03.2007, 23:33
So nun denke ich über 1Wire nach.

Ist das nun für meinen Fall besser geeignet? Ich habe mir die Bascom Hilfe angesehen und ich denke das ist einfacher über 1Wire zu machen.

Vergiss es, soviel ich weiss ist 1 Wire in der Slave Version insofern geschützt, das dieses nur als Hardware zu implettieren ist.
Nicht umsonst findet man recht wenige Beispiele zum Thema 1 Wire Slave (mir ist exakt eine Impletierung in Software bekannt!)... und recht viele zum Thema 1 Wire Master.

Ich denke mal, du solltest deine I2C Kommunikationsroutinen vielleicht einmal etwas überdenken.

Grüße,
Hanni

PicNick
26.03.2007, 06:54
Moment.

Was erwartest du, daß er da tut ?
Twi = D(1) , 4

wkrug
26.03.2007, 08:08
Zum Thema 1wire Slave:

Ich hab mich auch schon an einer 1wire Slave implementation versucht.
So richtig hat das nicht funktioniert. Das Hauptproblem ist das timing.
Wenn Du in deinen Slave Controllern alle anderen Interrupts abschaltest könnte es gehen, ansonsten sind die Zeitfenster so knapp, das während einer 1wire Abfrage kein weiterer Interrupt mehr auftreten darf.

Im Zweifelsfall würd ichs dann doch mit SPI probieren, wenn das verdrahtungstechnisch geht. Oder Du kämpfst dich doch noch mal in I²C rein.

Eine long int in einzelne Bytes zu Zersägen ist für Assembler eigentlich kein Problem.

Wie wärs, wenn Du dir eine Sub Routine Schreibst die eine long int Variable erwartet und 4 char's zurückgibt ?

m@rkus33
26.03.2007, 18:11
Danke für Eure Antworten

also ich bin nun überzeugt, das nur I2C hier in Frage kommt. ;)

@PickNic
Das war natürlich Blödsinn

@Ratber
es ist egal wie rum ich es schreibe das Resultat ist immer das gleiche

Ich habe nun das Problem, das das der Master nun von -65550 auf null zählt.

Was ist denn nu faul? Irgend ne Idee?

Hier der code vom Master:

$regfile = "M8def.dat"
$crystal = 3686000
$baud = 9600



$lib "i2c_twi.lbx"

Config Timer1 = Timer , Prescale = 8
Const Timervorgabe = 19456
Config Lcd = 20 * 4
Config Lcdpin = Pin , E = Portd.3 , Rs = Portd.2 , Db7 = Portd.7 , Db6 = Portd.6 , Db5 = Portd.5 , Db4 = Portd.4

Config Scl = Portc.5
Config Sda = Portc.4

I2cinit

Config Twi = 100000


Declare Sub Datenholen
Declare Sub Zeittakttimer1 'alle 1/10 Sekunden Timer1 overflow



Dim B As Byte

'Dim C As Long
'Dim Buf(4) As Byte At C Overlay

Dim Buf(4) As Byte
Dim C As Long At Buf Overlay

Dim Ttakt As Byte


Ttakt = 0
B = 0
C = 0

Cls
Cursor Off

Enable Timer1
Enable Interrupts

On Timer1 Zeittakttimer1

Locate 1 , 1
Lcd "TWI master"
'-------------------------------------------------------------------
Do

If Ttakt = 5 Then Gosub Datenholen

Locate 2 , 1
Lcd "Startzeichen: " ; Chr(32) ; Chr(32) ; B ; Chr(32) ; Chr(32)

Locate 3 , 1
Lcd "Wert: " ; Chr(32) ; Chr(32) ; C ; Chr(32) ; Chr(32)
Locate 4 , 1
Lcd "Error : " ; Err

Incr B

Loop
'-------------------------------------------------------------------


Datenholen:

I2creceive &H40 , Buf(1) , 0 , 4
'C = Buf(1)
B = 0
Ttakt = 0
Return

Zeittakttimer1:
Incr Ttakt
Timer1 = Timervorgabe
Return


End



und der Slave:


$regfile = "m8def.dat"
$crystal = 7372800
' $baud = 9600
$lib "i2c_twi-slave.lbx"

Config Pinc.0 = Output
Config Pinc.1 = Output

Config Twislave = &H40 , Btr = 2 , Bitrate = 100000


Config Scl = Portc.5
Config Sda = Portc.4

Enable Interrupts

Dim C As Long
Dim D(4) As Byte At C Overlay


C = 0

Do

Portc.1 = 1
Incr C

Waitms 25
Portc.1 = 0
Waitms 25
Loop


'i2c Twi Sub
'--------------------------------
Twi_stop_rstart_received:

Return
'--------------------------------

Twi_addressed_goread:

Return
'--------------------------------

Twi_addressed_gowrite:
Portc.0 = 1
Twi = D(1)

Portc.0 = 0
Return
'--------------------------------

Twi_gotdata:

Return
'--------------------------------


Twi_master_needs_byte:

Return
'--------------------------------

Twi_master_need_nomore_byte:

Return





End


muss wohl noch viel lernen :( oder bin ich schon zu alt dafür??? #-o

Ratber
26.03.2007, 18:46
Hast du mal nur aus jux die I2C Bitraten runtergesetzt um auszuschlissen das hier einfach nur Latenzproblem auftreten ?

Prüf das einfach mal mit 1000 nach.

m@rkus33
27.03.2007, 18:02
Hi Ratber,

hat auch nix gebracht. Wo habe ich den Fehler???

Ratber
27.03.2007, 18:54
Dann fällt mir jetzt auch nix mehr ein .

m@rkus33
27.03.2007, 18:58
oha, wenn du auch nix in petto mehr hast.... ;)

Ratber
27.03.2007, 19:50
Der Fehler ist schon zu finden aber dafür müßte ich mich jetzt ganz in deine Soft einarbeiten und dafür fehlt momentan effektiv die Zeit.

m@rkus33
27.03.2007, 21:13
passt scho, ratber.

jemand noch eine Idee????

ich habs immer noch nicht rausgefunden.

Gruß
Markus

Blauelf
29.03.2007, 14:00
Könnte es sein, dass hinter "Twi_master_needs_byte" etwas stehen sollte, nicht hinter "Twi_adressed_gowrite"?

Oder liege ich komplett falsch, wenn ich versuche, folgender Anleitung zu folgen?

http://avrhelp.mcselec.com/bascom-avr.html?CONFIGTWISLAVE

Tschüs
Der Blauelf (der momentan noch seinen ersten µC zu bändigen versucht, I²C ist da Zukunft ;))

m@rkus33
02.04.2007, 17:49
habe beides ausprobiert, es ist von der Auswirkung das gleiche.

ich habe so schwer den verdacht, das bascom bei i2c das mit den byte arrays nicht so macht wie bei rs232. leider finde ich nirgends ein beispiel oder eine hilfe. bytes einzeln hin und her zu schieben geht aber halt keie arrays. irgendwie raff ich das nicht.

wo sind denn die i2c spezis die sowas schon mal gemacht haben??

linux_80
02.04.2007, 18:59
Hallo,

beim Master geht das schon mit dem Versenden und Empfangen von Arrays, geht mit I2CSEND und Co., aber nur ein Bytearray !
Beim Slave muss man das erst wieder zusammenstellen, was rein kommt.

m@rkus33
03.04.2007, 07:16
hi linux_80

wäre das dann mit einer FOR- NEXT zu machen?

So in etwa:

Dim C As Long
Dim D(4) As Byte At C Overlay
Dim I as Byte

Dann bei

Twi_addressed_gowrite:
For i = 1 to 4
TWI = B(i)
Next
Return

Meinst Du das geht auch so oder muss ich alle einzelnen Bytes mit I2CSEND einzeln versenden.

So wie:

I2Cstart
I2C send B(1)
I2C send B(2)
I2C send B(3)
I2C send B(4)
I2Cstop

??

linux_80
03.04.2007, 19:25
Schau mal in die Hilfe, mit I2Csend sendet man gleich alles auf einmal, ohne sich um das Start und Stop zu kümmern, macht alles der Befehel für einen.
Man gibt nur das Array an, die Slaveadresse und die Anzahl Bytes die übertragen werden sollen aus dem Array.

m@rkus33
03.04.2007, 19:59
ja das ist schon richtig, nur bei mir soll es anders rum sein. Der Slave muss dem Master daten geben. Da habe ich in der hilfe nichts rauslesen können. Der Master sendet die Slaveadresse und soll dann den Datensatz lesen.