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 | int main() |
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.
@MWS das ist auch nicht mein Assemblerprogramm. Ok hab es ausprobiert, leuchtet 8 sec.
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; }
define FOSC 7372800 define F_CPU 73728 was hast du denn für ein Quarz angeschlossen? Ich dachte es war ein 8Mhz Quarz.
Ja es ist ein 8 MHz Quarz, aber im Tutorial stand man sollte die Exatkte Frequenz einstellen, so steht die auch im Datenblatt.
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.
Ist define F_CPU 73728 ein Schreibfehler und zwei Nullen fehlen? Mach einfach ein Foto des Quarzes mit der beschriftung. Bitte Bildformate beachten.
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...
WOW!!! Scheint als wäre so ein UL wichtiger als man denkt ;-) Vielen Dank für die Hilfe!!
Schon die CLKDIV8-Fuse kontrolliert? Die macht ganz fix aus einem 8MHz Quarz 1MHz F_CPU.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.