Forum: Mikrocontroller und Digitale Elektronik Atmega8 UART ext. Quarz


von Dag0bert (Gast)


Lesenswert?

Guten Abend zusammen,

ich habe ein Problem mit der seriellen Datenübertragung bei einem 
Atmega8.
Befeuert wird der µC mit einem externen 8 MHz Quarz und den passenden 
Keramikkondensatoren. Die Fuse-Bits habe ich mit dem "AVR8 Burn-O-Mat" 
von Torsten Brischalle eingestellt. Also: external crystal, 3-8 MHz 
frequency range, large output swing und slowly rising power.
In der Software habe ich dann den UBBR-Wert für eine Baudrate von 9600 
Baud bei f_clk=8 MHz berechnet und in das entsprechende Register 
geschrieben. Einstellungen bzw. entsprechende Bits gesetzt für: 8-Bit 
Datenrahmen, 1 Stopbit und keine Parität.

Nun zu meinem Problem:
Wenn ich mit dem Atmega8 reden möchte (hterm), dann funktioniert das nur 
bei einer Baudrate von 300 Bit/s. Bei der eingestellten bzw. gewünschten 
Baudrate von 9600 Bit/s funktioniert es nicht. Es ist so, als wäre es 
ihm einfach zu schnell.

Woran könnte das liegen?

Gruß
Dag0bert

von Einer K. (Gast)


Lesenswert?

Da hilft nur "vor Ort Diagnose"

LA oder Oszi zeigen dir das Verhalten.

von Herman Kokoschka (Gast)


Lesenswert?

In den Fuses den Vorteiler DIV8 abgeschaltet?
UBBR-Wert korrekt berechnet?

Kommen denn bei den 300Baud die RICHTIGEN Daten, oder nur irgendein 
Müll?

von H.Joachim S. (crazyhorse)


Lesenswert?

Dag0bert schrieb:
> In der Software habe ich dann den UBBR-Wert für eine Baudrate von 9600
> Baud bei f_clk=8 MHz berechnet und in das entsprechende Register
> geschrieben.

Schön, dass du das berechnet hast...
Vielleicht zeigst du mal die UART-Initialisierung.

Dann gibts noch die div8-fuse.

von spess53 (Gast)


Lesenswert?

Hi

> Also: external crystal, 3-8 MHz
>frequency range, large output swing und slowly rising power.
>In der Software habe ich dann den UBBR-Wert für eine Baudrate von 9600
>Baud bei f_clk=8 MHz berechnet und in das entsprechende Register
>geschrieben. Einstellungen bzw. entsprechende Bits gesetzt für: 8-Bit
>Datenrahmen, 1 Stopbit und keine Parität.

Und wie sehen die genauen Werte aus?

MfG Spess

von Wolfgang (Gast)


Lesenswert?

Dag0bert schrieb:
> Woran könnte das liegen?

Das du dich verrechnet hast oder eine Fuse falsch eingestellt hast.

Wie sieht deine Initialisierung für den Baud Rate Generator aus?
Wie hast du deine Fuses gesetzt?
Wie schnell blinkt eine LED mit einem 1Hz LED-Blink Programm?
Hast du ein Oszi oder einen LA?

von Wolfgang (Gast)


Lesenswert?

H.Joachim S. schrieb:
> Dann gibts noch die div8-fuse.

Bei einem ATmega8?

Ein Faktor 8 würde außerdem einen Faktor 32 in der Symbolrate alleine 
nicht erklären.

