Forum: Mikrocontroller und Digitale Elektronik Zeichen auf serielle schnittstelle ausgeben


von micro (Gast)


Lesenswert?

hey leute könnt ihr mir sagen wie man ein Zeichen in ASCII Darstellung 
auf eine serielle Schnittstelle ausgeben kann??
Der Prozessor ist  mit 8MHz getaktet die Baudrate =9600Baud

Ich benutzt AVR-Studio GCC, ATMega128

von Johannes M. (johnny-m)


Lesenswert?

Eine serielle Schnittstelle überträgt eine Reihe von Bits. Was diese 
Bits letztendlich darstellen (ASCII-Zeichen, Zahlenwerte, ...) hängt 
ausschließlich davon ab, wie die empfangende Gegenstelle die Bits 
interpretiert. Wenn Du dem Empfänger sagst, er soll 8-Bit-Frames 
empfangen und diese jeweils als ASCII-Zeichen interpretieren, dann tut 
er das i.d.R. auch...

von Stefan B. (stefan) Benutzerseite


Lesenswert?


von micro (Gast)


Lesenswert?

ich les es mir die ganze zeit durch und recherchiert habe ich auch nur 
ich sag ja bin blutiger anfänger
und ich versteh da nur bahnhof

von Johannes M. (johnny-m)


Lesenswert?

Was ein ASCII-Zeichen ist, weißt Du aber? Wenn nicht, dann schau bitte 
mal bei Wikipedia nach!

von micro (Gast)


Lesenswert?

ja das weiss ich schon

von Johannes M. (johnny-m)


Lesenswert?

micro wrote:
> ja das weiss ich schon
Und wo liegt dann bitte genau das Problem? "Ich krieg es nicht hin" oder 
"ich versteh das nicht" ist keine ausreichende Beschreibung. Man müsste 
schon wissen, was Du schon probiert hast und wo es präzise hakt.

von micro (Gast)


Lesenswert?

Mein Probelm ist folgendes....
Ich weiss einfach nich wo ich anfangen soll
ich deklarieren meine Ports
bsp PortA als eingang und PortB als ausgang

so und dann? Ich hab einfach keine ahnung wie ich weiter machen soll !

ich soll beachten das die schnittstelle nich beliebig schnell ist

daraus schliess ich doch das ich irgendwie abfragen muss ob das 
Statusregister bzw die schnittstelle bereit ist das nächste zeichen 
abzufragen?! aber wie?!

von micro (Gast)


Lesenswert?

hab jetzt mal ein bisschen im tutorial gesucht
und zu dem ergebniss gekommen

#ifndef F_CPU
#define F_CPU 8000000UL    // Systemtakt in Hz - Definition als unsigned 
long beachten
#endif

#define BAUD 9600UL          // Baudrate

#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate


int main(void)
{
    UCR |= (1<<TXEN);
    UBRR = UBRR_VAL;

}

while (!(USR & (1<<UDRE)))  /* warten bis Senden moeglich 
*/
    {
    }

UDR = 'x';                  /* schreibt das Zeichen x auf die 
Schnittstelle */

von Das Kleinkind (Gast)


Lesenswert?

Ja genau so funktioniert es.
Noch Fragen?

von micro (Gast)


Lesenswert?

ja hab noch ne frage
und zwar wenn ich das im AVR-Studio mache und kann ich das da irgenwie 
im simulator testen?
Ausserdem lässt es sich nich compilieren also müssen fehler da sein

von micro (Gast)


Lesenswert?

habe es nochmal erweitert damit er was auf die schnittstelle "schreibt"


#ifndef F_CPU
#define F_CPU 8000000UL    // Systemtakt in Hz - Definition als unsigned 
long beachten
#endif

#define BAUD 9600UL          // Baudrate

#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate


int main(void)
{
    UCR |= (1<<TXEN);
    UBRR = UBRR_VAL;

}

while (!(USR & (1<<UDRE)))  /* warten bis Senden moeglich 
*/
    {
    }

UDR = 'x';                  /* schreibt das Zeichen x auf die 
Schnittstelle */


int uart_putc(unsigned char c)
{
    while(!(USR & (1 << UDRE)))  /* warte, bis UDR bereit */
    {
    }

    UDR = c;                     /* sende Zeichen */
    return 0;
}

von micro (Gast)


Lesenswert?

trotzdem wird es nich kompiliert

von Johannes M. (johnny-m)


Lesenswert?

micro wrote:
> Ausserdem lässt es sich nich compilieren also müssen fehler da sein
Grundregel Nr. 1: Vollständiges Programm posten, damit man das 
nachvollziehen kann! In Deinem Schnipsel fehlen einige Dinge 
(Headerdateien...).

Grundregel Nr. 2: Formatierungsmöglichkeiten der Forensoftware nutzen! 
Dann ist der Code viel leichter lesbar.

von micro (Gast)


Lesenswert?

haha johannes ich nehm an das war nich deine absicht aber meine frage 
hast du beantwortet  ich dachte es wär schon das fertige Programm =/
1
#ifndef F_CPU
2
#define F_CPU 8000000UL    // Systemtakt in Hz - Definition als unsigned long beachten 
3
#endif
4
5
#define BAUD 9600UL          // Baudrate
6
7
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
8
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
9
10
11
int main(void)
12
{
13
    UCR |= (1<<TXEN);
14
    UBRR = UBRR_VAL;
15
    
16
}
17
18
while (!(USR & (1<<UDRE)))  /* warten bis Senden moeglich                   */
19
    {
20
    }
21
22
UDR = 'x';                  /* schreibt das Zeichen x auf die Schnittstelle */
23
24
25
int uart_putc(unsigned char c)
26
{
27
    while(!(USR & (1 << UDRE)))  /* warte, bis UDR bereit */
28
    {
29
    }
30
 
31
    UDR = c;                     /* sende Zeichen */
32
    return 0;
33
}

von Johannes M. (johnny-m)


Lesenswert?

micro wrote:
> haha johannes ich nehm an das war nich deine absicht aber meine frage
> hast du beantwortet  ich dachte es wär schon das fertige Programm =/
Wenn Du das tatsächlich gedacht hast, dann solltest Du das 
AVR-GCC-Tutorial noch mal etwas gründlicher lesen! Da steht nämlich 
einiges drin, was so ein Programm noch alles braucht.

von micro (Gast)


Lesenswert?

kannst du mir nochmal sagen was in meinem fall in die header datei rein 
muss?

von Johannes M. (johnny-m)


Lesenswert?

micro wrote:
> kannst du mir nochmal sagen was in meinem fall in die header datei rein
> muss?
Bitte informiere Dich, was es mit Headerdateien auf sich hat! Da 
schreibst Du zunächst mal gar nichts selber rein. Die Headerdateien, die 
Du brauchst, sind fertig und müssen nur noch in Dein Programm 
eingebunden werden. Wie das geht, steht alles im Tutorial.

von micro (Gast)


Lesenswert?

einfach mit der standart header-datei oder?
1
#include<avr/io.h>
2
3
#ifndef F_CPU
4
#define F_CPU 8000000UL    // Systemtakt in Hz - Definition als unsigned long beachten 
5
#endif
6
7
#define BAUD 9600UL          // Baudrate
8
9
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
10
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
11
12
13
int main(void)
14
{
15
    UCR |= (1<<TXEN);
16
    UBRR = UBRR_VAL;
17
    
18
}
19
20
while (!(USR & (1<<UDRE)))  /* warten bis Senden moeglich                   */
21
    {
22
    }
23
24
UDR = 'x';                  /* schreibt das Zeichen x auf die Schnittstelle */
25
26
27
int uart_putc(unsigned char c)
28
{
29
    while(!(USR & (1 << UDRE)))  /* warte, bis UDR bereit */
30
    {
31
    }
32
 
33
    UDR = c;                     /* sende Zeichen */
34
    return 0;
35
}

von micro (Gast)


Lesenswert?

Ich hab nochmal kurz ne frage zu dieser Zeile
1
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)

und zwar hab ich diese Zeile aus dem Tutorial
Aber ich hab gedacht das UBRR durch (Taktfrequenz/(Baundrate*16)-1 
gebildet wird??

von micro (Gast)


Lesenswert?

also nochmal das was ich bisher habe funktioniert noch nich wirklich
kann mir jemand sagen wieso??
was noch fehlt?
1
#include<avr/io.h>
2
#ifndef F_CPU
3
#define F_CPU 8000000UL    // Systemtakt in Hz 
4
#endif
5
#define BAUD 9600UL          // Baudrate
6
7
8
9
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden ((Taktfrequenz/Baundrate*16)-1)
10
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
11
12
13
14
15
int main(void)
16
{
17
    UCR |= (1<<TXEN);
18
    UBRR = UBRR_VAL;
19
    
20
}
21
22
while (!(USR & (1<<UDRE)))        /* warten bis Senden moeglich */
23
    {    }
24
25
UDR = 'x';                  /* schreibt das Zeichen x auf die Schnittstelle */
26
     
27
28
             
29
30
int uart_putc(unsigned char c)
31
{
32
    while(!(USR & (1 << UDRE)))     /* warte, bis UDR bereit */
33
    {    }
34
 
35
36
    UDR = c;                       /* sende Zeichen */
37
    return 0;
38
}
39
40
void uart_puts (char *c)        /* Zeichen wird in uart_putc implementiert*/
41
{
42
    while (*c)
43
    { 
44
        uart_putc(*c);
45
        c++;
46
    }
47
}

von Achja (Gast)


Lesenswert?

>kann mir jemand sagen wieso??
>was noch fehlt?

Also ich nehme an, das das fehlt, dass dafür sorgen würde, das es 
wirklich funktioniert.

Falls das "nicht wirklich funktionieren" im Detail beschrieben wird, 
liesse sich vielleicht auch das, was fehlt im Detail beschreiben.

Im Moment sollte sich Dein Programm nicht kompilieren lassen.
Ich empfehle das oben angegebene Tutorial zu C.

Kleiner Tip: Welche Anweisungen oder Ausdrücke sind ausserhalb einer 
Funktion zulässig?

von Christoph Müller (Gast)


Lesenswert?

> kann mir jemand sagen wieso??
ja
> was noch fehlt?
Grundlegende C Kenntnisse

Du hast nichtmal eine Endlosschleife, dein "Programm" initialisiert den 
uart und beendet sich dann (schau mal in deine main-methode), 
desweiteren hängt da Code in der Luft.
Lies dir deine Compilerfehler durch und versuch sie zu verstehen, falls 
das nicht klappt poste sie hier ABER NICHT NOCHMAL DENSELBEN CODE!

von Achja (Gast)


Lesenswert?

>Ich hab nochmal kurz ne frage zu dieser Zeile
1
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)

