Erste Erfahrungen mit der seriellen Datenübertragung

Oskar01

Mitglied
24. März 2008
267
0
16
Köln
Sprachen
  1. Assembler
Hallo,
heute erste Erfahrungen mit der seriellen Datenübertragung beim STK500-Board
mit dem ATMega8515 gesammelt und in Screenshots dargestellt.
Hatte schon größere Befürchtungen, doch es klappte bis auf ein paar Kleinigkeiten, die ich (-wie meistens-) übersehen hatte, eigentlich auf Anhieb.

Punkt 1)
Die Errechnung der exakten Baudratenteilerwerte soll laut verschiedenen Testprogrammen im Net durch den Assembler selbst erfolgen und auch optimiert werden können. Das habe ich mir geschenkt und den heimischen Taschenrechner zu Hilfe genommen. Es wird die im Programmiertool unter Menü "Board" angezeigte Taktfrequenz des STK500-Boards eingesetzt. Es kommen "krumme" Werte heraus, wurde gerundet.

Punkt 2)
Die Übertragung funktioniert bis 4800 Baud auch bei höherer Anschlagsrate an der Tastatur ohne Probleme, bei 9600 Baud kommt es schon mal zur Anzeige von fehlerhaften Zeichen. Das steht aber sicher in Zusammenhang mit den in Punkt 1 genannten Quarzfrequenz-/Baudratenteiler-Werten. Bei weiteren Experimenten könnte man da sicher noch etwas besser "runden".

Punkt 3)
Verbindung wurde gesteckt von Port D Pin D0 und D1 an den zweipoligen RXD/TXD-Board-Jumper.
Natürlich kam es anfänglich zu keiner Verbindung, da ich ja die PC-Connection erst auf zweite DB-9-Verbindung am Board umstecken muß. Ist vielleicht IMHO etwas lästig, da man beim Programmieren das jedesmal wieder umstöpseln muß, Meldungen dazu in Screenshots Bild 8 und Bild 9. Auch Hyperterminal blockiert mir ja die Programmierschnittstelle, muß natürlich vor dem neuerlichen Flashen erst beendet werden, da ja die Maus auf COM1 läuft und ich somit keine seriellen Schnittstellen am PC mehr frei habe für das Terminalprogramm selbst.

Punkt 4)
Die anfänglichen Hurrah-Rufe über den (fast) auf Anhieb geklappt habenden Versuch, mit dem ATMega8515 über die serielle Schnittstelle eine Kommunikation mit der Außenwelt hergestellt zu haben, verstummten aber bald, als ich merkte, daß die Umlaute der deutschen Sprache nicht richtig wiedergegeben werden.
Habe per Experimenterfreude herausgefunden, daß dies mit der Terminalemulation in direktem Zusammenhang steht. Man muß zweimal hintereinander über Menü Eigenschaften das Hyperterminal entsprechend vorher konfigurieren (Bilder 10 bis 12 in den Screenshots).
Das Ergebnis präsentiert sich voller Stolz in Bild 13.

Fazit:
Hat super geklappt.

Gruß von Oskar01
 

Anhänge

  • RS232_01.zip
    37,2 KB · Aufrufe: 24
  • RS232_13.png
    RS232_13.png
    6,2 KB · Aufrufe: 56
  • RS232.txt
    2,6 KB · Aufrufe: 33
Guten Abend Oskar,

Dein Problem kann ich sehr gut nachvollziehen. Hab zwar zwei freie serielle Schnittstellen und habe dafür auch extra in meinen neuen Rechner noch eine PCI Karte spendiert aber ich habe lange genug hin- und her-gestöpselt.

Hast Du freie USB-Anschlüsse an Denem Rechner? Nachdem wie in meienm letzten Thread nachzulesen der AVRISP mkII nun auch unter Vista funktioniert bin ich ganz happy!

STK500 einmal aus AVR-Stuido heraus einstellen und dann bis auf weiteres zum proggen den mkII verwenden. Hat den Vorteil die RS232 beleibt Dir eizig und alleinig zum Daten übertragen.

