Hallo Zusammen,
ich habe nicht viel Erfahrung in der uC- Programmierung. Würde mich aber
freuen, wenn mir trotzdem jemand bei meinem Problem weiterhelfen könnte.
Folgendes: Ich möchte gerne ein Motor ansteuern. Diesen will ich z.B.
von 10000 U/min auf 7000 U/min mit Hilfe eines ATmega328P runter regeln.
Meine erste Frage wäre zur Initialisierung des UART:
Ich verstehe nicht ganz was diese Initialisierung bedeuten sollen. Nun
gut das UBRR ist ein 12 Bit-Register. UBRRH enthält die 4 MSB und UBRRL
enthält die 8 LSB. F_CPU ist ja die Taktfrequenz, beim ATmega328P also
16MHz. Ich steh da völlig auf dem Schlauch. Kann mir da jemand
weiterhelfen. Nun gut es gibt ja genügend Bsp. Mit denen ich das
irgendwie zusammen würfeln könnte und es vielleicht irgendwann auch
funktioniert. Allerdings würde ich schon gerne verstehen was das
bedeutet.
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#define F_CPU 16000000UL
#define BAUD 9600UL
#define UBRR_VAL (F_CPU+BAUD*8)/(BAUD*16)-1) //???
#define BAUD_REAL (F_CPU / (16 * (UBRR_VAL+1))) //???
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD)
#if ((BAUD_ERROR < 990) || (BAUD_ERROR < 1010))
#error Fehler der Baudrate größer 1%
#endif
void INIT_USART0 (void){
UBRR0H = UBRR_VAL >> 8;
UBRR0L = UBRR & 0xFF;
UCSR0A |=(1 << U2X0);
UCSR0B |=(1 << TXEN0) | (1 << RXEN0); // USART Receive/Transmit
Complete
UCSR0C |=(1<< UCSZ01) | (1 << UCSZ00) // Charactersize 8-bit
|(0 << USBS0) // 1 Stop Bit
|(0 << UPM01) | (0<< UPM00); // Parity Mode disabled
}
void SEND_CHAR (unsigned char DATA){
while (!(UCSR0A & (1 << UDRE0)));
UDR0 = DATA;
}
void SEND_STRING (unsigned char *DATA){
unint8_t COUNTER = 0;
while (COUNTER == 20){
SEND_CHAR(*DATA);
DATA ++;
COUNTER++;
}
}
void main (void){
unsigned char DATA [20];
INIT_USART0 ();
for(int i=0; i++; i<20){
SEND_STRING(0xB032373130373342460D); //10000 U/min
_delay_ms(8000);
SEND_STRING(0xB032333238303832300D); //9000 U/min
_delay_ms(8000);
SEND_STRING(0xB031463430413537360D); //8000 U/min
_delay_ms(8000);
SEND_STRING(0xB031423538464138420D); //7000 U/min
_delay_ms(8000);
}
}
Meine zweite Frage wäre bezüglich der Übertragung der Hex-String.
Mit dem Hyperterminal greife ich bei 10000U/min bspw. °271073B6/r ab.
Die entsprechenden Hex-Bytes wären: B0 32 37 31 30 37 33 42 46 0D
Bei der Eingabe dieses Strings, kann ich den Motor ansteuern. Wie
schaffe ich das jetzt mit dem UART? Der liest ja jedes einzelne Zeichen
(1Byte) ein also:
B 1011 0000
0 0000 0000
3 0000 0011
2 0000 0010
usw.
Allerdings muss ich das so verschicken:
B0 1011 0000
32 0011 0010
37 0011 0111
usw.
Ich wollte dass erst alles via ASCII-Darstellung über den UART jagen,
aber „°“ ist ja ein sog. nicht druckbares Zeichen. Keine Ahnung was ich
da machen soll. Evtl. als binäre Darstellung versenden?
Wie gesagt ich bin noch Anfänger. Wäre nett, wenn mir jemand bei meinem
Problem weiterhelfen könnte.
Grüße,
Louis
>Ich steh da völlig auf dem Schlauch. Kann mir da jemand>weiterhelfen. Nun gut es gibt ja genügend Bsp. Mit denen ich das>irgendwie zusammen würfeln könnte und es vielleicht irgendwann auch>funktioniert. Allerdings würde ich schon gerne verstehen was das>bedeutet.
Nun. Bitte versuche Dir erstmal das Datenblatt durchzulesen. Da steht
genau drin, wie der UBRRx Wert abhängig von der Taktfrequenz
ausgerechnet wird.
Lies es am besten zwei, drei Mal. Das ist keine Schande. Machen wir
alle, wenn es beim ersten Mal noch nicht Klick macht.
Du wirst vielleicht antworten wollen, das Du das schon gelesen hast,
auch mehrfach aber dennoch nichts verstehst.
Ich denke aber, das Du schon einige Teile verstanden haben wirst und
entweder einige Teile noch problematisch sind oder für Dich einiges
nebeneinander steht ohne das Du einen Zusammenhang herstellen kannst.
Wenn das so ist, dann schreib uns was Du schon verstanden hast und wir
können Dir dann bei Details helfen oder Dich auf einen besonderen
Abschnitt hinweisen, der eine Lücke schliesst.
Louis schrieb:> void SEND_STRING (unsigned char *DATA){> unint8_t COUNTER = 0;> while (COUNTER == 20){> SEND_CHAR(*DATA);> DATA ++;> COUNTER++;> }> }
das ist schon sehr mutig, was ist wenn du mal eine andere länge als 20
senden willst? Denn der Aufrufer weiss überhaupt nichts von der länge.
Aber noch schlimmer ist das
> while (COUNTER == 20)
das mach so überhaupt keinen sinn, weil die schleife gleich verlassen
wird, weil coutner ja 0 ist.
Louis schrieb:> Ich wollte dass erst alles via ASCII-Darstellung über den UART jagen,
wenn du es sowieso als ASCII Darstellung 'rüberjagen' willst, dann
spricht nichts dagegen, das gleich im Klartext zu tun.
Wenn du eine Drehzahl von 1000 U/min haben willst, dann übertrage doch
gleich den Text
"1000;"
(der ; ist ein Hilfszeichen, weilches dem Empfänger erlaubt
festzustellen, wann er genug Zeichen für die Zahl gesammelt hat um
sicher zu gehen, dass die Zahl auch wirklich komplett empfangen wurde
> aber „°“ ist ja ein sog. nicht druckbares Zeichen. Keine Ahnung was ich> da machen soll. Evtl. als binäre Darstellung versenden?
Geht auch.
Aber: Auch wenn es auf den ersten Blick komplizierter aussieht, ist eine
Übertragung im ASCII-Klarext einfacher zu handhaben.
* Du kannst auf der Leitung besser mitlesen
* Du kannst das leichter testen
* Du hast keine Probleme mit Synchronisiermechanismen
* Fehlererkennung ist meistens einfacher
Dem steht gegenüber
* eine längere Übertragungszeit gegenüber rein binärer Übertragung
* etwas mehr Aufwand beim Empfangen und 'dekodieren' der Nachricht.
(wobei insbesondere letzter Punkt nicht DAS große Problem darstellt. So
problemlos wie gerne gesehn ist nämlich eine rein binäre Übertragung
auch wieder nicht, solange man keine Frame-Start/Frame-Ende Bytes
dezidiert dafür abstellen kann.
Hallo Louis
als erstes mal zu deinem ersten Problem mit dem Einstellen der UART:
Die UART wird über die entsprechenden Register eingestellt. Schau mal
ins Datenblatt, da findest du die Register. Jedes hat 8 Bit, wobei jedes
Bit einen Namen hat. Um das Bit zu setzen, schiebst du eine "1" an die
Stelle (hier: UCSR0B |=(1 << TXEN0) | (1 << RXEN0) <- Bit TXEN0 und Bit
RXEN0 werden gesetzt)
Um die Baudrate einzustellen gibt es die Formel. Im Datenblatt ist eine
Tabelle, die dir sagt, welche Zahl in Register UBRR0H und UBRR0L stehen
muss. Du willst also bei einem Systemtakt von 16Mhz eine Baud von 9600
haben. Rechne mal, auf welche Zahl du kommst und vergleich es mit der
Tabelle, dann verstehst du das sicher.
Die Sache, was du mit den Hex-Werten vor hast, versteh ich nicht so
richtig. Ich glaub du springst da etwas in den Zahlensytemen hin und
her. Auch würde ich denken, dass der Wert, der an SEND_STRING übergeben
wird, zu groß ist.
Fakt ist eins: Deine SEND_CHAR Funktion sendet ein Zeichen, 8 Bit, 1
Byte. Ich würde also erstmal versuchen, die Bytes einzeln zu senden,
z.B. SEND_CHAR(0xB0); SEND_CHAR(0x32); SEND_CHAR(0x37); u.s.w.
Aber vllt sagst du uns nochmal genau, was dein Empfänger erwartet, ASCII
Zeichen oder eine Zahl, aufgeteilt in mehrere 8 Bit Blöcke, das ist mir
nämlich nicht klar.
Viele Grüße
André
Hallo zusammen,
danke für die schnellen Antworten. Aber Huch hat Recht, ich schau mir
lieber nochmal das Datenblatt durch und stell dann konkretere Fragen.
Das war etwas zu voreilig. Bis dann
Mir ist dieser Teil nicht klar und möglicherweise ist der die Ursache
für einige Missverständnisse
> Bei der Eingabe dieses Strings, kann ich den Motor ansteuern.
Ein Motor wird nicht dadurch angesteuert, dass man ihn an eine UART
hängt. Einen Motor hängt man an eine Versorungsspannung und er dreht.
Unterbricht man die Spannung hört er auf zu drehen. (*)
Um einen Motor mit einer bestimmten Drehzahl drehen zu lassen, muss es
daher so etwas wie eine Steuerelektronik geben. Und die kann man dann
auch mittels UART ansprechen (wenn die Steuerelektronik so etwas
vorgesehen hat)
* dein Motor hat eine eigene Steuerung, der man bestimmte Bytes
senden muss
* du hängst den Motor an deinen AVR an und willst vom PC aus dem AVR
sagen wie schnell der Motor drehen muss.
(Ich bin nämlich von letzterem Fall ausgegangen, komm jetzt aber drauf,
dass dein Posting auch für ersteren Fall aufgefasst werden könnte).
(*) vereinfacht gesagt. Bitte jetzt keine Hinweise auf Schrittmotoren
oder dlg. Darum geht es nicht. Es geht darum, dass man nicht einfach
einen Motor mittels UART ansprechen kann.
Hallo,
ich habs mir jetzt also nochmals durchgeschaut.
Zu meinem 1. Problem:
UBRR = ( f+BAUD*8 ) / (BAUD*16) -1
Wird zur besseren „Rundung“ der UBRR-Wertes verwendet.
Für UBRR gibt es zwei Register: UBRRL (Low-Byte) und UBRRH (High-Byte).
>> This is a 12-bit register which contains the USART baud rate.The UBRRnH>> contains the four most significant bits, and the UBRRnL contains the >>
eight least significant bits of the USART
>> baud rate.
OK, bei 9600 bps und 16MHz erhalte ich ein UBRR_Value = 103.
Wie ich das jetzt allerdings auf das UBRRL und UBRRH übertrage, bzw.
was/wie ich dann bei UBRR0H/UBRR0L einstellen muss, ist mir noch etwas
unklar.
UBRR0H = UBRR_VAL >> 8;
UBRR0L = UBRR & 0xFF;
Kurze Verständnisfrage: Der F-CPU ist ja nur eine Info für den Compiler,
aber der uC läuft dadurch j a nicht schneller oder langsamer, sondern
immer mit deram uC eingestellten Taktfrequenz, im Falle des ATmega 328P,
also mit 16 MHz. Dennoch meine ich, dass ich in manchen
Programmbeispielen schon gesehen hab, dass F_CPU und de eigentliche
Taktfrequenz nicht identisch waren bzw. F_CPU nicht entsprechend der
Taktfrequenz angegeben wurde.
Die zweite Sache:
Ich möchte mit dem uC den Motor ansteuern- ohne PC. Sorry, war etwas
schlecht beschrieben. Das Schnittstellenprotokoll konnte ich
identifizieren bzw. analysieren. Mit den folgenden Befehlen kann ich mit
Hilfe des Hyperterminals die Umdrehungsgeschwindigkeit des Motors
regulieren. Nun soll das ein uC machen.
Mit diesem Befehl kann ich die Umdrehungsgeschwindigkeit auf 10000 U/min
einstellen °271073B6/r. Die entsprechenden Hex-Bytes (siehe
ASCII-Tabelle) wären: B0 32 37 31 30 37 33 42 46 0D!
Bei der Eingabe dieses Strings, kann ich den Motor ansteuern. Wie
schaffe ich das jetzt mit dem UART? Der liest ja jedes einzelne Zeichen
(1Byte) ein, also:
B 1011 0000
0 0000 0000
3 0000 0011
2 0000 0010
usw.
Allerdings muss ich das so verschicken (siehe ASCII-Tabelle):
B0 1011 0000
32 0011 0010
37 0011 0111
usw.
Also ein Zeichen wird durch ein Nibble dargestellt. Zusammen ergibt sich
ein Byte. Ich muss das in dieser Bitfolge versenden. Allerdings liest
mein USART ja immer ein Zeichen ein und interpretiert es als ein Byte: 1
char= 1 Byte. Denkfehler? Ich habe also zwei Zeichen, die in 1 Byte
dargestellt sind.
Wie kann ich das via USART über die serielle Schnittstelle senden?
Kann ich einfach die ASCII-Zeichen angeben, also
SEND_STRING("°271073B6/r")und der USART sendet mir dann die
entsprechende Bitreihenfolge?!
Allerdings habe ich immer gemeint, das ich nicht die ASCII-Zeichen am
USART reinbekomme bzw. versende, sondern immer deren Hex-Bytes.
Denkfehler? Ein Terminalprogramm empfängt die Bitreihenfolge eines
seriellen Datenstroms, also nur die Einsen und Nullen, und wandelt sie
dann in ASCII-Zeichejn um. Wie läuft das dann beim USART?
Viele Grüße und nochmals Danke für die Antworten,
Louis
>wäre klasse, wenn mir da jemand vielleicht nochmal weiterhelfen könnte
Ich möchte mich dafür entschuldigen, dass wir Deinen zeitlichen
Anforderungen an unsere freiwillige und kostenlose Hilfe nicht genügt
haben. Falls Du Dich an ein anderes Forum wendest, das Deinen
Anforderungen eher genügt, hätten wir dafür natürlich volles
Verständnis, denn wir sind hier einfach gewohnt dann und in dem Umfang
zu antworten wenn es uns passt. Ist natürlich völlig absurd sowas, klar.
Aber so ist es nun mal.
Louis schrieb:> #if ((BAUD_ERROR < 990) || (BAUD_ERROR < 1010))
BAUD_ERROR wird auch bei korrekten Werten kleiner als 1010 sein.
Deswegen wird ein Fehler #error geworfen. Das Ungleichzeichen muss also
anders herum, so:
Louis schrieb:> Wie kann ich das via USART über die serielle Schnittstelle senden?
Kurioses Protokoll, aber sei's drum...
Erstmal ASCII nach Binär konvertieren:
- '0' subtrahieren
- falls noch >9, weitere 0x06 subtrahieren oder so, ascii table checken
Abschliessend ein bisschen bitschieben, um die Zahlen in die Nibbles zu
packen.
Hallo Mini Float und Tom,
danke für die Antworten, werde das sofort ändern und in Angriff nehmen!
@ Huch: Tut mir Leid wenn dich mein Beitrag auf irgendwelche Art und
Weise provoziert/verärgert hat. Allerdings war der Beitrag weder
ironisch, noch pöbelhaft auffordernd gemeint. Ich bin halt noch blutiger
Anfänger und ich versuch mich schon seit einiger Zeit in die Materie
rein zu beißen und ich komme nicht richtig voran. VG, Louis
>@ Huch: Tut mir Leid wenn dich mein Beitrag auf irgendwelche Art und>Weise provoziert/verärgert hat. Allerdings war der Beitrag weder>ironisch, noch pöbelhaft auffordernd gemeint.
Pushen ist einfach unschön. Dabei ist es egal ob Du es pöbelhaft gemeint
hast oder nicht.
>Ich bin halt noch blutiger>Anfänger und ich versuch mich schon seit einiger Zeit in die Materie>rein zu beißen und ich komme nicht richtig voran. VG, Louis
Schön. Aber das ist ja Dein Problem, nicht unseres.
Ganz so übel ernst brauchst Du das nicht nehmen, mein Lieber. Halte Dich
eben vor dem Pushen erstmal ein paar Tage zurück. Das ist alles. Nicht
schon nach knapp 1 1/2 Stunden. Halte Dir vor Augen, das wir Dir hier
freiwillig und kostenlos helfen.
Grüß Gott Louis,
zu deinem ersten Problem mit der Schnittstelle:
>OK, bei 9600 bps und 16MHz erhalte ich ein UBRR_Value = 103.>Wie ich das jetzt allerdings auf das UBRRL und UBRRH übertrage, bzw.>was/wie ich dann bei UBRR0H/UBRR0L einstellen muss, ist mir noch etwas>unklar.>UBRR0H = UBRR_VAL >> 8;>UBRR0L = UBRR & 0xFF;
Meiner Meinung nach musst du dem UBRRH ne 0 zuweisen, da der berechnete
Wert kleiner als 256 ist und somit in UBRRL alleine passt. Also:
UBRR0H = 0;
UBRR0L = UBRR_Val;
Das muss übrigen while(COUNTER != 20) heißen!
> void SEND_STRING (unsigned char *DATA){> unint8_t COUNTER = 0;> while (COUNTER == 20){> SEND_CHAR(*DATA);> DATA ++;> COUNTER++;> }> }
Was die serielle Übertragung angeht, kannst du das so nicht senden. Das
nicht druckbare Zeichen kannst du bspw. als Hex versenden. Also
SEND_STRING(0xB0).Den Rest kannst du ganz einfach als ASCII-Zeichen
normal versenden. SEND_STRING(’271073B6/r’), indem Zeichen für Zeichen
übertragen wird. Wenn du in die Tabelle schaust, siehst du ja, dass das
ASCII-Zeichen ’2 ’, 0x32 ist.
Die Übertragung findet immer binär statt. In der Speicherzelle steht der
Wert physikalisch gesehen also in 1 und 0. Dein String besteht immer aus
ASCII-Zeichen. Du kannst das dir vielleicht so merken, dass der
Controller für jedes Zeichen einen binären Wert hinterlegt hat. Kommt
bspw. ein Byte 0100 0001 über den USART, so interpretiert dein uC das
als ASCII-Zeichen ’A’ oder 0x41.
In deinem Programm kannst du daher auch die Bytes vgl. Es ist total
Wurst, ob du jetzt, bspw. zur Prüfung bestimmter Zeichen in einem
String, 0x41 oder ’A’ hernimmst. Der uC weiß, das damit die Bitfolge
0100 0001 gemeint ist. Bei diesen nicht druckbaren Zeichen musst du
allerdings aufpassen! Die würde ich als Hex, wie oben schreiben. ASCII
hat halt den Vorteil das es lesbarer ist und somit das Debugging
erleichtert. Wichtig ist einfach, dass du, wenn man von einem Byte
redet, die binäre Darstellung beachtest und nicht die Zeichen. Klar "A"
hat 0100 0001, aber B0 (zwei Zeichen) wird ebenfalls durch 1 Byte, also
1100 0000 präsentiert.
Ich hoffe das Hilft dir etwas weiter…
Grüße und noch frohes Schaffen!
Hallo Louis,
Du sagst daß Du 2 Zeichen in einem Byte übertragen möchtest - Du meinst
nicht zufällig eine BCD-Codierung oder?
Zu einem anderen Teil Deiner Frage wie kann ich die wieder auseinander
fieseln...
nibbel1=byte&0xF0;
nibbel2=byte&0x0F;
Zum Thema Hex oder ASCII schließe ich meinem Vorredner an.
Hallo Jürgen, Hallo Ulrich,
danke für die Antworten...
Was ich mit den zwei Zeichen in einem Byte sagen wollte, ist das ich
gedacht hab, das wenn ich 0xB0 übertragen möchte, ich zwei Zeichen
übertragen muss.
Allerdings hat Ulrich ja gesagt, dass ich immer nur die binäre Form
anschauen muss. Also 1100 0000 --> 1 Byte.
Das war glaube ich mein Denkfehler! Ich hatte immer im Hinterkopf das 1
Zeichen, 1 Byte groß ist. Wenn ich jetzt 0xB0 übertragen will muss ich
zwei Zeichen übertragen, ist ja aber nicht so. Es geht immer nur ums
binäre. Das scheint mir langsam klar zu sein.
Allerdings kommt mir die Sache mit der USART Initialisierung immer noch
etwas spanisch vor...Es will nicht in meinen Kopf gehen, weshalb man das
so macht...
>UBRR0H = UBRR_VAL >> 8;>UBRR0L = UBRR & 0xFF;
Uffff....
Trotzdem DANKE nochmal für eure Antworten!
VG
Hallo Louis,
Der Divisor für die Baudrate ist ein 12Bit Wert (4096) deshalb reicht
ein Bit nicht für den Wert. Man schreibt also die unteren 8 Bit in das
eine Register und blendet die dann mit dem "&" weg um die restlichen 4
Bit in das andere Register zu schreiben.
Schau mal in das Datenblatt des Controllers. Für ubrr musst du dann eben
bei der Initialisierung dein UBR-VAL einsetzen.
void USART_Init( unsigned int ubrr)
UBRR0H = (unsigned char)(ubrr>>8);
UBRR0L = (unsigned char)ubrr;
.
.
.
Hallo Jürgen und Klick,
danke für die Antworten und den Versuch mir das verständlich zu
machen...
Allerdings versteh ich nicht was du damit meinst...
> Der Divisor für die Baudrate ist ein 12Bit Wert (4096) deshalb reicht> ein Bit nicht für den Wert.
OK das UBRR besteht ja aus 12 Bit = 4096
Wenn ich jetzt ein UBR-VAl von 103 habe 0110 0111 sieht das ja in dem 12
Bit Register so aus: 0000 0110 0111
Wenn ich jetzt den Rechtsshift anwende werden die letzten 8 Bits heraus
geschoben. Ich hab also 0000 0000 0000. Das ist wohl auch dass, was
Ulrich mir mit 0 fürs UBRRH-Register sagen wollte, oder?
> Meiner Meinung nach musst du dem UBRRH ne 0 zuweisen, da der berechnete> Wert kleiner als 256 ist und somit in UBRRL alleine passt. Also:> UBRR0H = 0;> UBRR0L = UBRR_Val;
Aber warum der Shift und nicht gleich einfach ne 0 zuweisen?
Liegt das daran, wenn ich ein Wert wie bspw. 256 als UBR_VAl habe, das
ich dann nach dem Rechtsshift dann 0000 0000 0001 raus bekomme und die
0001 dann ins UBRRH schreibe kann?
VG
Louis schrieb:> Kurze Verständnisfrage: Der F-CPU ist ja nur eine Info für den Compiler,>> aber der uC läuft dadurch j a nicht schneller oder langsamer, sondern>> immer mit deram uC eingestellten Taktfrequenz, im Falle des ATmega 328P,>> also mit 16 MHz. Dennoch meine ich, dass ich in manchen>> Programmbeispielen schon gesehen hab, dass F_CPU und de eigentliche>> Taktfrequenz nicht identisch waren bzw. F_CPU nicht entsprechend der>> Taktfrequenz angegeben wurde.
Wenn ich das richtig interpretiere hast du hier ebenfalls ein
Verständnisproblem. Die Taktfrequenz ist abhängig von der Taktquelle die
am Mikrocontroller anliegt und muss nicht gleich 16MHz sein. Im Programm
stellst du F_CPU dementsprechend ein.
Louis schrieb:> Liegt das daran, wenn ich ein Wert wie bspw. 256 als UBR_VAl habe, das>> ich dann nach dem Rechtsshift dann 0000 0000 0001 raus bekomme und die>> 0001 dann ins UBRRH schreibe kann?
Ja, das hast du richtig verstanden.
> Wenn ich das richtig interpretiere hast du hier ebenfalls ein> Verständnisproblem. Die Taktfrequenz ist abhängig von der Taktquelle die> am Mikrocontroller anliegt und muss nicht gleich 16MHz sein. Im Programm> stellst du F_CPU dementsprechend ein.
Hi "nicht Gast", da hast du Recht:-) Also mein Board bzw.
Mikrocontroller Atmega 328P wird mit einem externen Quarzoszillator
16MHz betrieben. Ok, muss ich jetzt also mein F_CPU auf 16 MHz
einstellen? Mein F_CPU muss also gleich dem Wert des externen
Quarzoszillators sein, richtig?
Im Grunde ist die F_CPU nur eine Info für den Compiler, aber der uC
läuft dadurch ja nicht schneller oder langsamer, sondern mit der
Frequenz des externen Quarzoszillators. Wenn die beiden Werte allerdings
nicht übereinstimmen, kann es zu Problemen bei der Übertragung mit Hilfe
des USART und bei delay-Funktionen kommen ?!
Wie ich gelesen habe, sind diese externen Quarzoszillatoren viel genauer
wie der interne Oszillator des uC.
Danke für die Antwort!
> Ja, das hast du richtig verstanden.
Bei delay-Funktionen gibts da auf jeden Fall Probleme. Allgemein muss
F_CPU immer gleich der Taktfrequenz sein!!!
Hallo "Pusher" ;-)
also bei 9600 bps benötigst du meiner Meinung nach nicht mal ein
externen Oszi. WAs die Sache mit F_CPU angeht stimme ich meinem
Vorredner zu.
N´abend
Rüdi schrieb:> Das mit der Stringfunktion kannst du so knicken!> Diese Wirrwarr da oben kannst du doch auch einfach so schreiben, völlig> unnötig mit der Rundung:
warum soll man eine unnötige Abweichung einbauen,
ich würde die Rundung auf jeden Fall drin lassen
> #define UBRR_VAL FOSC/16/BAUD-1 // Equation for //Calculating UBRRn
und hier unbedingt Klammern setzen, im Beispiel geht's zwar so, aber
wenn man UBRR_VAL mal anders verwendet gibt's Probleme, also
> #define (UBRR_VAL FOSC/16/BAUD-1) // Equation for //Calculating UBRRn
Hallo Walter,
also im Tutorial habe ich auch gelesen, dass mit der zuerst
geschriebenen Formel eine bessere Rundung erzielt werden kann.
Allerdings versteh ich nicht, warum das beim Programm immer
Fehlermeldungen hervorgerufen hat.
@Rüdi: Kann ich einfach '2' eingeben? Ich muss das doch erst in Ascii
umwandeln, oder? Denkfehler?
> SEND_CHAR(0xB0);> SEND_CHAR('2'); //0x32> SEND_CHAR('7'); //0x37> SEND_CHAR('1'); //0x31> SEND_CHAR('0'); //0x30> SEND_CHAR('7'); //0x37> SEND_CHAR('3'); //0x33> SEND_CHAR('B'); //0x42> SEND_CHAR('F'); //0x46> SEND_CHAR(0x0D)
VG