Anzeige:

Uart-Verbindung zwischen Atmegas

Hier finden sie die archivierten Beiträge des alten PHPBB Forums von www.loetstelle.net

Uart-Verbindung zwischen Atmegas

Von Movie85 am 29.06.2009 14:41

Hallo Leute!

Ich bastle gerade an meinem Homecockpit rum und will die Elektronik komplett selber realisieren (keine fertigen Module kaufen).
Da ich nicht alles mit einem MC ansteuern kann, möchte ich das alles auf mehrere verteilen, die dann einzelne Module ansteuern. Mein PC hat leider keine 20 Serial-Ports, deshalb wollte ich versuchen alle Module (Atmega8 etc.) an ein gemeinsames RS-232(oder RS-485, wie immer das heißt) System anschließen.
Das heißt, ein Atmega ist der Master, die anderen alle Slaves(beide müssen Daten senden/empfangen). Der Master sendet dann die relevanten Daten an den PC.
Ich habe jetzt aber schon bei den Startversuchen Probleme: Daten von PC(Hyperterminal) zum Atmega zu senden und auszuwerten(wie das Tutorial von Gerold "Ausgänge mit PC steuern") funktioniert tadellos. Wenn ich jedoch statt den PC einen Atmega nehme, und mit ihm z.B. den Befehl "Print "SET 2 ON"" sende, passiert am anderen Atmega nix. Er empfängt zwar die Daten, erkennt aber nichtmal "SET"...

Daher: Weißt jemand zufällig, was hier das Problem ist? Angeschlossen hab ich das ganze richtig, er löst auch die Prozedur "Serial0charmatch" aus. Wenn ich jedes Zeichen einzeln sende, funktioniert es ebenfalls.

Viele Grüße,

Tom

Edit: Hier der Code vom Master:
1]
'Master
$regfile = "M8def.dat"
$crystal = 8000000

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

'Uart
$baud = 9600







Wait 1
'Main:
Do


'senden

Print Chr(65) ; ' A ON einzeln senden
Print Chr(32) ;
Print Chr(79) ;
Print Chr(70) ;
Print Chr(70) ; Chr(13)
Wait 2
Print "A ON" ; Chr(13) ' A ON zusammen senden
Wait 3

Loop

1]

Und der vom Slave:(Übernommen vom Tutorial " Ausgänge mit PC steuern")
1]
'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
Dim C As Integer
Dim Z As Byte
Dim B As String * 5

'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) , " ")


For C = 1 To 6 Step 1 'ASCII Code ausgeben, zur Überprüfung
B = Mid(new_command , C , 1)
Z = Asc(b)
Print Z

Next

For C = 1 To 3 Step 1
B = Mid(command_array(1) , C , 1)
Z = Asc(b)
Print Z

Next




Select Case Command_array(1)
Case "A"

Call Do_set_command(command_array(2))

End Select


New_command = ""
End If


Loop


'Subs

Serial0charmatch:
Input New_command Noecho
Return

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


1]

Von Sam am 07.08.2009 14:27

Wähle mal als BAUD-Rate statt "9600" "250000". Wie sieht es aus mit zeitkritischen Befehlen. Wenn µSekunden keine Rolle spielen, würde ich an deiner Stelle einen Quarz mit 3,6864 MHz nehmen. Die sind meiner Meinung nach am besten für UART geeignet.

MfG Sam

Re: Uart-Verbindung zwischen Atmegas

Von gerold am 08.08.2009 09:06

Movie85 hat folgendes geschrieben:
Wenn ich jedoch statt den PC einen Atmega nehme, und mit ihm z.B. den Befehl "Print "SET 2 ON"" sende, passiert am anderen Atmega nix. Er empfängt zwar die Daten, erkennt aber nichtmal "SET"...

Hallo Tom!

Das deutet meist auf Verbindungsprobleme hin. Es kann auch sein, dass beide ATmegas nicht genau getaktet sind. Ohne Quarz ist eine genaue Taktung kaum möglich. Wie weit sind die ATmegas voneinander entfernt?
Setze die Baudrate mal bei beiden auf das absolute "Minimum" und versuche es noch einmal. Je höher die Baudrate, desto mehr wirkt sich eine ungenaue Taktung des µC auf die Datenübertragung aus. Idealerweise verwendest du bei beiden µC Quarze um diese genau zu takten. Dann kannst du auch schneller übertragen.

Nur zwei Drähte zwischen zwei ATmegas zu spannen ist zu störanfällig. Das heißt, es funktioniert nicht mehr, sobald die Entfernung zu den einzelnen ATmegas größer wird. Ich habe keine Erfahrung damit, aber ich schätze, dass es schon bei mehreren zehn Zentimetern zu Problemen kommen kann.

Mit RS-232 kannst du Daten über längere Strecken übertragen. Hier sprechen wir schon von Metern. Der Spannungsunterschied zwischen einem LOW und einem HIGH ist ja auch größer als bei TTL-Level.

Für dein Gesamtprojekt würde ich dir unbedingt zu RS-485 raten. Das ist am wenigsten störanfällig (die Störungen in Autos sind enorm) und Daten können sehr schnell mehrere Meter bis Kilometer übertragen werden.

Lasse die Clients immer nur dann etwas sagen, wenn diese vom Master dazu aufgefordert werden. Ansonsten wird das ein riesiges Durcheinander.

mfg
Gerold
Smile

PS:

Vernünftige UART-Verbindungen sind bei 1 MHz Systemtakt nahezu unmöglich.

Noch so ein Fehler ist z.B. dass man eine falsche Zahl an "$crystal" übergibt.

Ist der ATmega per FuseBits auf 1 MHz eingestellt (das ist die Standardeinstellung) und man setzt die $crystal-Direktive auf 8000000, dann funktioniert das Timing natürlich auch nicht mehr.

Anzeige: