Forum: Mikrocontroller und Digitale Elektronik Terminal Window error


von Hasibeder Thomas (Gast)


Angehängte Dateien:

Lesenswert?

Ich versuche gerade das Terminal zum laufen zu bringen.

Leider kommt immer der Fehler auf dem Bild im Anhang.

Hat den schon jemand bekommen?
1
void USART_init (void)
2
{
3
// USART initialization
4
// Communication Parameters: 8 Data, 1 Stop, No Parity
5
// USART Receiver: On
6
// USART Transmitter: On
7
// USART Mode: Asynchronous
8
// USART Baud rate: 9600
9
UCSRA=0x00;
10
UCSRB=0x18;
11
UCSRC=0x86;
12
UBRRH=0x00;
13
UBRRL=0x33;//67
14
}
mit printf() will ich dann einige Daten ausgeben zur Kontrolle.

Danke

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Hasibeder Thomas schrieb:
> Ich versuche gerade das Terminal zum laufen zu bringen.
>
> Leider kommt immer der Fehler auf dem Bild im Anhang.

Ganz ehrlich?

Die Qualität der Tools im Atmel-Studio scheint seit der Umstellung auf 
Visual Studio als Basis nicht besonders zugenommen zu haben. Eher im 
Gegenteil.

Pfeif auf das mitgelieferte Terminal-Programm für den PC und nimm ein 
externes Terminal-Programm, zb HTerm, statt dessen her. Die 
funktionieren seit Jahren zuverlässig.

> Hat den schon jemand bekommen?
>
1
> void USART_init (void)
2
> {
3
> // USART initialization
4
> // Communication Parameters: 8 Data, 1 Stop, No Parity
5
> // USART Receiver: On
6
> // USART Transmitter: On
7
> // USART Mode: Asynchronous
8
> // USART Baud rate: 9600
9
> UCSRA=0x00;
10
> UCSRB=0x18;
11
> UCSRC=0x86;
12
> UBRRH=0x00;
13
> UBRRL=0x33;//67
14
> }
15
>

Der AVR-Teil hat nichts damit zu tun.
Der Fehler wird von einem Programm auf dem PC verursacht.

> mit printf() will ich dann einige Daten ausgeben zur Kontrolle.

printf bringt dich nicht weiter. Du wirst dir einen Ersatz bauen müssen, 
der auf der Kette uart_putc, uart_puts aufbaut. Du kannst dann zb 
sprintf benutzen, um die Ausgabe in einen String zu packen, und den 
String dann mittels uart_puts über die UART ausgeben. Aber eigentlich 
braucht man die Fähigkeiten der xprintf-Familie eher selten. Meistens 
erzeugt man sich den String zb mittels itoa und Konsorten.

von Cyblord -. (cyblord)


Lesenswert?

Karl Heinz schrieb:

> printf bringt dich nicht weiter. Du wirst dir einen Ersatz bauen müssen,
> der auf der Kette uart_putc, uart_puts aufbaut.

Naja wenn man den stdout auf die uart_putc umleitet, kann man printf 
benutzen. 3 Zeilen Code + die uart_putc Funktion. Ist in der avr-libc 
Doku beschrieben. Somit kann er schon einfach printf ohne einen Ersatz 
nutzen.
1
  #include <stdio.h>
2
3
    static int uart_putchar(char c, FILE *stream);
4
5
    static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL,
6
                                             _FDEV_SETUP_WRITE);
7
8
    static int
9
    uart_putchar(char c, FILE *stream)
10
    {
11
12
      if (c == '\n')
13
        uart_putchar('\r', stream);
14
      loop_until_bit_is_set(UCSRA, UDRE);
15
      UDR = c;
16
      return 0;
17
    }
18
19
    int
20
    main(void)
21
    {
22
      init_uart();
23
      stdout = &mystdout;
24
      printf("Hello, world!\n");
25
26
      return 0;
27
    }

: Bearbeitet durch User
von Hasibeder Thomas (Gast)


Lesenswert?

Hey,

Der Code funktioniert zwar und ich kann etwas ausgeben aber es gibt 
keinen Zusammenhang zu dem was ich ausgeben will.
Und leider gibt er einen String sowieso nicht aus.

von Karl H. (kbuchegg)


Lesenswert?

Wahrscheinlich wieder das 'übliche Problem'
1
void USART_init (void)
2
{
3
// USART initialization
4
// Communication Parameters: 8 Data, 1 Stop, No Parity
5
// USART Receiver: On
6
// USART Transmitter: On
7
// USART Mode: Asynchronous
8
// USART Baud rate: 9600
9
UCSRA=0x00;
10
UCSRB=0x18;
11
UCSRC=0x86;
12
UBRRH=0x00;
13
UBRRL=0x33;//67
14
}

