PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Mehrere Atmegas Koppeln- UART



Movie85
27.06.2009, 21:59
Hi Leuts,

ich hock grad vor einem, wahrscheinlich simplen Problem:
Ich versuch gerade mehrere Atmega8 zu verbinden, und zwar via UART.
Erstmal will ich es mit 2 Schaffen, danach mit mehreren. Ich verbinde also RxD un TxD jeweils gekreuzt. Eine Nachricht, der der Master sendet, heißt z.B. "A ON": Das heißt das er Slave A meint und die Nachricht "ON" schickt, was einfach eine LED anschalten soll.
Hier mein Code:
Master:


'Master
$regfile = "M8def.dat"
$crystal = 8000000

$hwstack = 100
$swstack = 100
$framesize = 100

'Uart
$baud = 9600
Config Serialin = Buffered , Size = 15 , Bytematch = 13
Enable Interrupts
'Main:
Do
'senden
Print "A"
Wait 2
Print "B ON"
Wait 2
Print "A OFF"
Wait 2
Print "B OFF"
Wait 2


Loop


Und Slave:


'Slave 1
$regfile = "M8def.dat"
$crystal = 8000000

$hwstack = 100
$swstack = 100
$framesize = 100

$baud = 9600





'Globale Variablen
Dim Tmp As Byte
Dim New_command As String * 15
Dim Command_array(3) As String * 5
Dim New_status As Bit


'Prozeduren
Declare Sub Serial0charmatch()
Declare Sub Do_set_command(cmd_output As String)

'Configs
Config Portc.5 = Output
Portc.5 = 1
Config Serialin = Buffered , Size = 15 , Bytematch = 13
Enable Interrupts

'Main:
Do
If New_command <> "" Then
'Alles in Großbuchstaben umwandeln
New_command = Ucase(new_command)

'Anweisung aufteilen
Tmp = Split(new_command , Command_array(1) , " ")

Select Case Command_array(1)
Case "A"
'Status des Ausganges/der Ausgänge zurück geben
Call Do_set_command(command_array(2))
Toggle Portc.5
End Select

New_command = ""
End If


Loop


'Subs

Sub Serial0charmatch()
Input New_command Noecho
End Sub

Sub Do_set_command(cmd_output As String * 5)
Select Case Cmd_output
Case "ON"
Portc.5 = 1
Case "OFF"
Portc.5 = 0
End Select

End Sub



Wenn ich jedoch starte, dann passiert beim Slave nix. Der Master sendet fließig(sieht man am Hyperterminal) doch der Slave verarbeitet das Signal nicht. Ankommen tuts (Serial0charmatch wird aufgerufen), aber er erkennt "A" nicht. Wenn ich per Hyperterminal "A ON" sende, dann funzts...

Ich bin nicht so der Bascom-Kreck, vielleicht hab ich mich mit irgendwelchen Variablen vertaen...

Vielleicht kann ja irgendjemand helfen,

Grüße,

Tom

peterfido
27.06.2009, 23:27
Im Master fehlt hinter A das on.

Movie85
28.06.2009, 09:19
Hi,

danke für deine Antwort, aber das "A" hatte ich nur mal zu Testzwecken genommen, um zu prüfen, ob es an dem "on" liegt.

Gruß,

Tom

EDIT:
Ich hab jetzt nochmal nachgeprüft, und den Slave mal das ausgeben lassen, was er bekommt. Er bekommt ganz normal "A OFF" und dann halt CR.

Ich verstehe nicht warum das nicht funktioniert, ich hab auch schon versucht CHR(64) zu senden. A kommt an aber es tut sich nix...

Christian H
28.06.2009, 09:36
Hi,

Semikolon (carriage return) hinter den Text setzen.
Print "A on";
sollte funktionieren


Gruß

Christian

Movie85
28.06.2009, 09:42
Hi,

danke für die Antwort aber soweit ich weiß verhindert das Semikolon Carrige Return. Ohne sollte CR und LineFeed(oder so) automatisch gesendet werden.

Gruß,

Tom

PS: Habs auch ausprobiert

robin
28.06.2009, 09:55
hi,

