Forum: Mikrocontroller und Digitale Elektronik Atmega8 - USART -> nur nullen


von Di P. (drpepper) Benutzerseite


Lesenswert?

Hallo,

mein Atmega8 sendet nur nullen, wenn ich per USART_transmit etwas senden 
möchte.
Mein Terminalprogramm ist auf 9600 baud, 2 stoppbits eingestellt. 
Loopback auf TTL-Seite des MAX232 funktioniert problemlos.
Hat vielleicht jemand eine Idee, woran es liegen könnte?

Danke :)

(Es folgt der relevante Codeausschnitt)
1
#ifndef F_CPU
2
#define F_CPU 4000000     
3
#endif
4
5
#include <avr/io.h>
6
#include <inttypes.h>
7
#include <util/delay.h>
8
#include <stdlib.h>
9
#include <avr/interrupt.h> 
10
11
#define uchar unsigned char
12
#define uint unsigned int
13
14
#define FOSC 4000000  // Clock Speed
15
#define BAUD 9600
16
#define MYUBRR FOSC/16/BAUD-1
17
18
// procedures
19
20
void USART_Init(unsigned int ubrr);
21
void USART_Transmit(unsigned char data);
22
23
int main(void)
24
{  
25
  USART_Init(MYUBRR); // initialize USART
26
27
  for(;;) {  
28
         USART_Transmit(65);
29
  }
30
}
31
32
void USART_Init(unsigned int ubrr)
33
{
34
  /* Set baud rate */
35
  UBRRH = (unsigned char)(ubrr>>8);
36
  UBRRL = (unsigned char)ubrr;
37
  /* Enable receiver and transmitter */
38
  UCSRB = (1<<RXEN)|(1<<TXEN);
39
  /* Set frame format: 8data, 2stop bit */
40
  UCSRC = (1<<USBS)|(3<<UCSZ0);
41
}
42
43
void USART_Transmit( unsigned char data )
44
{
45
  /* Wait for empty transmit buffer */
46
  while ( !( UCSRA & (1<<UDRE)) )
47
  ;
48
  /* Put data into buffer, sends the data */
49
  UDR = data;
50
}

von jonny (Gast)


Lesenswert?

Was sendest du denn? Einen String doe nur Zeichen?

meine kleine Datenübetrageung sieht so aus:
1
//Funktion uart_send:
2
void uart_send(const char *s)
3
{
4
while (*s) {
5
while (!(UCSRA & (1<<UDRE)))  {   }
6
UDR = *s++;}
7
}
8
9
// Aufruf der Funktion durch:
10
uart_send("Test Test Test");

Habe deinen Code jetzt nciht genau durchgeguckt aber kannst es ja mal 
mit meinen Einstellungen Testen:
1
// BAUS: 9600 | 8 Datenbits | 1 Stoppbit
2
#define BAUD        9600UL
3
#define UBRR_BAUD   ((F_CPU/(16UL*BAUD))-1)  
4
5
void uart_init(void)
6
{
7
    // Baudrate einstellen (Normaler Modus)
8
    UBRRH = (unsigned char) (UBRR_BAUD>>8);
9
    UBRRL = (unsigned char) (UBRR_BAUD & 0x0ff);
10
11
    // Aktivieren des Empfängers, des Senders und des "Daten empfangen"-Interrupts
12
    UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
13
14
    // Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit
15
    UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
16
}

von Di P. (drpepper) Benutzerseite


Lesenswert?

Ich möchte vorerst nur einzelne Zeichen senden.

Mit deiner Methode kommt zwar was anderes als nullen, aber auch nicht 
das richtige. Abgesehen davon geht dann nach kurzer zeit garnichts mehr. 
Timer halten an, Interrupts lösen nicht aus :/

von Rolf Magnus (Gast)


Lesenswert?

Womit taktest du den AVR?

von Falk B. (falk)


Lesenswert?


von thomas (Gast)


Lesenswert?

Check mal die Kontaktierung. Hatte mal das selbe Problem, lag an ner 
schlechten Lötverbindung.

von Di P. (drpepper) Benutzerseite


Lesenswert?

Ich hab nen externen 4MHz Quarz. Allerdings auf nem Breadboard.

von Di P. (drpepper) Benutzerseite


Lesenswert?

Es geht! Danke an alle, die versucht haben, mir zu helfen :)

von Falk B. (falk)


Lesenswert?

Woran lag es?

MFG
Falk

von Di P. (drpepper) Benutzerseite


Lesenswert?

Ich habe die USART-Initialisierung verändert (keine Ahnung, warum es 
vorher nicht ging):

1
#define FOSC 4000000  // Clock Speed
2
#define BAUD 19200
3
#define MYUBRR FOSC/16/BAUD-1
4
5
void USART_Init(void)
6
{
7
  /* Set baud rate */
8
  UBRRH = (unsigned char) (MYUBRR>>8);
9
  UBRRL = (unsigned char) (MYUBRR);
10
  /* Enable receiver and transmitter */
11
  UCSRB = (1<<RXEN)|(1<<TXEN);
12
  /* Set frame format: 8data, 2stop bit */
13
  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
14
}
15
16
void USART_Transmit( unsigned char data )
17
{
18
  /* Wait for empty transmit buffer */
19
  while ( !( UCSRA & (1<<UDRE)) );
20
  /* Put data into buffer, sends the data */
21
  UDR = data;
22
}

von Falk B. (falk)


Lesenswert?

@ Da Pep

>Ich habe die USART-Initialisierung verändert (keine Ahnung, warum es
>vorher nicht ging):

Was hast du geändert, ausser der Baudrate?

>#define FOSC 4000000  // Clock Speed
>#define BAUD 19200
>#define MYUBRR FOSC/16/BAUD-1

Das sollte man lieber so schreiben, um Rundungsfehler zu minimieren

#define MYUBRR FOSC/(16*BAUD)-1

Ausserdem ist es nicht sinnvoll, die Quarzfreqeunz in zwei verschiedenen 
Defines zu definieren. F_CPU ist quasi der Standard.

MFG
Falk

von Di P. (drpepper) Benutzerseite


Lesenswert?

Ja, Baudrate und URSEL (jaja, ich weiß, ist eh auf 1 initialisiert). Ah, 
und ich habe vorher den UBRR an die Initialisierung übergeben. Jetzt 
greife ich direkt auf MYUBRR zu.

Danke wegen der Rundung.

Kosmetik mache ich später noch :D

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.