wo kommen die 67 her?
und warum schreibst du 0x33, wenn du 67 meinst. Schreib doch gleich 67, 
dann brauchst du keinen Kommentar. Aber eigentlich ist auch das 
unsinnig, denn den Zahlenwert kann der Compiler wunderbar aus der 
Cpu-Taktfrequenz und der gewünschten Baudrate auch selber ausrechnen.

So etwas
1
UCSRC=0x86;
ist sowieso ein Sargnagel. Die Bits haben Namen! Diese Namen benutzt man 
auch, damit man im Source Code sehen kann, welche Bits gesetzt sind (wie 
die heissen). Denn mit den Bitnamen hast du im Gehirn eine Bedeutung 
verknüpft. Damit, dass das Bit 4 gesetzt ist, hab ich überhaupt nichts 
verknüpft. Das muss ich erst mal im Datenblatt nachsehen, was das 
überhaupt für ein Bit ist, bis es dann endlich bei mir klingelt, dass 
hier (beispielweise) der Transmitter Empty Interrupt freigeschaltet 
wird.

Fazit: Es ist nicht schlau, generell einfach überall Hex-Zahlen zu 
benutzen. Die Art und Weise wie Zahlen angeschrieben werden, sei es als 
Dezimalzahl, sei es als Hex-Zahl, sei es als ASCII-Character, oder sei 
es auch in Form der Bitnamen-Verschiebe Schreibweise, richtet sich nach 
dem Einsatzzweck und welche Form dort am klarsten die Absicht ausdrückt.

Technisch gesehen, machen
1
  c = 'A';
2
  c = 65;
3
  c = 0x41;
4
  c = ( 1 << 6 ) | ( 1 << 5 ) | ( 1 << 2 ) | ( 1 << 1 );
5
  c = 0b01100101;
alles dasselbe: in c wird das Bitmuster 01100101 abgelegt. Und trotzdem 
ist je nachdem, wofür dieses c verwendet wird, die eine oder andere Form 
die klarste, weil sie die beasichtigte Wirkung am besten ausdrückt.

Zurück zum Problem.
Wenn dein AVR in der Zeichen-Ausgabe ein 'x' ausgibt, am PC aber alles 
mögliche andere ankommt, dann stimmt die Baudrate nicht.

: Bearbeitet durch User
von Hasibeder Thomas (Gast)


Lesenswert?

Hallo,

Habe das UART mit dem Code Wizard generiert und kopiert.
Habe auch Code wo ich mit Namen arbeite.

Nachdem ich die BOUD Rate auf 19200 gedreht habe ging es!

Danke

von Karl H. (kbuchegg)


Lesenswert?

Hasibeder Thomas schrieb:

> Nachdem ich die BOUD Rate auf 19200 gedreht habe ging es!

Die Baudrate muss mit der übereinstimmen, die du im Terminal eingestellt 
hast.

Wenn du um einen Faktor 2 daneben liegst, dann ist möglicherweise hier 
irgendwo das U2X Bit gesetzt worden
1
UCSRA=0x00;
2
UCSRB=0x18;
3
UCSRC=0x86;
4
UBRRH=0x00;
5
UBRRL=0x33;//67
allerdings drösle ich mir die Bits jetzt nicht aus. Denn um die 4 oder 5 
Bits herauszusuchen und zu setzen, die tatsächlich benötigt werden, 
benutze ich keinen Wizard, noch dazu wenn der zu dämlich ist, mir hier
1
UBRRH=0x00;
2
UBRRL=0x33;//67
eine ordentliche Berechnung basierend auf den F_CPU und BAUD Konstanten 
einzusetzen, so dass ich bei einer Veränderung der Baudrate nur bei
1
#define BAUD 9600
die andere gewünschte Baudrate eintragen muss und den im Register 
einzutragenden Zahlenwert rechnet mir dann der Compiler aus.

Es könnte allerdings auch sein, dass du deinem Wizzard eine falsche 
CPU-Taktfrequenz gegeben hast und der dann darauf basierend falsche 
WErte ausgerechnet hat. Wer weiß das schon. Wenn im Code stehen würde
1
#define F_CPU 8000000UL
2
...
dann könnte man das kontrollieren.
So aber kann man sich brausen gehen, weil niemand nachvollziehen kann, 
auf der Basis welcher Daten die 0x33 entstanden sind.

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.