mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Atmega8 und USART - Empfangen funktioniert, Senden nicht.


Autor: Julian Schmitz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich weiß, dass dieses Feld schon reichlich beackert wurde, aber ich habe 
zu meinem Problem tatsächlich keine passende Lösung gefunden.

Mein Atmega8 mit MAX232 empfängt zuverlässig Daten vom PC, aber beim 
Versand kommt am PC nichts an. Das Kabel ist mit 'nem Modem geprüft.

Ich habe mein Testprogramm nun völlig auf den Rahmen des im Datenblatts 
angegebenen Codes zurückgebaut:
#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <util/delay.h>
#define F_CPU 3686400

void USART_Init( unsigned int baud )
{
    /* Set baud rate */
    UBRRH = (unsigned char)(baud>>8);
    UBRRL = (unsigned char)baud;
    /* Enable Receiver and Transmitter */
    UCSRB = (1<<RXEN)|(1<<TXEN);
    /* Set frame format: 8data, 2stop bit */
    UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}

void USART_Transmit( unsigned char data )
{
    /* Wait for empty transmit buffer */
    while ( !( UCSRA & (1<<UDRE)) ){
    }
    /* Put data into buffer, sends the data */
    UDR = data;
}

unsigned char USART_Receive( void )
{
    /* Wait for data to be received */
    while ( !(UCSRA & (1<<RXC)) );
    /* Get and return received data from buffer */
    return UDR;
}

void USART_Flush( void )
{
    unsigned char dummy;
    while ( UCSRA & (1<<RXC)){
        dummy = UDR;
    }
}

int main(void){
    USART_Init(95); //2400 BAUD bei 3686400
    DDRD = 12;
    PORTD = 0;
    while(1){
        /*if(USART_Receive() == 8){
            PORTD ^= 4;
        }
        else if(USART_Receive() == 16){
            PORTD ^= 8;
        }*/
        _delay_ms(100);
        USART_Transmit('A');
        PORTD ^= 4;
    }
}

Der auskommentierte Teil ist der Empfangsteil, der tadellos funktioniert 
(lässt 2 unterschiedliche LEDs an und ausgehen, durch das "==" gehe ich 
mal von einem stabilen Empfang aus).
Aber das Senden klappt absolut nicht. Ich habe mittlerweile auch schon 
verschiedene Terminalprogramme, inkl. eines Selbstgeschriebenen 
verwendet, aber es kommt absolut nichts an.

BAUD-Raten habe ich auch Verschiedene getestet, daran dürfte es nicht 
liegen (auch hier auf Basis der im Datenblatt angegebenen Werte).

Ich werde beinahe verrückt, kann mir jemand weiterhelfen und sagen woran 
es noch liegen könnte?

Gruß
Julian

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hilf du uns mal mit nem Schaltplan

Autor: Julian Schmitz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
http://shop.myavr.de/bestückte%20Boards/myAVR%20Bo...

Ist dieser Bausatz, vom Fotosensor mal abgesehen.

Schaltplan ist hier:

http://www.myavr.info/download/schaltplan_mk1_lpt_16.png

Gruß
Julian

Autor: Julian Schmitz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also dieser Bausatz natürlich, der Link oben ist vom schon bestückten 
Board.

http://shop.myavr.de/Bausätze%20und%20Platinen/myA...

Dürfte aber keine Rolle spielen.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wenn möglich schau dir mal das Ausgangssignal an, wenn du kein oszi hast 
kannst du auch endlos 0xaa senden, dann soltte etwa die halbe Spannung 
anliegen

Autor: Julian Schmitz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falk: Danke für die Checkliste, aber ich kann da jetzt erstmal keinen 
Punkt entdecken der bei mir zutrifft. Zumal das Empfangen ja stabil 
funktioniert.

Walter: Habe weder Oszi noch Multimeter, aber kann mir sicher die Tage 
mal eines leihen, so dass ich zumindest mal die Spannungen auf'm TX 
checken kann, danke für den Tipp.

