www.mikrocontroller.net

Forum: Compiler & IDEs Mega8 UART funktioniert nicht


Autor: Dominik (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!
Ich habe bisher meinen Mega8 immer mit Assembler programmiert. Jetzt 
habe ich ein Programm angefangen, dass mit Assembler einfach zu 
umständlich wird und bin deshalb auf C umgestiegen.

Mit Assembler hat das Senden über den UART problemlos geklappt, mit C 
funktioniert es komischerweise nicht. Es kommt nur sporadisch mal ein 
Zeichen, dass so aussieht wie ein hochgesetztes L. Es wird aber 
scheinbar permanent etwas gesendet, da die LEDs an TX und RX flackern. 
Da es mit Assembler klappt, ist die Hardware also schonmal in Ordnung.

Vielleicht ist es nur ein kleiner Fehler. Bitte helft mir.

Hier mein Code:

#define F_CPU 8000000
#define BAUD 9600

#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD)
#define LOW(x) ((x) & 0xFF)
#define HIGH(x) (((x) >> 8) & 0xFF)


#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu 
hoch!
#endif


#include <avr/io.h>
#include <stdlib.h>

void initUART()
{
  UCSRB |= (1<<TXEN);
  UBRRL = LOW(UBRR_VAL);
  UBRRH = HIGH(UBRR_VAL);
}

int uart_putc(unsigned char c)
{
  while (!(UCSRA & (1<<UDRE)));  /* warten bis Senden moeglich */
  UDR = c;                      /* sende Zeichen */
  return 0;
}

void uart_puts (char *s)
{
    while (*s)
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
        uart_putc(*s);
        s++;
    }
}

void main()
{
  char buffer[20];

  initUART();

  while(1)
  {
  //sprintf(buffer, "Hallo");
  //uart_puts(buffer);
  uart_putc('H');
  uart_putc('A');
  uart_putc('L');
  uart_putc('L');
  uart_putc('O');
  }
}

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dominik wrote:
> void initUART()
> {
>   UCSRB |= (1<<TXEN);
>   UBRRL = LOW(UBRR_VAL);
>   UBRRH = HIGH(UBRR_VAL);
> }

Wie war das mit dem temporären oberen Register?
/* entweder */
   UBRRH = HIGH(UBRR_VAL);
   UBRRL = LOW(UBRR_VAL);
/* oder */
   UBRR = UBRR_VAL

Autor: Dominik (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, danke. Das war schonmal der erste dumme Fehler. Da muss aber noch 
was sein, denn es funktioniert immer noch nicht.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das "Übliche" hast du abgecheckt?

Richtige BAUD-Rate am Empfänger eingestellt?
Läuft der Mega8 wirklich mit 8MHz?

Autor: Dominik (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, das übliche habe ich gecheckt. Wie gesagt, wenn ich eins von meinen 
Assemblerprogrammen lade, funktioniert es direkt.

Autor: Dominik (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Statt Hyperterminal benutze ich jetzt TeraTerm. In TeraTerm werden jetzt 
sehr schnell hintereinander diese besagten "L" ausgegeben. Woran liegt 
das denn bloß???

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sven Pauli wrote:
> Wie war das mit dem temporären oberen Register?
Gibt's beim USART Baud Rate Register aber nicht (macht auch nur dort 
Sinn, wo es wirklich wichtig ist, dass die Werte für Low- und High-Byte 
synchronisiert werden)

> /* entweder */
>    UBRRH = HIGH(UBRR_VAL);
>    UBRRL = LOW(UBRR_VAL);
Siehe oben: Reihenfolge spielt in diesem Fall keine Rolle

> /* oder */
>    UBRR = UBRR_VAL
Ein 16-Bit-Register gibt es in diesem Falle nicht und kann es auch nicht 
geben, u.a. weil UBRRL und UBRRH beim Mega8 im Speicher nicht 
hintereinander liegen.

Autor: Dominik (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kurzes Update:
Es muss irgendwo in der Baudraten-Berechnung der Wurm drin sein. Ich 
habe jetzt ins Baudratenregister direkt den Wert 52 geschrieben (aus der 
Tabelle im Datenblatt entnommen).

Jetzt kommt aber nur nach mehrmaligem Reset-Drücken das gewünschte 
Zeichen!!!

Woran liegt das nun wieder? Ich verzweifele gleich....

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> #define BAUD 9600
Das müsste vermutlich ein 9600L oder 9600UL sein, F_CPU sollte auch ein 
8000000UL verpasst bekommen, sonst kann es Problemchen bei der 
Berechnung geben...

Autor: Dominik (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Johannes. Trotzdem ist das Problem noch da: Nur nach mehrmaligem 
Reset kommen die richtigen Zeichen an. Wenn man dann nochmal Reset 
drückt kommen meistens wieder die falschen.

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mal nen auszug vin meinem mega8, da funktionierts:
[c]
#include <inttypes.h>
#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>
#include "lcd_mega8.h"

#ifndef F_CPU
#define F_CPU 8000000
#endif

#define BAUD 9600UL //Baudrate
#define UBRR_BAUD   ((F_CPU/(16UL*BAUD))-1)

void wait (uint16_t zeit) //zeit: wartezeit in ms (0 bis 65536)
{
   uint16_t i;
   for(i=0;i<zeit;i++) _delay_ms(1); //da für _delay_ms max 
Takt-abhängige Werte erlaubt
}

// 
uart#################################################################### 
##
void uart_init(void)
{
  UCSRB = (1<<RXEN)|(1<<TXEN);      // UART TX und RX einschalten
    UCSRC |= ( 1 << URSEL )|( 3<<UCSZ0 );  // Asynchron 8N1
  //nur für 19200 Baud bei 16MHz für Mega32
    //UBRRH  = 0;                             // Highbyte ist 0
    //UBRRL  = 51;                            // Lowbyte ist 51

  //falls anderer Mega bzw andere Frequenz
  UBRRH = (uint8_t) (UBRR_BAUD>>8);
    UBRRL = (uint8_t) (UBRR_BAUD & 0x0ff);
}

void uart_data(unsigned char c)
{
    while (!(UCSRA & (1<<UDRE))) {}  // warten bis Senden möglich
    UDR = c;                         // Zeichen senden
}

void uart_string (char *s)
{
    while (*s)
    {   uart_data(*s);
        s++;
    }
}
//###################################################################### 
#####

int main(void)
{
   uint16_t adcval=0;
   char s[17];

   uart_init();
   uart_string( "Messung gestartet:" );
   uart_string( "\n\r" );


while(1)
{

}

  return 0;

}

[\c]

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.