Forum: Mikrocontroller und Digitale Elektronik UART, ATmega16, Eval-Board 2.0 zum PC .. erfolglos


von Markus B. (krabbe)


Angehängte Dateien:

Lesenswert?

Hallo!

Ich habe ein Evaluation Board 2.0 bei Pollin angeschafft und mit einem 
ATmega16 bestückt. Danach (unter zuhilfnahme des Datenblatte und des 
UART Tutorials) eine kleine Initialisierungsprozedur für das UART 
geschrieben. Das Hauptprogramm solln nur zwei Dinge erledigen, immmer 
wieder auf UDRE warten und dann das Zeichen 'x' ins UDR-Register 
schreiben.

Beim Debuggen wird allerdings nur zweimal ins UDR geschrieben, danach 
wird endlos auf UDRE gewartet. Wenn ich das Programm auf den Controller 
übertrage wird trotzdem kein einziges Byte übertragen.

Die Übertragung über den MAX 232 von TI ist getestet, indem der PC mit 
dem Eval-Board verbunden wurde, dann die Masse, RxD, TxD von der 40-pol. 
Stiftleiste bzw. von Jumper 1 + 2 des Eval-Boards auf eine 
Wandlerplatine für RS232-Pegel (ebenfalls Pollin) verbuden wurden. 
Anschliessend konnte man mit Bray's Terminal Daten vom PC übers 
Eval-Board über die Wandlerplatine auf eine zweiten PC an dessen 
Bray-Terminal verschicken.

Statt des 8 MHZ Quarzes habe ich einen mit 7372800 Hz ins Eval-Board 
eingebaut und die Fuse über das AVR Studio mit AVRProg auf "Ext XTAL, 
medium frequency" umgestellt. Da auf dem E-Board zwei LED's sind habe 
ich zunächst ein kleines Blinky-Programm getippt und laufen lassen. War 
kein Problem.

Jetzt möchte ich die UART benutzen und bin, trotz Zahlreich gelesener 
Threads und Code-Examples, schon an der Übertragung eines einzelnen 
Charcters gescheitert.

Die Datei mit meinem Quellcode (etwas ausführlicher als nötig, ...) ist 
im Anhang. Kann jemand den Fehler erkennen und etwas dazu sagen?

Gruß
Markus

von Markus B. (krabbe)


Angehängte Dateien:

Lesenswert?

Hi@All!

Es gab einige Downloads, aber keine Antwort, kann daraus schliessen das 
noch jemand ratlos ist?

Selbst habe ich inzwischen den Quellcode leicht geändert, und an einen 
ATtiny2313 angepasst, der passt ebenfalls ins Evaluation-Board.
Da der ATtiny auch nicht sendet und die Simulation bei dem auch nicht 
geht, bleibt mir wohl nur noch mit dem AVR Studio von SP2 nach SP4 und 
beim WinAVR von 20060421 ebenalls auf eine höhere Version zu wechseln.
Ich hab' an einigen Stellen allerdings auch schlechtes vom SP4 gehört, 
das gleiche gilt auch für den aktuellsten WinAVR 20070101.

Deshalb meine Frage:
Konnte jemand das Problem auf einem der Controller Typen bei sich 
nachvollziehen, oder des Code mit erfolgt ausführen?
Vielleicht hilft es mir weiter, wenn er/sie mit die Versionsnummer 
seines AVR Studios und des WinAVR schreibt.

Danke!
Markus

von Karl H. (kbuchegg)


Lesenswert?

Probier mal dieses Programm auf dem Mega16 aus:
1
#ifndef F_CPU
2
#define F_CPU 7372800UL
3
#endif
4
5
#include <avr/io.h>
6
7
8
void InitUart( unsigned int Baud )
9
{
10
  UCSRB |= (1<<TXEN) | (1<<RXEN);
11
  UCSRC |= (1<<URSEL)| (1<<USBS) | (3<<UCSZ0);
12
13
  Baud = F_CPU / (Baud * 16L) - 1;
14
15
  UBRRH = (unsigned char)( Baud >> 8 );
16
  UBRRL = (unsigned char)Baud;
17
}
18
19
void uart_putc( const char c )
20
{
21
  while( !( UCSRA & (1<<UDRE) ) )
22
    ;
23
  UDR = c;
24
}
25
26
int main()
27
{
28
  InitUart( 4800U );
29
30
  while( 1 ) {
31
    uart_putc( 'X' );
32
  }
33
}

Wenns damit nicht klappt, hast du ein Hardware-Problem.
In dem Fall tippe ich mal darauf, dass das RS232 Kabel
nicht richtig gekreuzt ist.

von Stefan (Gast)


Lesenswert?

@ Markus C.

The Data Register Empty (UDRE) Flag indicates whether the transmit 
buffer is ready to receive new data. This bit is set when the transmit 
buffer is empty, and cleared when the transmit buffer contains data to 
be transmitted that has not yet been moved into the Shift Register. For 
compatibility with future devices, always write this bit to zero when 
writing the UCSRA Register. (lt. Atmega16(L) Datenblatt)

Mach das letztere mal in deiner uart-init-Routine, insbesondere weil der 
Initialwert 1 ist (lt. AVR-GCC-Tutorial).

von Markus B. (krabbe)


Lesenswert?

Danke für die Unterstützung!