ich hab den quelltext nur mal überflogen, kann es evtl. daran liegen, dass du bei deiner slave zwar ein "A[leer]ON" erhälst, aber in deiner auswertung auf das Signal "AON" wartest, also dieses Leerzeichen nicht bei der auswertung mit einbeziehst?

Wie gesagt, ich hab den code nur überflogen und in bascom hab ich auch lang nicht mehr programmiert.

mfg robin

Movie85
28.06.2009, 09:59
Hallo,

guter Ansatz, aber
Tmp = Split(new_command , Command_array(1) , " ") splittet das eingangssignal nach einer Leerzeile in ein Array.
Und wie gesagt, wenn ich mit Hyperterminal genau das gleiche sende wie der master, dann funktionierts beim Slave!

Grüße,

Tom

Edit:
Sagtmal kann es sein das die Server-Zeit um eine Stunde zu spät ist?:D

for_ro
28.06.2009, 11:33
Wenn es vom Hyperterminal aus geht, zwischen den µC aber nicht, dann würde ich mal auf einen Unterschied zwischen den CR/New_Line Zeichen tippen.
Lass dir doch mal die Länge des Strings ausgeben, bevor der Split Befehl es zerstückelt, und danach die Längen der einzelnen Stücke.
Evtl. kannst du auch die ASCII Werte aller Zeichen ausgeben.
Wenn dann irgendwo noch der Wert 10 oder 13 auftaucht, dann ist das der Grund für den Fehler.

Gruß

Rolf

iBot
28.06.2009, 12:31
Moin,
kann man eig. auch 2 Atmega über Pins und Ports miteinander "reden" lassen ?
Wäre doch deutlich einfacher oder nicht ?
MfG iBot

Movie85
28.06.2009, 12:42
Hi,

danke Rolf, das hilft mir weiter:
Ich hab jetzt herausgefunden, dass der Gesamtstring (New_command) eine länge von 6 hat, und Command_Array(1) eine Länge von 3. (Bei "A ON").
Es besteht aus den Ascii Zeichen: 53, 10, 66, 32,79, 78.
Command_Array(1) besteht aus 53, 10, 66.
Was ja völliger quatsch ist!!
Wenn ichs per Hyperterminal mache dann bekomm ich meine 64, etc...

Was läuft da denn schief?

Grüße,
Tom

Edit:
Geht bestimmt auch, aber mit Uart hat man halt schon das Protokoll vorgefertigt...............

magnetix48
28.06.2009, 13:47
Hallo,
kann es sein, dass Du ein Geschwindigkeitsproblem beim slave hast? Wenn Du über das Terminal eintippst, ist der Zeitabstand zwischen den Zeichen größer!

gruß
magnetix48

for_ro
28.06.2009, 14:11
Gib mal hinter den Input-Befehl ein
Clear SerialIn
um sicherzustellen, dass der Buffer komplett leer ist.
66 32 79 78 hätte ich laut ASCII Tabelle allerdings als B ON übersetzt.
Wieso erwartest du eigentlich 64?

Gruß

Rolf

magnetix48
28.06.2009, 14:23
Hallo,

die Routine Serial0charmatch() wird garnicht aufgerufen. Woher bekommt der slave seine Informationen?

Gruß
magnetix48

Movie85
28.06.2009, 14:51
Hi,
Serial0charmatch() wird automatisch nach empfangen von CR aufgerufen.
Hm, es kann sein dass ich mich bei dem Ermitteln vertan habe, aber ich erwarte halt als erstes: "65, 32, 79, 78"( sorry, nicht 64).
Ich werde nachher nochmal alles nachprüfen. Aber auch wenn ich mich mit dem B On vertan habe, was hat das 53, 10 da zusuchen?(Also Line Feed und 5).

Grüße und danke,

Tom

for_ro
28.06.2009, 15:03
Hallo,

die Routine Serial0charmatch() wird garnicht aufgerufen. Woher bekommt der slave seine Informationen?

Das Label Serial0charmatch: wird automatisch angesprungen, wenn du ein
Config Serialin ByteMatch <chr> eingibst.
Man braucht das auch nicht zu deklarieren, weil es keine Sub im eigentlichen Sinne ist.

@Movie85: Hast du mal das Clear SerialIn probiert?

Gruß

Rolf

Movie85
28.06.2009, 15:33
Also,

