USART sendet falsch

OP #363414
Lesenswert?
• ▲
▼
Hallo zusammen,

Ich habe mir nun einmal das GCC-Tutorial durchgelesen und auch das
senden mit dem USART ausprobiert.
AVR: mega8515
Terminalprogramm: Br@y

Den Sendecode habe ich 1:1 aus dem Tutorial übernommen.
------------------------
#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>

#define CLOCK    8000000          //Clock 8MHz
#define BAUD    19200          //USART BAUD
#define UBRR_BAUD  ((CLOCK/(16*BAUD))-1)

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

int main(void) {

    DDRD   = 0xff;
  PORTD   |= (1 << PD7);
    UCSRB   |= (1<<TXEN);  // UART TX einschalten
  UCSRA   |= (1 << U2X);
    UCSRC   |= ( 1 << URSEL )|( 3<<UCSZ0 );  // Asynchron 8N1
    UBRRH  = (uint8_t) (UBRR_BAUD>>8);  // USART Baud
  UBRRL    = (uint8_t) UBRR_BAUD;

  uart_putc('A');
}
-----------------------

Mein Problem ist jetzt dass im Terminal zwar jedesmal wenn ich den AVR
resete was ankommt allerding immer 0x00, obwohl ich ja 'A' sende.
Bin noch Neuling in der Welt von C :)

Woran kann das liegen?

Gruß Julien
Gast #363419
Lesenswert?
• ▲
▼
Die Portinitialisierung in main() birgt eine Falle:

    DDRD   = 0xff;

Beim "DDRD = 0xff" schaltest Du alle Pins als Output, also geht auch
der TX-Pin (PD1) auf Low, da in PortD zu dieser Zeit nur Nullen stehen.
Diese Low-Flanke gelangt aber als Startbit zum PC und dessen UART
versucht nun, ein Zeichen zu samplen. Das kurz danach korrekt
abgesendete 'A' kann dadurch nicht korrekt empfangen werden.

Lösung:
Am besten den TX-Pin erstmal als Eingang lassen, d.h. bei der
DDR-Anweisung auf Null lassen. Sobald der Transmitter über das TXEN-Bit
aktiviert wird, setzt der Controller den Pin automatisch auf High und
als Ausgang. Also z.B.:

