Atmega8 UART ext. Quarz

Gast #6170295
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
Gast #6170321
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
Gast #6170330
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.
Gast #6170332
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.
Gast #6170335
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.
Beitrag #6170348 wurde von einem Moderator gelöscht.
Gast #6170364
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!
Gast #6170426
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.
Gast #6170611
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
}
Gast #6170645
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.
Gast #6171575
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!
Gast #6172023
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.
Gast #6172029
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!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren