mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Timerproblem 89C5131A-UM


Autor: M. D. (derdiek)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich hab versucht mich mit dem Datenblatt ins Thema Timer einzulesen, 
aber komme nicht so recht weiter.

Also ich habe einen Controller: AT89C5131A-UM.
Ich will eine Baudrate generieren für die serielle Schnittstelle.
Das Quartz ist ein 12 Mhz, da ich dieses für die integrierte 
USB-Schnittstelle zum flashen brauche.

Was ich jetzt nicht verstehe, ist ob man weiterhin Timer0 und Timer1 
benutzen kann, wie beim 89C51CC03, den ich von der Schule bekommen habe, 
oder ob man das jetzt alles mit dem Timer2 realisieren muss, weil im 
Datenblatt nichts mehr von Timer0/1 beschrieben ist.
Zudem sind für Timer2 mehrere Formeln angebenen, einmal in der Sektion 
Serial I/O Port, und in Timer2. Da steig ich momentan nicht richtig 
durch.

Wie muss ich da jetzt allgemein vorgehen wenn ich eine Baudrate von 9600 
haben möchte?
Meine momentane Initialisierung ist folgende:
SCON=0x50;
BDRCON &= 0xEC //BRR=0, SRC=0
BDRCON |= 0x0E //TBCK=1, RBCK=1, SPD=1
BRL= 0xF9 //Wert vom Keil-Rechner, Teiler fragwürdig
ES=1
BDRCON |= 0x10 //starten

Gruß derdiek

Autor: 5131benutzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sieht eigentlich ok aus
ich würde klare Verhältnisse schaffen mit
BDRCON = 0x0E

also
BDRCON = 0x0E ; stop baudrateclock
SCON = 0x50
BRL = 217 ; 256-39 = 9600 baud @ 12 MHz, SMOD1 = 0
ES = 1
BDRCON |= 0x10


für polling statt interrupt setze ich
SCON = 0x52

Autor: 5131benutzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sri, natürlich // statt ;
bin mehr der Assembler-Freak ;-)

Autor: 5131benutzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Timer1 und 0 kann man weiterhin benutzen.
Deren Dokumentation hat Atmel in ein allgemeines
8051-PDF verschoben.
Auch Timer 2 kann man unabhängig von dem Baudraten-
Generator benutzen, wenn Du den gesonderten Baudraten-
takt (BRR) benutzt, wie Du es oben codiert hast.
Es stehen also alle drei Timer 0, 1 und 2 frei zur
Verfügung.

Autor: 5131benutzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Beschreibung zu Timer 0 und 1 und weitere 8051-
Architektur-Details hat Atmel in folgendes Dokument
verschoben:
doc4316.pdf

Eine Beschreibung des Befehlssatzes zu 8051 findet
man in:
doc0509.pdf
Für Dich als C-Programmierer weniger interessant,
aber es lesen hier vielleicht noch Andere mit.

Autor: M. D. (derdiek)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alles klar, besten Dank für die Hinweise.

Werd mich da mal durch lesen. Mit dem BRL-Wert 217 funktioniert es 
leider noch nicht, evtl hab ich da auch was anderes falsch gemacht.
Es kommt nur Quatsch im Terminal an momentan ;)

Autor: 5131benutzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
SMOD1 in SCON ist 0 ?

Autor: M. D. (derdiek)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist doch nach dem Reset automatisch 0 oder?
Sonst setz ich das nochmal direkt auf 0.

Autor: 5131benutzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein wenig mehr source-code wäre hilfreich...
Insbesondere, was die Interrupt-Behandlung
der TX-Routine betrifft.
Das TI-Flag ist eine beliebte Falle.

Vielleicht eine wiederkehrende Sequenz schicken,
z.B. 0x55. Dann mit hterm das empfangene Bit-
Muster analysieren.

Autor: 5131benutzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, SMOD1 ist default 0, aber ich sehe ja nicht den
ganzen source-code. Wer weiß, ob da nicht irgendwo
SMOD1 = 1 steht? ;-)
Ich setze z.B. SMOD1 immer auf 1, aber das braucht
es in diesem Falle nicht.

Autor: M. D. (derdiek)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moment ich schließ mal mein Scope an und versuch die Baudrate zu messen.
Meld mich gleich nochmal.

Autor: M. D. (derdiek)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im restlichen Code wird nichts mehr mit den Registern gemacht, nur noch 
SBUF. Das was ich gepostet hab steht in der Serial_Init und die wird nur 
einmal aufgerufen.

Hab das Scope mal angeschlossen, wenn ich 0x55 in einer Schleife 
schicke, sind die Flanken 190uS auseinander, 1/0,00019 = 5263,16
Also fallende Flanke 1 -> steigende Flanke 1. |_|

1/9600 = 104,2 uS..
Dann müsste ich also den Reloadwert größer machen damit der Timer nicht 
so lange läuft oder?

Autor: 5131benutzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
füge bei der Baudraten-Einstellung ein
PCON |= (1<<SMOD1)

oder

PCON |= 0x80

Autor: 5131benutzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich denke mal, die Formel im Datenblatt stimmt bezüglich
SMOD1 nicht.

Sollte wohl besser 2^(1-SMOD1)
statt 2^SMOD1
lauten...

Autor: M. D. (derdiek)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Komisch ist eigentlich das selbst wenn ich per Scope die Baudrate auf 
ca. 100uS einstelle nur Quatsch ankommt..

Du meinst also SMOD = 1, und dann

BDRCON = 0x0E ; stop baudrateclock
SCON = 0x50
BRL = 217 ; 256-39 = 9600 baud @ 12 MHz, SMOD1 = 0
ES = 1
BDRCON |= 0x10