Für mich hat das ganze noch einen weiteren Vorteil: Ich kann das STK500 nun erstmal im Schrank verschwinden lassen da ich mit dem mkII direkt auf mein Target komme. Damit sieht mein Arbeitsplatz gleich viel aufgeräumter aus :p

Vielleicht kannst Du mit der info zum mkII ja etwas anfangen. USB hat den Vorteil, dass man ggf. noch einen USB-Hub verwenden kann, wenn die Anschlüsse ausgehen.

Grüße und weiter gutes gelingen,
Markus
 
Hallo Markus,

ok. Danke für den Tip!

Meinst Du den Baustein AVRISP mkII ?


Da muß ich mich mal so langsam ranpirschen.....

Da stand auch was von Vista-Kompatibilität drin. Aber wie ich sehe, ist Dein Prob ja mittlerweile gelöst.

Mein Mutter-Bord am PC unterstützt nicht USB, fahre aber auf einem freien PCI- Slot (ISA-Slots hat das auch noch, ja, ja...) mit einem Lucent-USB-Host-Adapter.



So long....
Gruß von Oskar01
 
Hallo Oskar,

nein, ich meine nicht den Bustein sondern den fertigen Programmer von Atmel. Dirk hat Ihn auch hier im Forum-Shop.

Schau mal nach unter:
http://shop.avr-praxis.de/development-tools/programmer-und-mulator/avrisp-mkii.html

Was mir hierbei auffällt ist, dass das Proggen mit dem mkII x-fach schneller geht als das Proggen über RS232 und die STK500 eigene Umsetzung. Mit demn mkII werden die Daten so richtig in den Mega reingepustet :p

Hmmmm, habe aber keine Ahnung ob die AVR-Studio-USB-Treiber Deinen Lucent-Adapter unterstützen. Das müsste man mal probieren. Auf jeden Fall: ACHTUN! Solltest Du Dir einen mkII zulegen dann UNBEDINGT zuerst die treiber installieren, ggf. nochmals das AVR-Studio inkl. USB-Treiber-Update installieren und dann erst den mkII anstöpseln sonnst geht Dir wie mir und es geht nix mehr :rolleyes:

Grüße,
Ma
 
LCD eibinden und include-file falsch

Hallo,
ungeachtet der geplanten Anwendung des neuen Proggers, möchte ich noch etwas berichten zu den Versuchen mit dem U ( S ) ART.
Also, beim Studio4 hatte ich ein neues Projekt eröffnet und auch den Radiobutton auf ATmega8515 gesetzt. Offensichtlich ist aber das Include-File "8515...." nicht das richtige,
denn es muß "m8515..." heißen. Die Fehlermeldung "unknown statement" bei den UART-Registern allesamt. Der Assembler stoppt da.
Klaro, die Auswahl des MC im Studio4-Menü hat nichts mit dem im Editor manuell gesetzten Include-File zu tun, das reagiert ja erst, wenn ich assembliere mit "Built".
Dann meckert er, wenn es irgendwelche Unstimmigkeiten gibt ... und derer gibt es viele bei mir. -)
Im vorigen Prog-File hatte ich die "einfachen" 8-Bit-Register benutzt, jetzt aber UBRRH, UBRRL, UCSRB und so weiter.
Dabei ist mir noch aufgefallen, daß man diesen String für die Initialisierung nochmal senden muß, hat man das UCSRC mal nach unten angegebener Manier beschreiben.