von Dag0bert (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> Da hilft nur "vor Ort Diagnose"
>
> LA oder Oszi zeigen dir das Verhalten.

Ich habe mir das vom PC gesendete Signal schon mit dem Oszi angeschaut, 
bei verschiedenen Baudraten, passt alles soweit. Taktfrequez des µC habe 
ich auch überprüft (Timer -> toggle Pin).


Herman Kokoschka schrieb:
> In den Fuses den Vorteiler DIV8 abgeschaltet?
> UBBR-Wert korrekt berechnet?
>
> Kommen denn bei den 300Baud die RICHTIGEN Daten, oder nur irgendein
> Müll?

Von einem Vorteiler in den Fuses höre ich das erste mal, muss ich noch 
einmal nachschauen. Allerdings hätte dann die gemessene Taktfrequenz am 
Pin nicht gestimmt.
Den UBBR-Werte sollte ich richtig berechnet haben (nach Datenblatt).
Bei 300 Baud kommen die richtigen Daten an.


H.Joachim S. schrieb:
> Dag0bert schrieb:
>> In der Software habe ich dann den UBBR-Wert für eine Baudrate von 9600
>> Baud bei f_clk=8 MHz berechnet und in das entsprechende Register
>> geschrieben.
>
> Schön, dass du das berechnet hast...
> Vielleicht zeigst du mal die UART-Initialisierung.
>
> Dann gibts noch die div8-fuse.

Habe den code gerade nicht zur Hand, reiche ich nach.

von Einer K. (Gast)


Lesenswert?

Dag0bert schrieb:
> Ich habe mir das vom PC gesendete Signal schon mit dem Oszi angeschaut,

Und, die andere Richtung?

Tipp:
PC->µC kann man sich anschauen, zum Vergleich
µC->PC sollte man sich dringenst anschauen, wenn man Probleme hat.

Dag0bert schrieb:
> Den UBBR-Werte sollte ich richtig berechnet haben (nach Datenblatt).
Natürlich musst du deine Berechnung(ERgebnis) und die UART 
Initialisierung geheim halten.
Sonst wird das Problem ja langweilig, wenn jeder sofort den Fehler sehen 
kann.

von Dag0bert (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> Dag0bert schrieb:
>> Ich habe mir das vom PC gesendete Signal schon mit dem Oszi angeschaut,
>
> Und, die andere Richtung?
>
> Tipp:
> PC->µC kann man sich anschauen, zum Vergleich
> µC->PC sollte man sich dringenst anschauen, wenn man Probleme hat.

Bei 300 Baud passt auch das Signal µC->PC.
Bei größerer Baudratekommt nur Müll an. Das liegt aber vermutlich daran, 
dass die gesendeten Daten abhängig davon sind, welche Daten empfangen 
wurden. Soll heißen, wenn er die zu empfangenden Daten nicht richtig 
versteht, kommt bei den darrauf gesendeten auch nur Müll raus.

von Wolfgang (Gast)


Lesenswert?

Dag0bert schrieb:
> Von einem Vorteiler in den Fuses höre ich das erste mal, muss ich noch
> einmal nachschauen.

Ich auch, zumindest beim ATmega8 ;-)

von spess53 (Gast)


Lesenswert?

Hi

Dir ist auch bekannt das die Register UBRRH und UCSRC die gleiche 
Adresse besitzen und mit dem Bit URSEL ausgewählt wird, welches der 
beiden Register angesprochen wird?

MfG Spess

Beitrag #6170348 wurde von einem Moderator gelöscht.
von Herman Kokoschka (Gast)


Lesenswert?

Dag0bert schrieb:
> Bei 300 Baud passt auch das Signal µC->PC.

Ok, sieht nach einem simpel-zu-lösenden Problem aus:
Deine UART-Init ist nicht korrekt.

DA JA NUN ABER Dein Init-Code offizielle Geheimsache bleibt,
ist kaum zu helfen.

UND mit Verlaub:
Es ist schon etwas sehr-albern, dies geheimzuhalten.
Dann frag aber auch halt nicht!

von Frank B. (frank501)


Lesenswert?

Mal wieder typisch µC.net
Es heißt zwar, wer lesen kann, ist klar im Vorteil, aber wer es nicht 
TUT, ist noch mehr im Nachteil als jener, der es nicht kann:


Dag0bert schrieb:
> Habe den code gerade nicht zur Hand, reiche ich nach.

von Herman Kokoschka (Gast)


Lesenswert?

@Frank B.:
Dag0bert in der Autowerkstatt:

"Ich habe an meinem Auto gebastelt, aber das funktioniert nicht.
Ich habe aber ALLES RICHTIG GEMACHT. Woran liegt das jetzt?"

Werkstatt:
"Können Sie etwas mehr dazu sagen?"

Dag0bert:
"Nö, ist unnötig weil ICH HABE ALLES RICHTIG GEMACHT!"

Werkstatt:
"Sind Sie da sicher, hier mal 3-4 theoretische Fehlerursachen"

Dag0bert:
"Nö, ICH HABE ALLES RICHTIG GEMACHT!
Warum funktioniert das nicht?"

Werkstatt:
"Können wir denn das Auto wenigstens mal sehen?"

Dag0bert:
"Nö, Habe ich gerade nicht zur Hand."

Beitrag #6170580 wurde von einem Moderator gelöscht.
Beitrag #6170586 wurde von einem Moderator gelöscht.
von Dag0bert (Gast)


Lesenswert?

spess53 schrieb:
> Hi
>
> Dir ist auch bekannt das die Register UBRRH und UCSRC die gleiche
> Adresse besitzen und mit dem Bit URSEL ausgewählt wird, welches der
> beiden Register angesprochen wird?
>
> MfG Spess

Danke Spess für den Hinweis, daran liegt es vermutlich. Konnte es aber 
noch nicht probieren.


An den Rest: Bitte die Kirche im Dorf lassen. Wie gesagt, reiche ich den 
Code nach (siehe unten).

Mit der seriellen Schnittstelle sollen Werte an für einen Drehzahlregler 
übertragen werden. Zu Testzwecken habe ich es aktuelle so realisiert, 
dass bei empfangen eines der Zeichen (n,p,i), jweils der entsprechende 
Werte eingegeben werden muss (Drehzahlsollwert, proportional-/ 
integral-Verstärkungsfaktor)
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
#define F_CPU 8000000UL  // Prozessorfrequenz
5
#define BAUD 9600UL  //Baudrate
6
#define UBBR_Value  F_CPU/16/BAUD-1
7
8
volatile uint8_t Auswahl=0;  //globale variable
9
char *Drezahlanfrage = "\r\nDrehzahlwert eingeben: \r\n"; // string kommen in " " Zeichenkette als char-array: *Satz, \r\n für Zeilenumbruch
10
char *I_Anfrage = "\r\nI-Verstaerkungswert eingeben: \r\n";
11
char *P_Anfrage = "\r\nP-Verstaerkungswert eingeben: \r\n";
12
char *Eingabe = "\r\n\r\nn fuer Drehzahl,\r\np fuer P-Verstaerkungsfaktor,\r\ni fuer I-Verstaerkungsfaktor\r\neingeben: \r\n";
13
char data,data_n,data_p,data_i; // char kommen in ' '
14
15
16
//-------------------Funktionen-------------------
17
18
19
void USART_init (uint16_t ubrr)
20
{
21
  UBRRH = (uint8_t)(ubrr >> 8);  // Berechneter Wert aus Baudrate und Prozessortakt
22
  UBRRL = (uint8_t)ubrr;
23
  UCSRC = (1<<UCSZ1)|(1<<UCSZ0);  // Datenrahmen einstellen 8bit
24
  UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);  // RXEN/TXEN Sende-,Empfangskanal aktivieren, Empfangsinterrupt aktivieren
25
  
26
}
27
28
void USART_Flush(void)
29
{
30
  uint8_t dummy;        //entfernen evtl. vorhandener ungültiger Werte
31
  while (UCSRA & (1<<RXC));
32
  dummy=UDR;
33
}
34
35
char USART_Receive (void)
36
{
37
  while( !(UCSRA & (1<<RXC)) );  //Wenn Bit RXC gesetzt, dann Daten im Empfangspuffer
38
  return UDR;  //Funktion gibt Byte aus Datenregister UDR zurück
39
}
40
41
void USART_Transmit (char data) // war uint8_t
42
{
43
  while ( !( UCSRA & (1<<UDRE)) );
44
  UDR = data;
45
}
46
47
void USART_Transmit_STRING (char *s)
48
{
49
  while(*s)
50
  {
51
    USART_Transmit (*s);
52
    s++;
53
  }
54
}
55
56
57
//-------------------Hauptprogramm-------------------
58
59
60
int main(void)
61
{
62
63
DDRC=0x0F;  // alle Pins an PortC als Ausgänge
64
DDRD=0x04;  // alle Pins an PortD als Ausgänge
65
DDRB=0xFF;  // alle Pins an PortD als Ausgänge
66
USART_init(UBBR_Value);
67
USART_Flush();
68
sei();
69
70
while(1)
71
  {
72
    //PORTC = 0x00;
73
    //data=USART_Receive();
74
    //USART_Transmit(data);
75
    //PORTC = data;
76
    PORTD ^= ( 1 << PD2 );
77
  }
78
79
}
80
81
82
//-------------------ISR-------------------
83
84
85
ISR(USART_RXC_vect)
86
{
87
///*
88
  if (Auswahl == 0)
89
  {
90
    data=USART_Receive();
91
  }
92
93
94
  if (Auswahl == 1)
95
  {
96
    data_n=USART_Receive();
97
      PORTB ^= ( 1 << PB1 );
98
    if (data_n == 8)
99
    {
100
      Auswahl=0;
101
      data_n=0;
102
      data=0;
103
    }
104
       
105
  }
106
  else if (Auswahl == 2)
107
  {
108
    data_p=USART_Receive();
109
    if (data_p == 8)
110
    {
111
      Auswahl=0;
112
      data_n=0;
113
      data=0;
114
    }
115
  }
116
  else if (Auswahl == 3)
117
  {
118
    data_i=USART_Receive();
119
    if (data_i == 8)
120
    {
121
      Auswahl=0;
122
      data_n=0;
123
      data=0;
124
    }
125
  }
126
127
128
  if (data == 'n')
129
  {
130
    USART_Transmit_STRING(Drezahlanfrage);
131
    Auswahl=1;
132
  }
133
  else if (data == 'p')
134
  {
135
    USART_Transmit_STRING(P_Anfrage);
136
    Auswahl=2;
137
  }
138
  else if (data == 'i')
139
  {
140
    USART_Transmit_STRING(I_Anfrage);
141
    Auswahl=3;
142
  }
143
  else
144
  {
145
    USART_Transmit_STRING(Eingabe);
146
    Auswahl=0;
147
  }
148
//*/
149
}

