Atmega8 und USART - Empfangen funktioniert, Senden nicht.

Gast #1309598
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:
1
#include <stdint.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <avr/signal.h>
5
#include <util/delay.h>
6
#define F_CPU 3686400
7

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

19
void USART_Transmit( unsigned char data )
20
{
21
    /* Wait for empty transmit buffer */
22
    while ( !( UCSRA & (1<<UDRE)) ){
23
    }
24
    /* Put data into buffer, sends the data */
25
    UDR = data;
26
}
27

28
unsigned char USART_Receive( void )
29
{
30
    /* Wait for data to be received */
31
    while ( !(UCSRA & (1<<RXC)) );
32
    /* Get and return received data from buffer */
33
    return UDR;
34
}
35

36
void USART_Flush( void )
37
{
38
    unsigned char dummy;
39
    while ( UCSRA & (1<<RXC)){
40
        dummy = UDR;
41
    }
42
}
43

44
int main(void){
45
    USART_Init(95); //2400 BAUD bei 3686400
46
    DDRD = 12;
47
    PORTD = 0;
48
    while(1){
49
        /*if(USART_Receive() == 8){
50
            PORTD ^= 4;
51
        }
52
        else if(USART_Receive() == 16){
53
            PORTD ^= 8;
54
        }*/
55
        _delay_ms(100);
56
        USART_Transmit('A');
57
        PORTD ^= 4;
58
    }
59
}

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
Gast
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
Gast
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.
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.
Gast
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.
Gast
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.
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.
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
1
  uint8_t w;
2
  for(w = 0; w < 100; w++)
3
          _delay_ms(10);
 einen 1 Sek busy-wait gemacht.
Gast
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?
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.
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.
Hallo ich habe exakt das gleiche Problem gehabt,

ich möchte zwar ungerne ein Beitrag aus 2009 wieder hochholen, da Ihr 
nicht zu einer Lösung gekommen seid, denke ich mal wäre es nicht 
schlecht, für anderen ein weiteren Info hier reinzutun, bevor da ein 
neuer Beitrag erstellt wird.

Bei mir lag es daran, dass ich den TXEN beim init() nicht mit 
eingeschaltet habe.

1
//SO IST NUR DER EMPFANGPIN RX EINGESCHALTET
2
//UCSRB |= (1<<RXEN);
3

4
//NUN SIND BEIDE PINS EINGESCHALTET UND EMPFANGEN SOWIE SENDEN KLAPPT //EINWANDFREI
5
UCSRB |= (1<<RXEN)| (1<<TXEN);

Ich hoffe, dass es irgendwann mal jemanden helfen, der genau den 
gleichen dummen Fehler wie ich gemacht hat.

Liebe Grüße =)
Gast
Auch wenn's 8 Jahre her ist...

Julian Schmitz schrieb:
> #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);
> }

Julian Schmitz schrieb:
> int main(void){
>     USART_Init(95); //2400 BAUD bei 3686400

hier-------------^^ sollte dann besser 2400 stehen ;-)

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

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.