Man kann nämlich UCSRC laut Datenblatt nicht "direkt" beschreiben, weil derselbe I/O-Bereich für UBRRH- und UCSRC-Register verwendet wird. Dazu muß erst der Wert 0x80 Hex in das UBRRH geladen werden (also Bit URSEL im UBRRH-Register auf high), damit das Ding auf das UCSRC Register springt.
Eigentlich sollte jetzt das UBRRH-Register unangetastet bleiben. Könnte aber sein, daß es anschließend, nachdem UCSRC (auch mit Bit für URSEL) beschrieben wurde, nochmals so geladen werden muß, daß Bit für URSEL (Bit7) wieder auf Low steht, womit dann UBRRH wieder aktiv ist.
Am besten aber zu Sicherheit den gesamte String mit UBRRH und UBRRL nochmal dahinter reinsetzen, wie ich es im unten angegebenen Proggi auch ausprobiert habe. Anders als von der Stackpointerinitialisierung her bekannt. (Dort erst Low, dann High, hier, beim USART erst High, dann Low.OK.)
(Jedenfalls verstehe ich die Dokumentation so, obwohl das auf Seite 153 angegebene Codebeispiel IMHO etwas irreführend ist. Auf Seite 8 und den auf die Seite 153 folgenden Seiten der Doku ist's aber korrekt dargestellt.
Übrigens:
Es muß nicht 3 sondern 6 heißen, wie ich anderswo gelesen habe.
Zitat:
ldi temp, (1<<URSEL)!(3<<UCSZ0)

für den hier verwendeten "Frame" 8N1 also korrigiert:

ldi temp, (1<<URSEL)!(6<<UCSZ0) (statt Ausrufezeichen den "komischen" Strich)

irgendwie richtiger wäre wohl diese Darstellung dafür:

ldi temp, (1<<URSEL)!(1<<UCSZ1)!(1<<UCSZ0)

wobei man natürlich "im Regen" steht, auf welcher Position im Byte-Rahmen genau die "Platzhalterbits" tatsächlich sitzen. Der Assembler scheint hier ja echt alles umsetzen zu können, vorausgesetzt, die Zuordnung ist mit dem "richtigen" Include-File vorher definiert.
Man kann natürlich auch das betreffende Include-File mit dem Editor öffnen und mal rumstöbern, ob man was findet dazu, vielleicht gibt es ja dann nochmals einen Aha-Effekt.

....Oder sehe ich das falsch, denn mit dieser Art der "bitweisen" Schreibweise habe ich so meine ganz spezifischen Probs.)

Das ist nun im Proggi konkret mit Hex-Werten ohne "Brimborium" drin.
.....Und es läuft wunschgemäß.

Hier der Programmschnipsel dafür:

Code:
ldi	temp,	HIGH(bdteiler)	;Baudratengenerator high byte
out	UBRRH,	temp 		;Teiler setzen
ldi	temp,	LOW(bdteiler)	;Baudratengenerator low byte
out	UBRRL,	temp
ldi	temp,	0x80
out	UBRRH,	temp
ldi	temp,	0x86		;Frameset 8N1
out	UCSRC,	temp
ldi	temp,	0x18 		;enablen TX und RX
out	UCSRB,	temp 		;an UART Control-Register
ldi	temp,	HIGH(bdteiler)	;Baudratengenerator high byte
out	UBRRH,	temp 		;muss nochmal reingesetzt werden
ldi	temp,	LOW(bdteiler)	;Baudratengenerator low byte
out        UBRRL,    temp                   ;muss nochmal reingesetzt werden


Unten noch die Response des LC-Displays, das ja die bekannte "Macke" hat, etwas zu verschlucken.

So long.....
Es grüßt,
Oskar01
 

Anhänge

  • LCD-RS232A.JPG
    LCD-RS232A.JPG
    16,6 KB · Aufrufe: 13
  • LCD-RS232B.jpg
    LCD-RS232B.jpg
    40 KB · Aufrufe: 17
  • LCD_RS232G.txt
    7,3 KB · Aufrufe: 10
  • S_153.png
    S_153.png
    45,1 KB · Aufrufe: 17
Registerinhalte in Hex-Format seriell auslesen

Hallo,
ok.
Erstens: Es geht jetzt auch mit 9600 Baud. (Teilerwert nochmals optimiert.)
Zweitens: Programm ergänzt um Konversion in Dezimalschreibweise und
Hexadezimalschreibweise.
Das Programm für die Dezimalzahlumwandlung eines 8-Bit-Register-Wertes vom allseits bekannten "Tutorial" klappte eigentlich auf Anhieb, so daß ich es mir hier schenke.
Nur, die Routine für die Hex-Darstellung zeigt mir nur Nullen.