von S. Landolt (Gast)


Lesenswert?

> Danke Spess für den Hinweis, daran liegt es vermutlich.

So ist es. Die Übertragungsrate wird nicht auf 9600 Bd eingestellt, 
sondern auf 315. Dieses
1
UCSRC = (1<<UCSZ1)|(1<<UCSZ0);
geht in Wirklichkeit nach UBRRH, damit wird UBRR = 6*256 + 51.

von Stefan F. (Gast)


Lesenswert?

Ich empfehle, die Berechnung der Baudrate nicht selber vorzunehmen, 
sondern die dafür vorgesehene Header Datei der AVR C Bibliothek zu 
verwenden. Dann kann man an dieser Stelle auch nichts falsch machen.
https://www.nongnu.org/avr-libc/user-manual/group__util__setbaud.html

von Dag0bert (Gast)


Lesenswert?

Danke für die konstruktiven Beiträge und die Hlfe bei der 
Lösungsfindung!

von Dyson (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Ich empfehle

Ich empfehle, diesen unsinnigen Beitrag zu ignorieren, da das in diesem 
Fall zu gar nichts führt.

von Stefan F. (Gast)


Lesenswert?

Dyson schrieb:
> Ich empfehle, diesen unsinnigen Beitrag zu ignorieren, da das in diesem
> Fall zu gar nichts führt.

Du bist ja echt eine heiße Luftpumpe.

Hat er die Baudrate richtig berechnet? Nein!

Habe ich ihm den allgemein gültigen korrekten Algorithmus für alle AVR 
samt Doku empfohlen? Ja.

Hat Dag0bert sich dafür bedankt? Ja.

Was hast du hier überhaupt verloren? Du hast hier gar nichts 
intelligentes beigetragen. Denke mal darüber nach!

von Dyson (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Dyson schrieb:
>> Ich empfehle, diesen unsinnigen Beitrag zu ignorieren, da das in diesem
>> Fall zu gar nichts führt.
>
> Du bist ja echt eine heiße Luftpumpe.

Da gehen die Meinungen auseinander.

> Hat er die Baudrate richtig berechnet? Nein!

Doch, hat er. Er hat das URSEL-Bit nicht gesetzt und damit die korrekte 
Baudrate unwissentlich überschrieben.

> Habe ich ihm den allgemein gültigen korrekten Algorithmus für alle AVR
> samt Doku empfohlen? Ja.

Deine Epmpfehlungen kannst du dir... Lassen wir das.
> Hat Dag0bert sich dafür bedankt? Ja.

Bei den Leuten mit den konstruktiven Beiträgen, also nicht bei dir.

> Was hast du hier überhaupt verloren?

Was geht dich das an?

> Du hast hier gar nichts intelligentes beigetragen. Denke mal darüber
> nach!

Den Ball spiele ich einfach mal zurück.

von Einer K. (Gast)


Lesenswert?

Klasse!
Zwei Hähne auf dem gleichen Misthaufen und plustern sich mit 
Selbstbeweihräucherungen auf.

Sieht von weitem etwas borniert/blamabel aus.

Aber lasst euch nicht stören, die Show ist toll.
Weiter machen!

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.