www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATmega8 Frequenz stimmt nicht


Autor: Franki C. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute!

Ich arbeite mit dem USART auf dem ATMEGA8 und habe das Starterkit aus 
dem Forum 
http://www.eproo.de/index.php?module=artikel&actio...

Jetzt muss ich ja für eine genaue Frequenz den externen Quarz nutzen.
Habe dazu in AVR Studio unter Tools->Program AVR->Auto Connect unter 
Fuses folgende Einstellungen gemacht die auf dem Bild zu sehen sind. 
Habe auch eine Delay Time von 0 und 4 ms ausprobiert, auch mit BODEN und 
ohne auch mit CKOPT und ohne, aber der ATMEGA arbeitet immer mit einer 
Frequenz von ungefähr 1 MHz. Habe alles eigentlich so eingestellt wie es 
im Datenblatt und im Forum beschrieben wird. Wenn ich die Fuses auslese 
bleiben die Einstellungen auch drin.

Autor: Franki C. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach ja der Quarz schwingt, hab es nachgemessen...

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Franki C. schrieb:
> aber der ATMEGA arbeitet immer mit einer
> Frequenz von ungefähr 1 MHz

Mit welcher Frequenz soll er arbeiten?
Wie hast du die Frequenz gemessen?
:-)

Autor: Franki C. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also am im Starterkit ist ein 8 MHz Quarz angeschlossen an Pin 9 un 10, 
da gehört er auch hin und die möchte ich nutzen. Gemessen habe ich das 
so, dass ich ein einfaches Assemblerprogramm geschrieben habe, das am 
pin 0 von Port B ein Ein/Auschalten realisiert.Dabei jeden Zyklus 
beachtet und dadurch am Oszilloskop die Frequenz abgemessen. Bin knapp 
bei einem MHz. Wenn ich die 1 MHz in meinem USART einstelle stimmt dann 
auch die Baudrate.




#define FOSC 1322751 // Clock Speed
#define BAUD 9600
#define MYUBRR ((FOSC+(BAUD * 8))/(16*BAUD))-1

#include <avr/io.h>
#include<stdio.h>
#include <util/delay.h>

unsigned char USART_Receive( void );
void USART_Init( unsigned int);
void USART_Transmit( unsigned char);


void main( void ){

unsigned char a = 'U';

  PORTC = (0<<PC3);
  PORTC = (0<<PC2);
  USART_Init (MYUBRR);


  do{
    USART_Transmit(a);

  }while(1);



}

void USART_Init( unsigned int ubrr){

  /* Set baud rate */
  UBRRH = (unsigned char)(ubrr>>8);
  UBRRL = (unsigned char)ubrr;
  /* Enable receiver and transmitter */
  UCSRB = (1<<RXEN)|(1<<TXEN);
  /* Set frame format: 8data, 2stop bit */
  UCSRC = (1<<URSEL)|(0<<USBS)|(3<<UCSZ0);
  return(0);

}


void USART_Transmit( unsigned char data )
{
/* Wait for empty transmit buffer */
while ( !( UCSRA & (1<<UDRE)) )
;
/* Put data into buffer, sends the data */
UDR = data;
}

unsigned char USART_Receive( void )
{
/* Wait for data to be received */
while ( !(UCSRA & (1<<RXC)) );
//PORTB = UDR;
/* Get and return received data from buffer */
return UDR;

}

Autor: MWS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Gemessen habe ich das so, dass ich ein einfaches Assemblerprogramm
> geschrieben habe

Schönes Assemblerprogramm, und sogar in C :D

Für einen einfachen Test per Oszi würde man einen Portpin direkt 
toggeln.
Den µC Clock wie gezeigt über das UART ermitteln zu wollen ist doch 
kompletter Unsinn.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Franki C. schrieb:

> pin 0 von Port B ein Ein/Auschalten realisiert.Dabei jeden Zyklus
> beachtet und dadurch am Oszilloskop die Frequenz abgemessen. Bin knapp
> bei einem MHz. Wenn ich die 1 MHz in meinem USART einstelle stimmt dann
> auch die Baudrate.


Das hättest du auch einfacher haben können :-)

http://www.mikrocontroller.net/articles/AVR_Checkl...

Hast du irgendwo eine LED drann hängen?
Dann pass dieses Programm an deine Gegebenheiten an.
  /*
  Testprogramm für CPU Takt
  Hier die vermeintliche Taktrate des µC eintragen
  */
  #define F_CPU 8000000
 
  #include <avr/io.h>
  #include <util/delay.h>
 
  /*
     Hier die tatsächlich verwendeten Parameter angeben
  */
 
  #define LED_PORT    PORTB
  #define LED_DDR     DDRB
  #define LED_PIN     PB0
 
  int main()
  {
    LED_DDR |= (1<<LED_PIN);
 
    while( 1 ) {
      LED_PORT ^= (1<<LED_PIN);
      _delay_ms(1000);
    }
  } 

Entweder die LED ist 1 Sekunde an bzw. aus oder sie ist es nicht. Wenn 
du für F_CPU 8Mhz eingetragen hast und dein µC auch tatsächlich mit dem 
8Mhz Quarz arbeitet, dann blinkt die LED auch mit 1 Sekunde. Arbeitet 
dein µC im Wirklichkeit mit 1Mhz (obowhl es eigentlich 8 sein sollten 
und du daher auch 8000000 eingetragen hast), dann ist die LED 8 Sekunden 
an bzw. aus. Den Unterschied sieht man mit freiem Auge.

Es gibt noch einen Test. Zieh den Quarz ab. Das Blinken muss schlagartig 
aufhören, weil der µC keinen Takt mehr hat.

Solange du beide Tests nicht 100% zufriedenstellend absolviert hast, 
brauchst du gar nicht weiter mit der UART probieren. Die beiden Tests 
sind die Grundlage.

Autor: Franki C. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@MWS das ist auch nicht mein Assemblerprogramm.


Ok hab es ausprobiert, leuchtet 8 sec.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Franki C. schrieb:
> @MWS das ist auch nicht mein Assemblerprogramm.
>
>
> Ok hab es ausprobiert, leuchtet 8 sec.

Dann läuft dein µC mit 1Mhz und du musst rausfinden warum.

Autor: Franki C. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Habe jetzt mal einen anderen µController ausprobiert (ATMEGA8A) ist ja 
eigentlich fast der gleiche... Das mit der LED klappt jetzt also bei 
F_CPU 73728 blinkt die LED 1 Sekunde an und aus. Aber wenn ich das USART 
Programm laufen lasse messen ich mit dem Osziloskop an Pin3 (TxD) für 
eine high Flanke 650µs, aber bei 9600 Baud müsste ich doch 1/9600= 104µs 
messen.


#define FOSC 7372800 // Clock Speed
#define BAUD 9600
#define MYUBRR ((FOSC+(BAUD * 8))/(16*BAUD))-1

#include <avr/io.h>
#include<stdio.h>
#include <util/delay.h>

unsigned char USART_Receive( void );
void USART_Init( unsigned int);
void USART_Transmit( unsigned char);


void main( void ){

unsigned char a = 'U';

  PORTC = (0<<PC3);
  PORTC = (0<<PC2);
  USART_Init (MYUBRR);


  do{
    USART_Transmit(a);

  }while(1);



}

void USART_Init( unsigned int ubrr){

  /* Set baud rate */
  UBRRH = (unsigned char)(ubrr>>8);
  UBRRL = (unsigned char)ubrr;
  /* Enable receiver and transmitter */
  UCSRB = (1<<RXEN)|(1<<TXEN);
  /* Set frame format: 8data, 2stop bit */
  UCSRC = (1<<URSEL)|(0<<USBS)|(3<<UCSZ0);
  return(0);

}


void USART_Transmit( unsigned char data )
{
/* Wait for empty transmit buffer */
while ( !( UCSRA & (1<<UDRE)) )
;
/* Put data into buffer, sends the data */
UDR = data;
}

unsigned char USART_Receive( void )
{
/* Wait for data to be received */
while ( !(UCSRA & (1<<RXC)) );
//PORTB = UDR;
/* Get and return received data from buffer */
return UDR;

}

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
define FOSC 7372800

define F_CPU 73728

was hast du denn für ein Quarz angeschlossen? Ich dachte es war ein 8Mhz 
Quarz.

Autor: Franki C. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja es ist ein 8 MHz Quarz, aber im Tutorial stand man sollte die Exatkte 
Frequenz einstellen, so steht die auch im Datenblatt.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#define FOSC 7372800UL // Clock Speed
                    ^^
#define BAUD 9600UL
                 ^^

Autor: Michael H. (michael_h45)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
8MHz ist die exakte Frequenz.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Franki C. schrieb:
> Ja es ist ein 8 MHz Quarz, aber im Tutorial stand man sollte die Exatkte
> Frequenz einstellen, so steht die auch im Datenblatt.

die Extrakte Frequenz bei einem 8Mhz Quarz ist aber 8.000.000 Mhz.

Autor: Franki C. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was bedeutet denn das UL in 9600UL. Ist dies wichtig?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist

define F_CPU 73728

ein Schreibfehler und zwei Nullen fehlen? Mach einfach ein Foto des 
Quarzes mit der beschriftung. Bitte Bildformate beachten.

Autor: Michael H. (michael_h45)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Franki C. schrieb:
> Was bedeutet denn das UL in 9600UL. Ist dies wichtig?
lass es weg.

Autor: Michael H. (michael_h45)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan B. schrieb:
> ein Schreibfehler und zwei Nullen fehlen? Mach einfach ein Foto des
> Quarzes mit der beschriftung. Bitte Bildformate beachten.
jedem hier außer dir ist klar, was hier los ist...

Autor: Franki C. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
WOW!!! Scheint als wäre so ein UL wichtiger als man denkt ;-)
Vielen Dank für die Hilfe!!

Autor: Aldinator (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schon die CLKDIV8-Fuse kontrolliert? Die macht ganz fix aus einem 8MHz 
Quarz 1MHz F_CPU.

Autor: Michael H. (michael_h45)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hat ein mega8 nicht

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Bedeutung des UL kannst du in jedem C-Buch in den ersten Kapiteln 
nachlesen ;-)

Es gibt an, dass die damit ausgezeichnete Konstante unsigned (ohne 
Vorzeichen) und long ist.

Die Kennzeichnung ist wichtig damit die folgende Berechnung

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

mit dem entsprechenden Wertebereich berechnet wird, statt wie üblich mit 
int Werten. Dadurch lassen sich Überläufe im Wertebereich vermeiden.

Autor: Michael H. (michael_h45)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Franki C. schrieb:
> WOW!!! Scheint als wäre so ein UL wichtiger als man denkt ;-)
das is jetz zufall und funktioniert vmtl wegen eines überlaufs.

dein eigentlicher fehler ist nicht behoben.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael H. schrieb:

> Stefan B. schrieb:
>> ein Schreibfehler und zwei Nullen fehlen? Mach einfach ein Foto des
>> Quarzes mit der beschriftung. Bitte Bildformate beachten.
> jedem hier außer dir ist klar, was hier los ist...

Ich wünsche dir, dass dein Tag noch besser wird als jetzt, lieber 
Michael.

Autor: Franki C. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achso, natürlich kenn ich die Bezeichnung unsigned long hätte nur nicht 
gedacht das es in diesem Fall eine Bedeutung hat, da im Datenblatt 
leider nichts davon stand.
@Michael H.:

Habe ich noch einen Fehler? Also falls du die 8Mhz meinst die habe ich 
natürlich jetzt eingestellt auf 8000000.

Autor: Michael H. (michael_h45)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Franki C. schrieb:
> da im Datenblatt
> leider nichts davon stand.
Das ist ja auch Compiler-spezifisch und hat mit dem Controller selbst 
nichts am Hut. Der kennt nichts außer 8 bit =)

> Habe ich noch einen Fehler? Also falls du die 8Mhz meinst die habe ich
> natürlich jetzt eingestellt auf 8000000.
Alles klar - ja, das war der eigentliche Fehler.
Die Berechnung klappt auch bestens ohne die UL Tags.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael H. schrieb:

>> Habe ich noch einen Fehler? Also falls du die 8Mhz meinst die habe ich
>> natürlich jetzt eingestellt auf 8000000.
> Alles klar - ja, das war der eigentliche Fehler.
> Die Berechnung klappt auch bestens ohne die UL Tags.

?

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

