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&action=artikel&id=108
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.
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?
:-)
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;
}
> 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.
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_Checkliste#UART.2FUSART
Hast du irgendwo eine LED drann hängen?
Dann pass dieses Programm an deine Gegebenheiten an.
1
/*
2
Testprogramm für CPU Takt
3
Hier die vermeintliche Taktrate des µC eintragen
4
*/
5
#define F_CPU 8000000
6
7
#include<avr/io.h>
8
#include<util/delay.h>
9
10
/*
11
Hier die tatsächlich verwendeten Parameter angeben
12
*/
13
14
#define LED_PORT PORTB
15
#define LED_DDR DDRB
16
#define LED_PIN PB0
17
18
intmain()
19
{
20
LED_DDR|=(1<<LED_PIN);
21
22
while(1){
23
LED_PORT^=(1<<LED_PIN);
24
_delay_ms(1000);
25
}
26
}
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.
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.
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;
}
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.
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...
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.
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.
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.
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.
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.
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"
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.
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.
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.
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.