mikrocontroller.net

Forum: Compiler & IDEs USART sendet falsch


Autor: Julien M. (ljminti)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Taktfrequenz des ATmega auch wirklich von 1 MHz auf 8 MHz
gedreht?

Autor: Julien M. (ljminti)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nun der mega8515 hängt auf nem STK500 mit externem 8MHz Quarz.
Muss hier dann noch was anderes eingestellt werden bzw dann an den FUSE
BITs?

RS232 SPARE ist mit PortD des Megas verbunden.

Zum Proggen nehme ich das AVR Studio.-->erhalte dort keinerlei
Fehlermeldungen.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jap, schau dir mal die Registerkarte "Fuses" im AVR Studio an. da
kannst du das schön bequem auswählen woher er den takt nehmen soll.
dann klappts auch mitm nachbarn.

Autor: Julien M. (ljminti)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nun dort ist EXT. CRYSTAL/RESONATOR HIGH SPEED ausgewählt.
CKSEL=1111
SUT=11

ebenso:
BODLEVEL=1
BOOTSZ=00

Leider funktioniert es nicht, oder ist eben gerade diese einstellung
falsch?

Autor: Olaf_K (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Julien M. (ljminti)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Olaf
Vielen Dank für diesen Hinweis:)
Leider hat sich das Problem dadurch noch nicht gelöst!

Es wird immernoch nach jedem RESET eine 0 gesendet.
Wo können denn noch Fehler stecken?

Gruß

Autor: Julien M. (ljminti)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Julien M. (ljminti)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Dirk Bxxxxx (dirk-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

fehlt da kein " sei(); " ?

Gruß,
Dirk

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nö, gibt ja auch keine Interrupts. Also brauch man auch kein sei();

Autor: Peter (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Patrick Dohmen (oldbug) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>=> kein semicolon [;] nach dem #endif

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

Autor: Julien M. (ljminti)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Julien M. (ljminti)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Autor: Julien M. (ljminti)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

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.