Das klappt auf einem 16-Bit int System nicht wirklich.
9600 * 8  gibt einen Overflow

Bei 8000000 kann man darüber diskutieren, ob der Suffix UL sinnvoll ist 
oder nicht. Durch das UL gewinnt man auf jeden Fall noch ein Bit, 
welches im schlimmsten Fall die Overflows ein wenig hinauszögert. Bei 
den 9600 ist es aber wichtig, dass der Suffix vorhanden ist.

Da der Suffix aber auch nicht schadet, sollte deine Empfehlung sein 
"Mach sie" und nicht "Lass sie weg"

Autor: Michael H. (michael_h45)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
>> Die Berechnung klappt auch bestens ohne die UL Tags.
> ?
Ich habs grade nochmal ausprobiert. Es geht.
Muss es natürlich nicht bei jedem Compiler, insofern...

> Da der Suffix aber auch nicht schadet, sollte deine Empfehlung sein
> "Mach sie" und nicht "Lass sie weg"
...hast du da völlig Recht.



Was mich einfach störte, war das hier:

> define F_CPU 73728
Offensichtlich völlig verkehrt.
Die Antwort darauf...
> #define FOSC 7372800UL // Clock Speed
> #define BAUD 9600UL
...was total am Thema vorbeigeht.

Ja, die Casts sind generell schon richtig; aber nur einfach so als 
Antwort darauf ohne jeglichen Text dazu ist es einfach unbrauchbar.
Sieht man auch daran, dass Franki es für die Lösung hielt, obwohl es 
ganz woanders haperte.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael H. schrieb:
> Karl heinz Buchegger schrieb:
>>> Die Berechnung klappt auch bestens ohne die UL Tags.
>> ?
> Ich habs grade nochmal ausprobiert. Es geht.

Höchstens zufällig

9600 * 8 ergibt 76800 und ist damit ausserhalb des 16-Bit int Bereiches.
Du hast damit einen Overflow und anstelle das

  FOSC+(BAUD * 8))

korrekterweise 8076800 ergibt, wird dann für diesen Term  8012265 
ausgerechnet.

Dasselbe passiert dann nochmal bei

  16*BAUD

anstelle von korrekten 153600 setzt der Compiler dann hier 23708 ein.

> Muss es natürlich nicht bei jedem Compiler, insofern...

Wenn es ein 16-Bit Compiler ist, dann ja.
Das einzige was an dem Beispiel tatsächlich Compilerabhängig ist, ist 
die Fragestellung wie groß den ein int ist. Das ist aber auch schon das 
einzige was hier frei gestellt ist, denn anders als du das hier 
suggerierst, kann sich der Compiler die Berechnung hier keineswegs 
irgendwie aus den Fingern saugen.

> Was mich einfach störte, war das hier:
>
>> define F_CPU 73728
> Offensichtlich völlig verkehrt.

Da hast du recht

> Die Antwort darauf...
>> #define FOSC 7372800UL // Clock Speed
>> #define BAUD 9600UL
> ...was total am Thema vorbeigeht.

Sie korrigierte gleich 2 potentielle Probleme auf einmal. Aber die 
Lösung ist nicht, dass man das UL weglassen kann.
Wie sooft greifen da mehrere Probleme ineinander.

Autor: Michael H. (michael_h45)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
>> Die Antwort darauf...
>>> #define FOSC 7372800UL // Clock Speed
>>> #define BAUD 9600UL
>> ...was total am Thema vorbeigeht.

> Sie korrigierte gleich 2 potentielle Probleme auf einmal. Aber die
Bei einem 8MHz Quarz?
F_CPU ist noch "verkehrter" gesetzt und findet gar keine weitere 
Beachtung.

> Lösung ist nicht, dass man das UL weglassen kann.
Richtig, hab ich eingestanden.

Autor: Michael H. (michael_h45)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael H. schrieb:
> Ich habs grade nochmal ausprobiert.
Und dabei natürlich das L bei meiner 16 übersehen...
Okay, okay, ich caste auch...

Nichtsdestotrotz ist
> #define FOSC 7372800UL // Clock Speed
bei einem 8MHz Quarz Unsinn. Da kann es noch so schön 
nichtvorzeichenbehaftet und 32bit breit sein.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.