Da Ihr euch für mein Problem(chen) interssiert habt, gilt das vermutlich 
auch für die Lösung. Es gibt eine gute Nachricht, und eine Lösung, die 
ich so nicht erwartet hatte.

Ein Hardwareproblem gibt's gottlob nicht, der Controller ist jetzt auf 
Sendung.

Nachdem KHB's Code erfolgreich ausgeführt wurde habe ich mich noch auf 
Fehlersuche begeben ...

Wenn ich in der Initialisierungsroutine folgendes

  UCSRC |= (1<<URSEL) | (0<<USBS);                // stopBit
  UCSRC |= (1<<URSEL) | (1<<UCSZ0);               // characterSize
  UCSRC |= (1<<URSEL) | (1<<UCSZ1);               // characterSize

durch

  UCSRC |= (1<<URSEL) | (0<<USBS) | (1<<UCSZ0) | (1<<UCSZ1);

ersetzte, dann funktioniert die UART - Das leuchtet mir im Augenblick 
nicht ein. Das (1<<URSEL) entscheidet dabei ob das zu schreibende Byte 
ins UBRRH oder in UCSRC geschrieben wird.

Was den Simulator im AVR Studio betrifft ... der bleibt bei beiden 
Varianten in der Sendeschleife hängen und wartet, nachdem er 2 Bytes ins 
UDR geschrieben hat endlos auf UDRE. Vermtulich nimmt er an, das sowohl 
das Schieberegister als auch UDR mit Daten belegt sind, die noch nicht 
gesendet wurden. Evtl. probiert ich morgen noch im Code etwas einzubauen 
um die Warteschleife zu unterbrechen ..  ein Delay und dann irgendwie 
das UDRE wieder auf "1" setzen, damit der Simulator annehmen kann das 
UDR ist seinen Inhalt ans Schieberegister losgeworden.

@Stefan
Habe das mal probiert, und in der Initialisierungsprozedur UCSRC = 0x00 
eingetragen ... ein paar Zeilen später, bei der initialisierung des 
UBRRH setzt der Simulator des AVR Studio UDRE-Bit eigenmächtig wieder 
auf "1"!?!? Die schreiben da ausserdem etwas von Kompatibilität zu 
kommenden Controllertypen ... . Lohnt sich bestimmt da mal im Hinterkopf 
zu speichern! Vorerst bleib ich beim ATmega16 :-))

Besten Dank!
Markus

von loenny (Gast)


Lesenswert?

Ist zwar für eine Atmega8. Aber deutlich kürzer als deins. Du musst die 
Bits nicht alle Null (z.b. UCSRB |= (0<<UCSZ2);) setzen. Glaub die sind 
von vornherein Null.

#include <avr/io.h>
#include <avr/iom8.h>
#ifndef F_CPU
#define F_CPU 3686400
#endif

int main(void)
{
  UCSRB |= ((1 << RXEN) | (1 << TXEN));
  UCSRC |= ((1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0));
  UBRRH  = 0;
        UBRRL  = 23;

  while (1)
  {
    UDR = 'x';
    while (!(UCSRA & (1<<UDRE)))
    {
    }
  }
  return (0);
}

von Markus B. (krabbe)


Lesenswert?

OK!

Die Länge des Code hat sich beim "Trail and Error" ergeben - War erstmal 
nicht entscheident, das Einkürzen kommt dann beim "Aufräumen".

Trotzdem Danke.


Hat jemand eine Erklärung dafür:

Wenn ich in der Initialisierungsroutine folgendes

  UCSRC |= (1<<URSEL) | (0<<USBS);                // stopBit
  UCSRC |= (1<<URSEL) | (1<<UCSZ0);               // characterSize
  UCSRC |= (1<<URSEL) | (1<<UCSZ1);               // characterSize

durch

  UCSRC |= (1<<URSEL) | (0<<USBS) | (1<<UCSZ0) | (1<<UCSZ1);

ersetzte funktioniert der Code - Bin immer noch der Ansicht das ist 
beides das Gleiche.

Gruß!

PS: Wo find' ich denn hier eine Beschreibung der Features 
(Syntaxhighlighting)?

von Stefan (Gast)


Lesenswert?

Von der Sprachsyntax her das gleiche.

Nur, weiss man, wie Atmel die Initialisierung im µC tatsächlich macht?

Du musst bedenken, dass du ein Hardwareregister (UCSRC) beschreibst und 
daraufhin eine dir/mir unbekannte "Auswertelogik" bestimmte Pfade in der 
Hardware entsprechend den Konfigurationsbits umbiegt.

Alle Bits auf einen Schlag setzen, wird (ohne Begründung) in den 
Beispielen in den Atmel Datenblättern auch gemacht.

von Markus B. (krabbe)


Lesenswert?

Das bringt mich auf folgenden Gedanken,

bei der etwas zu auführlichen Variante wir das UCSRC bei der Zuweisung 
eigentlich nur mit einer Bitmaske ODER-Verknüpft, denke das können die 
bei ATMEL. Vielleicht gibt es ein HW-Problem,  wenn man das dreimal 
hintereinander macht (Timing). Da in der Regel vermutlich alle die kurze 
Variante nehmen ... .

EGAL!

von Stefan (Gast)


Lesenswert?

Hört sich plausibel an.

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.