?
Dann müsst ich ja bei über 10k Baud liegen oder nicht?

Autor: M. D. (derdiek)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm.. Weiß zwar nicht wieso aber jetzt gehts ;)
Habs jetzt so gemacht, Smod=1 und restliche Einstellungen wie von dir 
gepostet.

Besten Dank :)

Autor: 5131benutzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok, also das mit SMOD1 in der Formel passt schon. ;-)

Ich hatte übersehen, dass ich meine 5131-CPU mit X2 = 1
betreibe, also im 6-clock-Modus.
Damit verdoppelt sich die Taktfrequenz für den Bauraten-
Generator.
Für die Einstellung der richtigen Baudrate sind also
nicht nur BRL, SPD und SMOD1 zu beachten, sondern auch
X2 (in CKCON0).

Mit
X2 = 0 (default)
SMOD1 = 0 (default)
SPD = 0 (default)
BRL = 253 // 256-3
für 9600 Baud zu setzen

Ich würde bevorzugen
X2 = 1
SMOD1 = 1
SPD = 1
BRL = 178 // 256-78
ebenfalls für 9600 Baud

Autor: 5131benutzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also um das abzuschließen - es geht ja jetzt -
in meinem ersten Beispiel hatte ich meine X2 = 1
unterschlagen, womit bei Dir mit X2 = 0 dann
natürlich nicht 9600 Baud, sondern 4800 Baud
erzeugt wurde. Das passt zu Deiner Messung von
ca. 190 us pro Bit - genau wären es 208 us für
4800 Baud gewesen.

Die beste Näherung an die 9600 Baud bekommst Du
mit den Einstellungen
X2 = 1
SMOD1 = 1
SPD = 1 // steckt in dem BDRCON = 0x0E drin
BRL = 178 // 256-78

die Variante
X2 = 0
SMOD = 0
SPD = 0
BRL = 253 // 256-3
liefert 10416 Baud als Näherung an 9600 Baud
und verbietet sich eigentlich wegen der über
8% Abweichung.

Womit auch klar wird, warum ich gerne SMOD = 1
setze.
Und X2 = 1 verdoppelt die Leistungsfähigkeit
Deiner CPU.

Viel Spaß mit dem AT89C5131!

Autor: 5131benutzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ersetze SMOD durch SMOD1 oben. ;-)

Autor: M. D. (derdiek)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jo supi, das mal ne gute Erklärung.
Danke für deine Hilfe!

Ich versteh nur noch nicht, wie du auf die BRL-Werte kommst.
also die 256-78, bzw die 256-3.

Aber dafür hab ich glaub noch zu wenig Hintergrundwissen.

Autor: 5131benutzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
für die 256-78:
12 MHz  16  9600 = 78,125 Hz, näherungsweise 78 Hz
Also ist der Teiler 78, um aus 12 MHz die 9600 Baud
zu gewinnen.

Der Baudratenteiler ist aber ein Aufwärtszähler, d.h.
er wird immer beim Überlauf 255->256 neu gesetzt.
Um einen Teiler durch 78 zu erhalten, muss der Teiler
mit 256 minus 78 vorbelegt werden, damit er nach 78 Takten
"überläuft" und BRL als Startwert neu nach BRH geladen
wird.
256-78 = 178 als Startwert.
178..179..180.. usw. 255..256(=0) peng! neu laden mit
178..179.. usw.

mit 256-3 das Gleiche, der Zähler wird aber nicht mit
12 MHz gefüttert, sondern mit 12 MHz /12 /6 und danach
noch einmal /2 (SMOD1).
12 MHz /2 /6 2  16 / 9600 = 3,255 Hz, näherungsweise 3 Hz
aber viel weiter weg als 78,125 zu 78...
Der Teiler wäre daher 3, bzw. da ein Aufwärtszähler
253..254..255..256(=0), durch 253 ersetzt

Die Gurus und Egonamen in disem Forum mögen meine
unprofessionelle Zusammenfassung verzeihen...
Andere können das natürlich viel besser erklären. ;-)

Autor: 5131benutzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
da gingen ein paar / verloren ;-)
einfügen, wo passend erscheint

Autor: M. D. (derdiek)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah naja aber hast es gut genug erklärt, habs zumindest soweit verstanden 
das ich auch von alleine auf den Wert kommen kann jetzt ;)

Hast mir sehr weiter geholfen :)

Autor: Bernhard Spitzer (b_spitzer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch ein Tip zur Nutzung der seriellen Schnittstelle in C.
Wenn man sich von der Assembler-SBUF-Fummelei löst und auf Standard-C 
Funktionen aus der stdio.h zurückgreift wird ein Programm leichter 
portierbar. Mit printf("Hallo"); wird z.B. direkt auf die serielle 
Schnittstelle gesendet. Zeichen=getch(); oder putch(Zeichen); 
funktionieren auch ganz nett. getch() macht dabei automatisch ein Echo 
(mit putch).

Nun aber zur Falle dabei: printf() und putch() prüfen das TI-Falg VOR 
dem Versenden eines Zeichens und sparen damit evtl. die Wartezeit, wenn 
der UART eh frei war. Dabei muss man aber das TI-Flag bei der 
Initialisierung einmal setzen, sonst hängt das Programm nach printf.
Also SCON = 0x52; schreiben.
(zumindest gilt das für uVision und RIDE. Beim SDCC ist putch() leer und 
muss selber programmiert werden, da hat man dann das TI-Flag selber wie 
gewünscht zu behandeln.)

tschuessle
B.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.