OK.
Hab mich drangesetzt und mal selber was ausgedacht.

Ein Registerwert kann zwar auch unmittelbar ohne vorherige Umwandlung als ASCII-Character auf dem Terminal des PCs dargestellt werden, nur sieht das dann wie in Bild 1 "Direktausgabe" aus und erinnerte einen eher an ein abstraktes Teppichknüpfmuster.-)
Es ist dann auch noch von der Terminalemulation stark abhängig.
Möchte man nun einen Code möglichst unverändert darstellen, muß man einen anderen Weg beschreiten.

Die Voraussetzung:

Die Hex-Darstellung erfolgt bekannterweise bei acht Bit in zwei Zeichen.
Also brauche ich schon mal zwei Schreibvorgänge pro Wert.

Dann ist die Darstellung für Zahlen von 0 bis 9 eigentlich eine nicht sonderlich schwierige Umsetzung in den ASCII-Code: Man braucht nur die entsprechende Konstante addieren.

Für die Zahlendarstellung von 10 ab aufwärts bis 15 kann man nicht einfach jetzt eine Fortsetzung des bekannten ASCII-Codes nehmen, da durch die Sonderzeichen dazwischen eine Lücke entsteht, so daß eine zweite Kodierung notwendig ist.

Fazit: Eine Unterscheidung zwischen Ziffern von 0 bis 9 und 10 bis 15 bzw. A bis F wird notwendig.

Und dann das Ganze zweimal. Da in der Terminaldarstellung von links nach rechts gelesen wird,
muß nun die höherwertige Vierergruppe, sprich Nibble (... da war doch noch was mit LCD-Vierbitmodus oder so.....?) zuerst als Symbol geschrieben werden, dann das niederwertigere Nibble.
Der dazu angebotene Code hier läuft bei mir nicht:

Code:
hex:

push	temp3
swap	temp3
rcall	hex_
swap	temp3
 
hex_:

push	temp1
andi	temp1,	0x0F
cpi	temp1,	0x0A
brlt	hex_1
subi	temp1,	-('A'-'9'-1) 

hex_1:

subi	temp1,	-'0'
rcall	senden
pop	temp1
pop	temp3
ret

Habe nun das Ganze so realisiert:

Code:
hexumrechnung_:		;wandelt 8-Bit-Registerwert in
			;ASCII-Code in zwei Hex-Zeichen um
rcall	hex		;high nibble zuerst
rcall	hex_		;low nibble zuletzt
ret

hex:			;Umwandlung hoeherwertiges Nibble

mov	temp1,	zeichen	;sichert Inhalt des Ausgaberegisters 
mov	temp5,	temp1	;fuer weitere Operationen unten
swap	temp1		;schiebt hoeherwertiges Nibble nach
andi	temp1,	0x0F	;unten, Register wird maskiert 
cpi	temp1, 10	;springt auf Marke hex2, wenn Zahl
brsh	hex2		;groesser gleich 10 ist
rcall	hex1		;springt auf Marke hex1, wenn Zahl
ret			;0...9 betraegt

hex1:

ldi	temp4,	0x30	;addiert 48 zu Zeichen 0...9,
add	temp1,	temp4	;damit entspr.ASCII-Zeichen (0 bis 9)
rcall	ausgabe_txd	;entsteht;ruft serielle Ausgabe auf 
ret

hex2:

ldi	temp4,	0x37	;addiert 55 zu Zeichen 10...15, 
add	temp1,	temp4	;damit entspr.ASCII-Zeichen (A bis F)
rcall	ausgabe_txd	;entsteht;ruft serielle Ausgabe auf
ret

hex_:			;Umwandlung niederwertiges Nibble
			;gibt Inhalt des gesicherten Registers oben her
