Forum: Mikrocontroller und Digitale Elektronik Probleme mit der UART bei einem ATmega8


von S. S. (smi)


Angehängte Dateien:

Lesenswert?

Hallo liebe Forengemeinde,

ich würde mich selbst als Anfänger auf dem Gebiet der µC bezeichnen, 
habe aber durch mein Studium Erfahrungen mir C. Jetzt habe ich 
angefangen, mich  mit kleinen Programmen in die Sache hineinzuarbeiten 
und es lief auch bis zur UART.

Ich würde gerne eine Kommunikation zwischen meinen myAVR Board MK2 USB 
Version 2.0 bestückt mit einem ATmega8 und meinem ThinkPad aufbauen.
Ich habe das Programm so einfach wie möglich gehalten und will einfach 
nur das berühmte 'x', in einer Endlosschleife, an den PC senden.

Es funktioniert bedingt....Ich empfange in meinem Hyperterminal das 
Zeichen aus dem Anhang.

Hier mein Code:
1
#include <avr/io.h>
2
#include <stdlib.h>
3
#include <util/delay.h>
4
//#include <util/interrupt.h>
5
#include <stddef.h>
6
7
//F_CPU in Makefile definiert auf 3686400
8
9
#define BAUD 9600
10
#define MYUBRR F_CPU/16/BAUD-1
11
12
13
void USART_Init( unsigned int ubrr)
14
{
15
    /* Set baud rate */
16
  UBRRH = (unsigned char)(ubrr>>8);
17
  UBRRL = (unsigned char)ubrr;
18
    /* Enable receiver and transmitter */
19
  UCSRB = (1<<RXEN)|(1<<TXEN);
20
    /* Set frame format: 8data, 2stop bit */
21
  UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
22
  
23
}
24
25
void USART_Transmit( unsigned char data )
26
{
27
    /* Wait for empty transmit buffer */
28
  while ( !( UCSRA & (1<<UDRE)) );
29
    /* Put data into buffer, sends the data */
30
  UDR = data;
31
}
32
33
unsigned char USART_Receive( void )
34
{
35
    /* Wait for data to be received */
36
  while ( !(UCSRA & (1<<RXC)) );
37
    /* Get and return received data from buffer */
38
  return UDR;
39
}
40
41
int main( void )
42
{
43
44
USART_Init ( MYUBRR );
45
46
 while(1)
47
  {
48
49
50
  USART_Transmit('x');
51
      
52
  
53
  }
54
55
56
return 0;
57
}

Ich habe in meinem Hyperterminal 9600, 8N2 und keine Flusssteuerung 
eingestellt.

Ich denke es liegt Irgendwo an der Baudrate, habe schon viele Tipps aus 
Foren ausprobiert - leider kein Erfolg. Auch wenn ich den Wert für UBRR, 
aus dem Datenblatt bei der eingestellen F_CPU (23), direkt in main, in 
die Endlosschliefe, schreibe - auch kein Erfolg.

Habt ihr eine Idee, die mir helfen könnte?

Vielen Dank im Voraus
Smi

: Verschoben durch Moderator
von Karl H. (kbuchegg)


Lesenswert?

S. Schulz schrieb:

> Ich denke es liegt Irgendwo an der Baudrate,

tut es.
So ein Symptom deutet praktisch immer auf eine falsche 'Baudrate' hin.
Der Fehler liegt meistens darin, dass das hier

//F_CPU in Makefile definiert auf 3686400

nicht der Realität entspricht.
Soll heissen: Dein µC läuft nicht mit 3.6864Mhz sondern immer noch mit 
den 1Mhz aus dem Auslieferungszustand.

von S. S. (smi)


Lesenswert?

Danke für die Antwort.

In der Dokumentation zu dem Board steht es würde auf 3.6...MHz laufen 
und ich bekomme es aber auch mit 1 MHz nicht hin. Wie kann ich den Takt 
anpassen oder gibt es noch eine andere Lösung.

Vielen Dank

von Stefan (Gast)


Lesenswert?

Der Taktfrequenz hängt von der externen Taktquelle ab, und den 
Einstellungen der Fuse Bits. Dort kannst Du zwischen internem/externem 
Taktgeber umschalten und Du kannst die Frequenz nochmal durch 8 teilen.

Wenn Du einen 4Mhz Quartz hast, und die CLKDIV8 Fuse aktiviert ist, 
bekommst Du effektiv einen F_CPU von 1000000 Hz.

von S. S. (smi)


Lesenswert?

Kann mir Jemand einen Crahkurs im Fuses setzen geben ??? Ich nutze 
WINAVR.

Danke

von Purzel (Gast)


Lesenswert?

Das Datenblatt ? Nein ?

von Karl H. (kbuchegg)


Lesenswert?

> In der Dokumentation zu dem Board steht es würde auf 3.6...MHz laufen

Stell halt mal fest, ob dein µC mit 1Mhz läuft oder nicht
1
#define F_CPU 3686400UL
2
3
#include <avr/io.h>
4
#include <utils/delay.h>
5
6
#define LED_DDR   DDRB
7
#define LED_PORT  PORTB
8
#define LED_PIN   PB0
9
10
int main()
11
{
12
  LED_DDR |= ( 1 << LED_PIN );
13
14
  while( 1 ) {
15
    LED_PORT |= ( 1 << LED_PIN );
16
    _delay_ms( 1000 );
17
    LED_PORT &= ~( 1 << LED_PIN );
18
    _delay_ms( 1000 );
19
  }
20
}


die #define anpassen und laufen lassen. Wenn dein µC mit 3686400 Hz 
läuft, dann brennt die LED 1 Sekunde und ist 1 Sekunde aus. Brennt die 
LED 3.68 Sekunden, dann läuft der µC mit 1Mhz. Den Unterschied zwischen 
1 Sekunde und fast 4 Sekunden sieht man mit freiem Auge und danach weißt 
du mehr.

von S. S. (smi)


Lesenswert?

Hab es mit der LED ausprobiert und bin mir jetzt sicher das mein Board 
auf 3686400 läuft, da hier eine sekunde led an und eine sekunde aus.

Also die Baudrate berechtet mit F_CPU -> gleiches Ergenis wie vorher.

UBRR-Wert aus Datenblatt -> immernoch nicht korrekt Ausgabe: 
5R5R5R......

Also stimmen schon mal berechneter Wert und Wert aus Datenblatt nicht 
überein, obwohl die Berechnung aus dem Datenblatt kommt.

Ich komm nicht weiter...

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.