Autor: Christopher G. (cbg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Julian Schmitz schrieb:
> ...
> void USART_Transmit( unsigned char data )
> {
>     /* Wait for empty transmit buffer */
>     while ( !( UCSRA & (1<<UDRE)) ){
>     }
>     ...
> }
>
> unsigned char USART_Receive( void )
> {
>     /* Wait for data to be received */
>     while ( !(UCSRA & (1<<RXC)) );
>     ...
> }

Vl optimiert der compiler die Warteschleife beim senden weg, da sie 
wirklich leer ist. Mach sie mal so wie beim Receive also while(); oder 
gib ein asm volatile("nop\n\t" ::); rein.

Autor: Julian Schmitz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
An der Leerschleife lag es nicht. Wäre mir aber auch neu, dass eine 
While-Schleife ohne Körper, vom Compiler anders behandelt als eine mit 
leerem Körper.
Ich hab's mittlerweile auch auf dem baugleichen Board eines Kollegen 
getestet mit exakt gleichem Ergebnis.

Ich bin immer noch für weitere Vorschläge offen.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lass die UDRE-Abfrage einfach mal ganz weg, mit dem 100ms-Delay sollte 
das vorige Zeichen ja garantiert schon weg sein :-/

BTW:
Hängt der uC an der UDRE-Abfrage fest, oder blinkt die LED an
>> PORTD ^= 4;

Autor: Julian Schmitz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die LED blinkt, er hängt also nicht in der Warteschleife.
Ich habe diese jetzt auch mal weggelassen, ohne Erfolg.

Wie verhält sich der MAX232 eigentlich wenn von außen ein Signal auf TX 
ankommt?

Btw. vielen Dank für die große Resonanz.

Autor: Michael M. (mikmik)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
könnte es daran liegen, dass du DDR setzt nachdem du den uart init 
machst?
in deinem code setzt du ja das DDRD für pin 0-4 (dec. 12) wo auch der 
UART dranhängt (pin0 & pin1).

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

Bewertung
0 lesenswert
nicht lesenswert
Julian Schmitz schrieb:

> Walter: Habe weder Oszi noch Multimeter, aber kann mir sicher die Tage
> mal eines leihen, so dass ich zumindest mal die Spannungen auf'm TX
> checken kann, danke für den Tipp.

In der Zwischenzeit kannst du auch mal ein LED an den Ausgang hängen 
(mit Vorwiderstand). Das Blinzeln der LED wirst du sehen können. Zur Not 
einfach mit der Baudrate runtergehen. Bei 300 Baud sieht man eine LED 
schon wunderbar blinken.

Autor: Julian Schmitz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe gerade alle DDR-Geschichten auskommentiert - keine Änderung. :/

Autor: Christopher G. (cbg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also bei mir funktionniert das Programm. Muss wohl an der Verkabelung 
liegen.
Ich hab nur #define F_CPU als erste Zeile stehen (für delay.h), #include 
<avr/delay.h> (avr libc 1.2.5) und den entsprechenden UBRR Wert für 2400 
bps bei 16 MHz eingetragen.

Weiters ist _delay_ms(100) auch bei 3 MHz nicht möglich. "The maximal 
possible delay is 262.14 ms / F_CPU in MHz." Dadurch kommen die Zeichen 
aber einfach nur schneller daher.
Hab mit
  uint8_t w;
  for(w = 0; w < 100; w++)
          _delay_ms(10);
 einen 1 Sek busy-wait gemacht.

Autor: Julian Schmitz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach, der delay ist nur schnell reingesetzt, normalerweise arbeite ich 
mit _delay_loop2 in Schleifen.

Also ich habe jetzt mal mit 'ner LED geguckt ob da überhaupt irgendwas 
rausgeht. Es geht nichts raus :S

Gibt es vielleicht irgendeine Form von Flußkontrolle, also z.B. CTS/RTS?

Autor: Hubert G. (hubertg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Julian Schmitz schrieb:
> Falk: Danke für die Checkliste, aber ich kann da jetzt erstmal keinen
> Punkt entdecken der bei mir zutrifft. Zumal das Empfangen ja stabil
> funktioniert.
>
Das heisst das du die Checkliste nicht durchgearbeitet hast. Würde ich 
an deiner Stelle aber machen, bei mir läuft dein Programm einwandfrei, 
schreibt schöne A ins Terminalfenster.

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

Bewertung
0 lesenswert
nicht lesenswert
Julian Schmitz schrieb:

> Also ich habe jetzt mal mit 'ner LED geguckt ob da überhaupt irgendwas
> rausgeht. Es geht nichts raus :S

Wo hast du kontrolliert?
Halt die LED einfach mal an den Prozessorpin.
Wenns dort wackelt, dann verfolg das Signal über die Platine, bis du 
letztendlich am Kabelanschluss angelangt bist. Irgendwo dazwischen geht 
es verloren.

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.