mov	temp1,	temp5	;niederwertiges Nibble ist schon unten
andi	temp1,	0x0F	;Register wird maskiert, untere 4 Bit
cpi	temp1, 10	;springt auf Marke hex2, wenn Zahl
brsh	hex2		;groesser gleich 10 ist 
rcall	hex1		;springt auf Marke hex1, wenn Zahl
ret			;0...9 betraegt

ausgabe_txd:		;Ausgabe serielle Schnittstelle

rcall	sendebereit
mov	zeichen,	temp1	;kopiert Wert von LED-Ausgabe
out	UDR,	zeichen	;bzw. obiger Rechenoperation
ret

sendebereit:

sbis	UCSRA,	UDRE	;springt zurueck, bis 
rjmp	sendebereit	;"Sendepuffer-leer-Flag" gesetzt ist
ret                                  ;dafuer muß UDRE enabled sein

.........

ldi	temp,	0xE0		;setzt RX, TX und Pufferleerflag
out	UCSRA,	temp	;in UART Control-Register A

...............

So long,

Gruß von Oskar01
 

Anhänge

  • Terminal_Capture.txt
    1,4 KB · Aufrufe: 7
  • RS232_La_2909.txt
    12,6 KB · Aufrufe: 10
  • Direktausgabe.png
    Direktausgabe.png
    2,8 KB · Aufrufe: 20
Watchdog und Quarzwechsel im Betrieb

Hallo,
nachdem ich bemerkte, daß sich das Programm immer nach etwa einer Stunde
"aufhängt", hatte ich die Idee, es mal mit dem "Bello", seines Zeichens Wachhund, zu versuchen. Ebenso wollte ich mal testen, ob es an der Taktfrequenzgenerierung liegt, denn die geht beim "Absturz" auf Kilohertzwerte.
So habe ich im laufenden Betrieb den 4 MHz Quarz reingesteckt und den Jumper OSCSEL mal umgesteckt.
(Übrigens läuft der Programmer immer noch mit der 3,868 MHz Frequenz trotz Quarzwechsel.)
Daß sich tatsächlich die Taktfrequenz ändert, kann man schon daran erkennen, daß nach anderer Rechnung des Baudratenteilers der UART wieder auf "Normal"-Anzeige anstelle von "Hieroglyphen"-Darstellung umschaltet. Ebenso vollführt der "Bello" sofort einen Reset.
Also, ich verstehe das so, daß er auf die WDR-Anweisungen wartet, die ihm sozusagen als Leckerli immer wieder in regelmäßigen Abständen vorgelegt werden müssen, sonst reagierte er sauer und bellt los. Habe mal die WDRs mal testweise so gesetzt, daß ich sehen kann, wann das Programm wieder von vorne losläuft, das ist tatsächlich hier im 2-Sekundenrhythmus. Was zu beweisen war.

Wichtig ist noch, daß die Interruptfreigabe erst hinter der Wachhund-Initialisierung erfolgt, dann - entgegen einiger Darstellungen im Net- das WDCE-Bit bei Vorteilersetzen auf "low" stehen muß.
Hier der entsprechende Code-Abschnitt. Die WDRs sind dann testweise immer vor den Ausgaben und den Zeitschleifen gesetzt. Bis jetzt blinkert das Programm noch vor sich hin, hat noch keinen "Absturz" gegeben.

Code:
;sei
cli
ldi	temp,	0x18	;Watchdog enable
out	WDTCR,	temp
ldi	temp,	0x0F	;Prescaler Set
out	WDTCR,	temp
wdr
sei
rjmp	start

Im Bild noch der "aktive" Quarzwechsel im Hyperterminal, man erkennt deutlich, die Baudrate und korrekte Zeichendarstellung ist taktfrequenzabhängig.

Es grüßt,
Oskar, jetzt auch stolzer Wachhundbesitzer, gut gemacht "Bello". Platz und Sitz!
 

Anhänge

  • Quarz.png
    Quarz.png
    2,8 KB · Aufrufe: 22

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)