ich hab das Clear SerialIn eingesetzt, hat aber keine Wirkung ergeben.
Ich habs dann mal so versucht, jedes Zeichen einzeln zu senden(ohne CR) und dann am schluss mit CR abzuschließen:


Print Chr(65) ;
Print Chr(32) ;
Print Chr(79) ;
Print Chr(70) ;
Print Chr(70) ; Chr(13)

das funktioniert!
Wenn ich jetzt aber Print "A ON" ; Chr(13) ausführe, gehts wieder nicht, obwohl ich jetzt überprüft habe, dass genau das selbe ankommt, wie beim Hyperterminal (65,32,79,78). Ich hab die Baudrate auch schon auf 2400 runtergesetzt, keine Veränderung!

Grüße und nochmals danke,

Tom

magnetix48
28.06.2009, 15:55
Hallo,

in der Hilfe von Bascom ist die Verwendung von Serial0charmatch anders angegeben.

Versuch es doch mal statt:
Sub Serial0charmatch()
Input New_command Noecho
End Sub

mit:
Serial0charmatch:
Input New_command Noecho
Return

Gruß

magnetix48

Movie85
28.06.2009, 17:33
Hi,

danke, aber das nützt nichts, das Komische ist ja, dass es mit dem Hyperterminal reibungslos funzt. Jedoch nicht mit dem Atmega... Es scheint so, als würde er die Daten anders verschicken, aber dann verstehe ich nicht, warum ich mit der Ascii-Auswertung genau die selben Werte erhalte...

SEHR KOMISCH!!!
Mich nervt das jetzt wieder, ich hock den ganze Tag an diesem einem Problem! Obwohl ich eigendlich ein ganz anderes Programm schreiben wollte. Es funktioniert ja theoretisch, alles fein, aber halt nicht von Atmega zu Atmega....

Grüße,

Tom

magnetix48
28.06.2009, 17:45
Hallo Tom,

meine Vermutung ist, dass Du Geschwindigkeitsprobleme beim slave hast. Das Aufrufen eines Unterprogramms dauert länger als ein GOSUB - RETURN, da Register auf dem Stack abgespeichert werden müssen.
Wenn Du die Daten über's Terminal eingibst, entstehen längere Pausen zwischen den übertragenen Daten, die reichen dass der Controller nichts überliest.

Gruß
magnetix48

for_ro
28.06.2009, 19:40
Hallo Tom,
Das Aufrufen eines Unterprogramms dauert länger als ein GOSUB - RETURN, da Register auf dem Stack abgespeichert werden müssen.

Hallo Magnetix48,
deine Aussage stimmt so nicht.
Es ist zeitmäßig vollkommen egal, ob du mit Gosub-Return durch eine Sub läufst, oder mit Call-End Sub. Die reine Zeit zum Aufrufen und zurückspringen sind immer 7 Zyklen. Der Unterschied ist lediglich, dass im Declare Befehl Parameter angegeben werden können, die dann in der Sub benutzt werden können.
Und du hast recht, Serial0CharMatch ist ein Label, was angesprungen wird und keine Sub. Allerdings macht Bascom da keinen Unterschied, zumindest bis jetzt noch nicht.

@Movie85 Bist du dir ganz sicher, dass sämtliche Zeichen, die von Hyperterminal gesendet werden exakt so auch von deinem Master kommen und auch nur diese?
Ich glaube immer noch, dass da das Problem liegt.

Gruß

Rolf

Movie85
29.06.2009, 14:13
Hi,
also, ich hab das ganze jetzt nochmal mit DOCKLIGHT durchchecken lassen, und er meint auch, dass die Befehle(also erstmal alles einzeln, dann zusammen) genau gleich gesendet werden: "65 32 79 70 70 13 13 10" Warum zweimal CR und dann noch Line Feed gesentet wird, ist mir jedoch unklar. Aber das ist ja egal, es funktioniert ja.
Ich bin jetzt auch der Meinung, dass es ein Geschwindigkeitsproblem ist (wie Magnetix gesagt hat). Jedoch weiß ich nicht, wie ich dieses Problem beheben kann...
Vielleicht sollte ich doch auf I2C umsteigen oder so, ich weiß nicht...

Grüße

Tom