>und zwar hab ich diese Zeile aus dem Tutorial
>Aber ich hab gedacht das UBRR durch (Taktfrequenz/(Baundrate*16)-1
>gebildet wird??

Im übrigen hilft es Kommentare zu lesen oder Codezeilen wenigsten 
vollständig zu kopieren.
1
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden

Dem cleveren Leser ergibt sich dann zumindest ein Anhaltspunkt. In 
diesem Fall ein Runder .

von micro (Gast)


Lesenswert?

@ christoph

ja da stimm ich dir zu das grundlegende Kenntnisse fehlen ....
ich muss auch ehrlich sagen das unser prof ein bisschen viel erwartet 
wenn man beachtet das wir uns noch nie mit c beschäftigt haben?!

von micro (Gast)


Lesenswert?

1
../LABOR2.c:19: error: 'UCR' undeclared (first use in this function)
2
../LABOR2.c:19: error: (Each undeclared identifier is reported only once
3
../LABOR2.c:19: error: for each function it appears in.)
4
../LABOR2.c:20: error: 'UBRR' undeclared (first use in this function)
5
../LABOR2.c:24: error: expected identifier or '(' before 'while'
6
../LABOR2.c:31: error: expected identifier or '(' before 'while'

von micro (Gast)


Lesenswert?

ich habe jetzt mal die endlosschleife eingebaut
stimmt die so
1
while(1)
2
{
3
4
int uart_putc(unsigned char c)
5
{
6
    while(!(USR & (1 << UDRE)))     /* warte, bis UDR bereit */
7
    {    }
8
 
9
10
    UDR = c;                       /* sende Zeichen */
11
    return 0;
12
}
13
14
void uart_puts (char *c)        /* Zeichen wird in uart_putc implementiert*/
15
{
16
    while (*c)
17
    { 
18
        uart_putc(*c);
19
        c++;
20
    }
21
}
22
23
}

von Johannes M. (johnny-m)


Lesenswert?

micro wrote:
> @ christoph
>
> ja da stimm ich dir zu das grundlegende Kenntnisse fehlen ....
> ich muss auch ehrlich sagen das unser prof ein bisschen viel erwartet
> wenn man beachtet das wir uns noch nie mit c beschäftigt haben?!
Ach, für die Uni ist das? Nun, auch ohne das näher zu erörtern kann man 
wohl sagen, dass Du allein durch versuchsweises Zusammenkopieren von 
Codeschnipseln aus Tutorien nicht viel weiter kommen wirst. Bitte 
besorge Dir (wenn Dein Prof keine Literatur empfohlen hat) in der 
Bibliothek ein Buch, das die C-Grundlagen ordentlich behandelt (z.B. den 
Kernighan & Ritchie) und eigne Dir die absoluten Basics an. Ohne die 
wirst Du auch mit den AVR-Tutorien nicht weit kommen, da die praktisch 
durchweg bereits allgemeine C-Kenntnisse voraussetzen.

von Johannes M. (johnny-m)


Lesenswert?

Hast Du im Makefile bzw. AVRStudio unter Configuration Options auch den 
richtigen Ziel-Controller ausgewählt? Ohne das kennt der Compiler 
nämlich die richtigen Registernamen nicht, was dann zu den 
Fehlermeldungen führt.

EDIT:
Ich sehe grad, dass Du ja angeblich einen ATMega128 benutzt. Dann musst 
Du aber auch die entsprechenden Registernamen benutzen! Die Beispiele 
aus den Tutorien beziehen sich i.d.R. entweder auf einen ATMega8 oder 
sind allgemein gehalten. Beim ATMega128 gibt es keine Register "UCR" und 
"UBRR". Allein schon deshalb nicht, weil der Mega128 zwei UARTs hat, 
die mit 0 und 1 nummeriert sind. Bitte Datenblatt beachten!

von micro (Gast)


Lesenswert?

ja das Problem ist nur wie ich schon gesagt habe
das wir ins kalte wasser geschmissen wurden ..... und gestern die 
aufgaben bekommen haben und wir es bis morgen machen müssen und dem prof 
is das völlig egal ob wir c-kenntnisse haben oder nicht fakt ist wenn 
wirs haben bestehn wir unser testat und wenn nich dann nicht .

ich probier das mal mit den configurations options

von Johannes M. (johnny-m)


Lesenswert?

micro wrote:
> ich probier das mal mit den configurations options
Beachte auch die Ergänzung in meinem letzten Post. Das wird vermutlich 
eher das Problem sein!

von micro (Gast)


Lesenswert?

ahhhh klar
aber das heisst ja auch wenn ich einfach mit dem ATmega8 simuliere 
müsste es gehn oder??

von Christoph Müller (Gast)


Lesenswert?

>aber das heisst ja auch wenn ich einfach mit dem ATmega8 simuliere
>müsste es gehn oder??

Nein, weil du wieder nur stupide rumkopiert hast und zwar diesmal 
Funktionen in eine Schleife. Die Funktionen haben ausserhalb der 
main-Funktion und die Endlosschleife innerhalb zu stehen.
Hänge in Zukunft dein C-File als Anhang an deinen Post und zwar 
komplett!

von Michael Z. (incunabulum)


Lesenswert?

Bist du eigentlich dieser hier?

Beitrag "Ausgaberoutinen"

Zumindest der Inhalt wie auch die Formulierungen sind sehr ähnlich.... 
ansonsten kann ich meinen Vorpostern nur recht geben. Wer an der Uni was 
erreichen will, der muss sich auch mal mit Grundlagen wie C 
beschäftigen. Damit solltest du zumindest schon einmal den Compiler 
überreden können

mz

von Dieter E. (netdieter) Benutzerseite


Lesenswert?

micro wrote:
> ja das Problem ist nur wie ich schon gesagt habe
> das wir ins kalte wasser geschmissen wurden ..... und gestern die
> aufgaben bekommen haben und wir es bis morgen machen müssen und dem prof
> is das völlig egal ob wir c-kenntnisse haben oder nicht fakt ist wenn
> wirs haben bestehn wir unser testat und wenn nich dann nicht .

Darf ich mal fragen was das für ein Studiengang ist? Und an welcher 
Uni/FH?
>
> ich probier das mal mit den configurations options

Das ist schon mal der richtige Weg.
Ich rate Dir dringent Dir das Datenblatf für Deinen ATMega128 zu 
besorgen und schau Dir dann mal die Register an.

Viel Glück,
Dieter

von Das Kleinkind (Gast)


Lesenswert?

Das hier dürfte er wohl auch sein.
Beitrag "CHAR auf einem Port ausgeben"

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.