. . .
int main(void) {

    DDRD = 0xff - (1<<PD1);
    . . .


Oder: Zuerst PORTD setzen, dabei das TX-Bit (PD1) auf High setzen. Dann
erst im DDRD als Ausgang setzen. Dadurch bleibt der Pin die ganze Zeit
auf High. Also:

. . .
int main(void) {

    PORTD = (1 << PD7) | (1 << PD1) ;
    DDRD  = 0xff;
    . . .


Während Reset sind die Controller-Pins übrigens hochohmig und werden
vom MAX232 automatisch als High erkannt (über interne Pullups im
MAX232).

MfG Olaf
OP #363421
Lesenswert?
• ▲
▼
Hab gerade gesehen dass U2X = 1
Dann stimmt natürlich die Berechnung von UBRR nicht.

Aber egal was ich nehme, U2X = 0 mit entsprechender Berechnungsformel
oder obengenanntes. Nix geht-> außer der netten NULL.
Gibt es irgendwelche Vorgaben, wie mann übertragen muss damit der PC
was erkennt?
OP #363422
Lesenswert?
• ▲
▼
Naja also irgendwie verzweifel ich langsam an diesem USART!

Wenn schon das senden nicht funktioniert dann wollte ich mal sehen ob
er wenigstens was vom PC empfangen kann. Aber ebenfalls vergeblich :(

Ich habe jetzt einfach mal meinen Source inden Anhang gepackt.
Es wäre sehr hilfreich wenn sich jemand erbarmen könnte unter
Zuhilfenahme dieses Source(enthält eine USART lib)einen kleinen Code zu
schreiben der folgendes prüft.

- Zeichen(BYTE) an den PC senden (kann dann ja übers terminalprogramm
ekannt werden)
- Zeichen(BYTE) an den µC senden und dieses dann an PORTB über LEDs
ausgeben.

Vielen Dank im Vorraus.

Aber wenigstens gibt es Lichtblicke für mich als Anfänger in der Welt
der Hochsprache.
Ansteuerung von Ports (LEDs Taster) sowie einer PWM funktionieren sehr
gut!

Gruß Julien
Angehängte Dateien:
Gast #363425
Lesenswert?
• ▲
▼
Auf die schnelle sieht es soweit ganz gut aus!

Habe folgendes korrigiert:

in usart.c sowie in (usart)test.c
=> #include "usart.h"     //Hochkommas "" statt <>

in usart.c Zeile 35:
=> kein semicolon [;] nach dem #endif

Weiss nicht ob's daran lag.

Hab das ganze als AvrStudio-Projekt angehängt, probier mal ob's bei
Dir tut. Ich hab leider kein AtMega8515 zum ausprobieren

Gruss Peter
Angehängte Dateien:
OP #363427
Lesenswert?
• ▲
▼
@Peter

Vielen Dank für deine Arbeit, habs auch mal getestet, aber irgendwie
rührt sich da nix.
Hab leider auch kein scope da um zu sehen was am TX bzw. Rx raus-/rein
geht :(

P.S.: der code von Dir sollte Eigentlich auf den meisten megas laufen!

Ich werde jetzt nochmal einen Test machen, bei dem ich auschließlich
das ganze interuptgesteuert mache. Mal sehen ob dann was geht.
Ansonsten kann ja nur noch was am STK500 nicht stimmen.
Ist aber eigentlich auzuschließen da ja mal nur "0" nach einem rest
ankam.

Gruß
#363428
Lesenswert?
• ▲
▼
Schreibs nochmal um, sodass ein einer Schleife
staendig gesendet wird. Dann haeng mal eine
LED an den Transmit Ausgang. Die muesste eigentlich
flackern. Dann check nochmal das Seriell-Kabel durch
(gekreuzt, nicht-gekreuzt) und stell sicher, dass
das Sende-Signal am PC auch am richtigen Pin ankommt.

Meistens sind es die einfachen Dinge, die schief gehen.

Auf Interrupt wuerde ich da zunaechst mal nicht bauen.
Wenns in der allereinfachsten Version nicht geht, dann
bringen Interrupts nur einen Level Komplexitaet mehr
ins Spiel. Zum Fehlersuchen sollen die Dinge aber so
einfach wie moeglich sein.
OP #363429
Lesenswert?
• ▲
▼
Hier noch der geänderte Code:

#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
#include "usart.h"

typedef unsigned char BYTE;
typedef unsigned short WORD;

void reset(void)
{
  DDRB   = 0xff;
  PORTB  = 0x00;
  DDRD  |= (1<<DDD1);
  PORTD   |= (1<<PD1);
}

int main(void)
{
  reset();
    usart_init(9600, 8, 'N', 1);    //Init USART mit 9600 8N1
  while(1)
  {
    usart_putc(2);
  }
}

Wenn ich den jetzt ausführe Leuchtet die LED an PD1 permanent.
ist das jetzt richtig? ich vermute dass Sie leuchtet da ich PD1 auf
High beim reset gesetz habe.

Weiter ist mir beim debuggen noch folgendes aufgefallen.
Nach der initialisierung des USART **usart_init(9600, 8, 'N', 1); **
Hat UBRRL = 51 und in UBRRH sind Bit 1,2 und 7 gesetzt.
Hat das nicht zur folge das dann die Baudrate nicht mehr stimmt? oder
hat des mit URSEL(Bit7) zu tun und spielt keine rolle?

Gruß
OP #363430
Lesenswert?
• ▲
▼
Es könnte alles so einfach sein:)
Hab den Fehler endlich gefunden

Es lag am STK500

Entgegen den angaben im AVR Studio muss Pin RXD vom SPARE mit dem RX
vom  µC verbunden werden. genauso TXD

komisch, iss aber so

Trotzdem nochmals vielen Dank für eure Bemühungen.
Man merkt wieder einmal, wie hilfreich es ist gemeinsam Probleme zu
lösen.

Gruß Julien
Gast #363431
Lesenswert?
• ▲
▼
@Patrick Dohmen

>>kein semicolon [;] nach dem #endif

>Das ist auch nicht notwendig. Präprozessoranweisung
>terminiert man nicht mit Semikola.
_______________________

Mein ich ja auch, das Semikolon war zuviel! Doch ich habe mich
zugegebenermassen nicht klar genug ausgedrück!

Gruzzo  Peter

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.