Archiv verlassen und diese Seite im Standarddesign anzeigen : Daten von Software UART empfangen
Hallo,
ich möchte mit einem ATMEGA8 vom Software UART Daten empfangen.
Mit dem Hardware UART mache ich es so:
$regfile = "m8def.dat"
$crystal = 4000000
$baud = 19200
$framesize = 42
$swstack = 42
$hwstack = 42
Dim Eingang As Byte
Open "COMD.7:19200,8,N,1" For Output As #1
Open "COMB.0:19200,8,N,2" For Input As #2
Do
If Usr.rxc = 1 Then
Eingang = Udr
Select Case Eingang
Case "1" : Print #1 , "1" 'iv
Case "2" : Print #1 , "2" 'iru
Case "3" : Print #1 , "3" 'il
Case "4" : Print #1 , "4" 'ire
Case "5" : Print #1 , "5" 'is
Case Else : Print "???"
End Select
End If
Loop
End
Die Daten werden auch schon über Software UART weitergesendet. Aber ist es in dieser Art auch möglich Datren über SOFTWARE UART zu empfangen?
Freue mich auf jede Antwort!!
jon
P.S.:Kenn jemand einen Bootloader, mit dem ich den ATMega8 über meine ER400TRS brogrammieren kann?
Der Bootloadert von Frank kennt nur den ATMEGA32 :(
Ich weiß, es sind erst 3Std vergengen, aber kann mir niemand helfen???
Ich langweile mich :(
jon
Hallo Jon,
mit dem Befehl "SERIN var , byteanzahl , port , pin, baud , parity , dbits , sbits" kannst du Variablen per Sw-UART empfangen.
parity ist normaleweise 0, dbits 8 und s(top)bits 1.
Ich hoffe ich konnte dir weiterhelfen.
MfG Mark
Werd ich mal ausprobieren.
Danke für die Antwort!!
jon
Ich habe das jetzt schon vor längerer Zeit ausprobiert und es ging auch ganz gut^^
Jetzt habe ich das Problem, dass nicht immer was kommt. Ich will die kommenden Daten also nur abfragen, wenn auch welche kommen ;)
Im moment ist es so, dass er solange wartet, bis Daten kommt. Wenn da aber nichts kommt, soll er das einfach überspringen.
Am liebsten wäre mir so eine Variante wie oben in meinem Programm. Auch so, dass ich nur ein Byte empfange.
jon
Hallo Jon,
wenn du den SW-Uart wie den HW-Uart butzen willst, dann musst du RxD an einen Interrupt-Pin drangängen. Bei einer fallenden Flanke muss dann ein Interrupt ausgelöst werden, der das Byte empfängt und in eine Variable speichert. Eine zweite Variable kann dann als UCSRA1 dienen. Alternativ ginge es auch an jedem Pin, wenn du einen Timer einstellt, der ständig den RxD-Pin abtastet(normaleweise mit 3-facher Baud). Das ginge dann aber auf Kosten der CPU-Leistung sowie des Timers.
MfG Mark
Danke für deine Antwort.
Das wäre eine Möglichkeit mit dem Interrupt. Das werde ich mal probieren. Im moment sind nur meine Akkus leer :(
Was ist UCSRA1?
Und das mit dem Teimer fällt raus, da es so schnell wie möglich gehen soll.
jon
Hallo Jon,
UCSRA steht für UART Control and Status Register. dort werden Sachen des jeweiligen UART vermerkt wie z.b. ob ein byte empfangen wurde,ob der UART bereit ist ein byte zu senden usw. Eigentlich sollte es im obrigen Code UCSRA.rxd heissen, keine Ahnung wieso es in Bascom Usr heisst.
MfG Mark
Hast du dazu mal ein Beispielprogramm oder ist das in der Hilfe von BASCOM genannt (mit Beispiel)?
jon
Hallo Jon,
ich habe leider kein Beispielprogramm, weil ich in C programmiere. Ob das in der BASCOM-Hilfe steht weiss ich nicht. Du könntest es vllt so machen:
einfach Interrupt bei fallender Flanke aktivieren(wie das in Bascom geht, weiss ich nicht), in der ISR steht dann z.b.
serin UDR1, UCSRA1.rxd=1, return. die Variablen UCRSA1 und UDR1(Uart Dara Register) müssen zuvor natürlich deklariert werden.
wenn du dann eine gucken willst, ob ein byte empfangen wurde kannst du es mit "if UDR1.rxd=1 then..." abfragen. Das byte selbst steht dann in UDR1. Vergiss nicht, das UCSR1.rxd wieder zu löschen, wenn du im Hauptprogramm UDR1 ausliest.
Ich verspreche jedoch nicht, dass dieses Programm funktionieren wird.
Such mal bei google nach "software-uart bascom" vllt findest du was.
MfG Mark
Danke!!
dann werde ich mir mal die BASCOM-Hilfe anschauen und es mal probieren.
jon
Ich habe schon die BASCOM-Hilfe durchforstet, aber nichts gefunden :(
Jetzt bin ich aber auf die Idee gekommen über ein Low-Signal dem ATMega zu "sagen", dass was empfangen werden soll und er erst in eine Schleife geht, wenn das Signal wirklich anliegt.
Aber da ich diese Signalleitung auch zum Resetten (<--mit doppeltem "t"???) verwende, habe ich die Frage, wie lange ich den Reset-Pin auf low ziehen kann, ohne dass er resettet.
Ich werde gleich aber auch nochmal ins DB schauen :)
jon
Bluesmash
30.01.2007, 20:45
für den empfang mit der software uart kann ich nur die version mit dem interrupt empfehlen... bin gerade an nem projekt indem ich es verwende...
hier ein kleiner auszug aus meinem code must ihn halt noch abändern für deinen prozi... wichtig ist einfach dass der port für den empfang an einem interrupt pin hängt... bei mir wird der anfang der zu empfangenen daten mit einer 1 erkannt...
Open "Comb.6:9600,8,n,1" For Input As #2
Config Int0 = Falling
On Int0 Int0_isr
Enable Int0
Enable Interrupts
do
loop
Int0_isr:
Temp = Inkey(#2)
If Temp = 1 Then
Temp = 0
Servo1 = Waitkey(#2)
Servo2 = Waitkey(#2)
Speed = Waitkey(#2)
End If
Return
gruss bluesmash
Das blöde ist nur, dass bei mir schon alle Interrupt-Ports belegt sind :(
Sonst hätte ich es auch erst so versucht.
jon
Bluesmash
30.01.2007, 21:49
was hast du denn alles an den interrupts? ev. könnte man ja 2 zusammenfassen... indem man 2 auf einen interrupt legt und zusätzlich die beiden signale auf je einen normalen port legt, dann in der interrupt routine die beiden ports abfragen und schauen welcher interrupt ausgelöst hat....
gruss bluesmash
@Jon
Bluesmash hat den richtigen Weg beschrieben. Du solltest es in einer ISR abfangen.
Da Du auch mit einem ATMEGA8 arbeitest, verweise ich mal zur Info auf mein ATMEGA8-Projekt mit Software + Hardware UART:
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=26041
Ich verwende keine Interrupts. Ich habe nur noch einen Pin frei, den habe ich jetzt mit dieser Signal-Leitung belegt.
Weshalb ich kein Interrupt verwenden kann:
1.Kein Pin frei, der Interrupt hat
2.Kann ich nicht immer einen Interrupt vertragen, da ich auch die Signale abfragen muss, die von der Fernbedienung kommen. Und wenn er mich dann bei Vorwärtsfahren unterbricht, dann kann ich nicht bremsen. Kommt also eine Kannte, habe ich ein Problem.
Ich könnte zwar den Bot stoppen, aber das möchte ich nicht.
Ich werde es jetzt so mal probieren und schauen, was herauskommt.
jon
Ich verwende keine Interrupts.
Hallo Jon,
wie schon Bluesmash andeutete - es war nur ein guter Rat.
Wenn Du Dich mit Interrupts beschäftigst, wirst Du erkennen, das eine ISR der einzige Weg ist, um diese Unterbrechungen von INKEY/WAITKEY/GETRC5 o.ä. zu vermeiden.
Was benutzt Du für eine Fernsteuerung?
Das blöde ist nur, dass bei mir schon alle Interrupt-Ports belegt sind
Wirklich? Der Atmega8 besitzt mind. 4 Eingänge um Level-Interrupts zu erzeugen.
Eingänge: INT0, INT1, Analog Comparator ANA_COMP und noch den Timer/Counter1 Capture Event ICP1 (TIFR.ICF1)
Was benutzt Du für eine Fernsteuerung?
Diese (http://imadeit.roboterbastler.de/fernbedienung.html) O:)
Wirklich? Der Atmega8 besitzt mind. 4 Eingänge um Level-Interrupts zu erzeugen.
Eingänge: INT0, INT1, Analog Comparator ANA_COMP und noch den Timer/Counter1 Capture Event ICP1 (TIFR.ICF1)
Der muss aber auch mit 4µCs und über Funk kommunizieren. Da ist kaum weiterer Platz...
Aber ich habe es jetzt geschafft. Ich habe es hinbekommen, wenn ich mit dem Prog fertig bin, kann ich es mal auf meine Seite stellen.
jon
für den empfang mit der software uart kann ich nur die version mit dem interrupt empfehlen... bin gerade an nem projekt indem ich es verwende...
hier ein kleiner auszug aus meinem code must ihn halt noch abändern für deinen prozi... wichtig ist einfach dass der port für den empfang an einem interrupt pin hängt... bei mir wird der anfang der zu empfangenen daten mit einer 1 erkannt...
Open "Comb.6:9600,8,n,1" For Input As #2
Config Int0 = Falling
On Int0 Int0_isr
Enable Int0
Enable Interrupts
do
loop
Int0_isr:
Temp = Inkey(#2)
If Temp = 1 Then
Temp = 0
Servo1 = Waitkey(#2)
Servo2 = Waitkey(#2)
Speed = Waitkey(#2)
End If
Return
gruss bluesmash
Hi,
wie wird das von dem anderen Controller angesteuert? Also wie sendest du die Bytes? Ich hab folgenden Code für den Servocontroller:
$regfile = "attiny2313.dat"
$crystal = 8000000
Waitms 100
Config Servos = 4 , Servo1 = Portb.0 , Servo2 = Portb.1 , Servo3 = Portb.2 , Servo4 = Portd.6 , Reload = 10
Config Portb = Output
Config Portd.6 = Output
Config Int0 = Falling
On Int0 Int0_isr
Enable Int0
Enable Interrupts
Servo(1) = 100
Servo(2) = 100
Servo(3) = 100
Servo(4) = 100
Dim Temp As Byte
Dim New As Bit
Dim Servo_num As Byte
Dim Servo_pos As Byte
Open "Comd.2:9600,8,n,1" For Input As #2
Do
If New = 1 Then
Servo(Servo_num) = Servo_pos
New = 0
End If
Loop
Int0_isr:
Temp = Inkey(#2)
If Temp = 1 Then
Temp = 0
Servo_num = Waitkey(#2)
Servo_pos = Waitkey(#2)
New = 1
End If
Return
Und das is der Code von dem Controller, der dem Servocontroller die "Befehle" gibt:
$regfile = "m8def.dat"
$crystal = 8000000
$baud = 9600
Waitms 100
Do
Print 1
Print 1
Print 170
Wait 2
Print 1
Print 1
Print 70
Wait 2
Loop
End
Dadurch sollte der Servo sich immer vor und zurückdrehn. Allerdings bewegt er sich keinen Millimeter. Es muss am Soft-UART liegen, wenn ich den Servo direkt ansteuer gehts. Ich denke mal dass die "Print"-Befehle nicht in Ordnung sind.
Kann mir jemand helfen?
MfG
Ich denke mal dass die "Print"-Befehle nicht in Ordnung sind.
Genau. Die Zahlen müssen in "" sein. Also z.B.: Print "1"
jon
Hi Jon,
habs grad probiert, geht trotzdem net.
MfG
Ist Pind.2 überhaupt ein Interruptfähiger Pin?
jon
Ja, das is beim Tiny2313 Int0.
MfG
Gut.
Versuche mal zw. die Printbefehle 10ms Pausen zu setzten.
Dann sähe das Programm so aus:
$regfile = "m8def.dat"
$crystal = 8000000
$baud = 9600
Waitms 100
Do
Print "1"
waitms 10
Print "1"
waitms 10
Print "170"
Wait 2
Print "1"
waitms 10
Print "1"
waitms 10
Print "70"
Wait 2
Loop
End
Noch ne blöde Frage:
Hast du bei den Fusebits auch die 8MHz eingestellt?
Mehr finde ich im Moment nicht.
jon
Hi,
danke für deine Hilfe. Klappt aber leider nicht. Fusebits sind ok, Kommunikation mit dem PC klappt.
Es reicht schon wenn ich den TxD Pin des Mega8 mit dem RxD Pin des Tiny2313 verbinde oder sollte ich die beiden anderen auch miteinander verbinden (die bräuchte ich eigentlich nur wenn ich vom Tiny2313 etwas zum Mega8 senden will oder?)?
MfG
Es reicht schon wenn ich den TxD Pin des Mega8 mit dem RxD Pin des Tiny2313 verbinde oder sollte ich die beiden anderen auch miteinander verbinden (die bräuchte ich eigentlich nur wenn ich vom Tiny2313 etwas zum Mega8 senden will oder?)?
Die eine Leitung reicht. Mehr brauchst du ja nicht.
jon
Hat sonst vielleicht jemand noch eine Idee wieso es nicht klappt?
MfG
Hi,
ich hab jetzt versucht auf hardware UART umzusteigen. Allerdings funktionierts immer noch nicht :(
Hier mal mein Code vom Empfänger:
$regfile = "attiny2313.dat"
$crystal = 8000000
$baud = 9600
Waitms 100
Config Servos = 4 , Servo1 = Portb.0 , Servo2 = Portb.1 , Servo3 = Portb.2 , Servo4 = Portd.6 , Reload = 10
Config Portb = Output
Config Portd.6 = Output
Config Portd.1 = Output
Portd.1 = 1
On Urxc Onrxd
Enable Urxc
Enable Interrupts
Servo(1) = 130
Servo(2) = 130
Servo(3) = 130
Servo(4) = 130
Dim I As Byte
Dim Servo_data(2) As Byte
I = 0
Do
If I > 1 Then
Servo(servo_data(1)) = Servo_data(2)
I = 0
End If
Loop
Onrxd:
Incr I
Servo_data(i) = Udr
Toggle Portd.1
Return
End
An Portd.1 hängt eine LED, um zu schaun ob die ISR überhaupt aufgerufen wird. Allerdings wird sie nicht aufgerufen, die LED ändert nicht ihren Zustand.
Code vom Sender:
$regfile = "m8def.dat"
$crystal = 8000000
$baud = 9600
Waitms 100
Do
Print "1"
Waitms 10
Print "170"
Wait 2
Print "1"
Waitms 10
Print "70"
Wait 2
Loop
End
Ich weiß echt nicht mehr was ich machen soll. Es will einfach nicht klappen. ](*,) ](*,)
Hoffe mir kann jemand helfen.
MfG
Fehlt bei den Prog für den sender nicht noch das "Startsignal"?
Du musst doch erst eine Zahl >1 senden, damit er in die IF-Schleife geht.
jon
Ne, sobald ein Zeichen ankommt, wird das in dem Array Servo_data gespeichert. I ist nur der Zähler für die Array Elemnte, wenn I also größer als 1 ist, sind 2 Bytes (Servo Nummer und Position) angekommen und das Programm geht in die if-Schleife wo es den Servo ansteuert. Das Problem is ja, dass die ISR gar nicht aufgerufen wird...
MfG
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.