Hi all, ich fange an, mein atmel mega16 zu programmieren, und versuche dieses einfache programm, zu programmieren. aber es klappt bei der zeicheneingabe net. weist jemand vielleicht woran es liegt. ------------------------------------------------------------------------ --- #define FOSC 3686400 // Clock Speed #define BAUD 9600 #define MYUBRR FOSC/16/BAUD-1 #include <avr/io.h> // USART initialisieren 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) | (1 << USBS) | (3 << UCSZ0); } // Zeichen senden void USART_Transmit (unsigned char data) { /* Wait for empty transmit buffer */ while (! (UCSRA & (1 << UDRE) ) ) ; /* Put data into buffer, sends the data */ UDR = data; } // Zeichen empfangen unsigned char USART_Receive (void) { /* Wait for data to be received */ while (! (UCSRA & (1 << RXC) ) ) ; /* Get and return received data from buffer */ return UDR; } int main (void) { // Parameter definieren unsigned char temp; // Schnittstelle Initialisierung USART_Init (MYUBRR); // Hauptprogramm USART_Transmit ('>'); temp = USART_Receive (); USART_Transmit (' '); USART_Transmit (temp); return 0; } ------------------------------------------------------------------------ ---
1 | #define FOSC 3686400L // Clock Speed // das L ist wichtig
|
2 | #define BAUD 9600
|
3 | #define MYUBRR FOSC/16/BAUD-1
|
4 | ..
|
5 | return 0; // wo springt er denn hier hin?? |
Sind die Einstellungen im Terminal auch korrekt?
Ich bin auch Anfänger, aber fehlt da nach "int main (void)" nicht die Schleife while(1){ ? Oder hab ich da was falsch verstanden?
>nach "int main (void)" nicht die Schleife while(1){ ? Oder hab ich da was >falsch
verstanden?
Naja ja.
Aber die muss nicht (gleich) hinter
1 | int main (void) |
deshalb ja meine Frage, wo er (der µC) bei
1 | return 0; |
hinspringt
Meiner Meinung nach müsste doch der Code so aufgebaut sein:
1 | int main (void){ |
2 | ...
|
3 | while(1){ |
4 | //Was zu tun ist
|
5 | }
|
6 | return 0; |
Der letzte Befehl meldet doch einfach 0 zurück und bricht dann main ab, oder?
Hallo, deine main wird exakt einmal durchlaufen. Also pack die USART Funktion in eine while (1) Schleife (oder eine for Endlosschleife), nicht jedoch die Initialisierung des USART. Mit return 0 im main springt der uC ins Nirvana, deine main darf das return also nie (!) erreichen! Robert
Konkret:
1 | int main (void) |
2 | {
|
3 | // Parameter definieren
|
4 | unsigned char temp; |
5 | |
6 | // Schnittstelle Initialisierung
|
7 | USART_Init (MYUBRR); |
8 | while(1){ |
9 | // Hauptprogramm
|
10 | USART_Transmit ('>'); |
11 | |
12 | temp = USART_Receive (); |
13 | |
14 | USART_Transmit (' '); |
15 | |
16 | USART_Transmit (temp); |
17 | }
|
18 | return 0; //Never reached |
19 | }
|
Oder bin ich damit wirklich auf dem Holzweg?
hallo beide. --- Matthias L. wie so is der - UL - wichtig? wofür seht es? und den - return 0; anweisung - habe ich einfach eingebaut, da die main-fkt von typ int ist. das programm soll erstmal einmal durchlaufen, um die fkt zu testen, ob es richtig funktionert. deswegen gibst auch in diesem programm keine unendl. scheife. --- Patrick ja. aber erst will ich nur alle fuktionen prüfen. später tue ich die while-schleife ein.
>wie so is der - UL - wichtig? wofür seht es?
Weil nach C-Standart der Compiler sonst mit 16bit arbeitet. Und wie
lautet 3686400 in eine 16bit Zahl "gepresst"? Richtig: 16384.
Und du hast ja wohl kaum einen 16kHz Quartz dran, oder?
PS: die Quartzfrequenz von 3,6864MHz hab ich noch nie gehört..
(Muss aber nix heißen)
aber das prob ist es, dass nach der ausgabe von > das programm net weiter läuft
>Oder bin ich damit wirklich auf dem Holzweg?
Nein. Passt schon. Da aber damit das return 0 NIE ausgeführt wird, kann
man es auch weglassen, und das main als void deklarieren..
(Es folgt eine Warnung da nicht C-konform, die kann aber (als einzige
Warnung) ignoriert werden)
>aber das prob ist es, dass nach der ausgabe von > das programm net >weiter läuft Natürlich nciht, denn was macht dieses Programm:?
1 | // Zeichen empfangen
|
2 | unsigned char USART_Receive (void) |
3 | {
|
4 | /* Wait for data to be received */
|
5 | while (! (UCSRA & (1 << RXC) ) ) |
6 | ;
|
7 | |
8 | /* Get and return received data from buffer */
|
9 | return UDR; |
10 | }
|
@ Robert (Gast) >die Initialisierung des USART. Mit return 0 im main springt der uC ins >Nirvana, deine main darf das return also nie (!) erreichen! Quark. Sowohl der AVR mit GCC als auch z.B. der M16C mit Renesas Compiler springen aus Main in eine Endlosschleife. Also nix Nirvana! MfG Falk
hmm verstehe. also diese zahl 3.6864 steht aufn quarzbauteil, die mit stk500 mitgeliefert wurde. das bedeutet doch quarzfrequenz von 3.6864 MHz. hab ich recht?
dieses programm soll einfach ein zeichen, das vom tastatur über
hyperterminal eingegeben wird, nur empfangen zu ins programm
zurückgeben.
>>>
// Zeichen empfangen
unsigned char USART_Receive (void)
{
/* Wait for data to be received */
while (! (UCSRA & (1 << RXC) ) )
;
/* Get and return received data from buffer */
return UDR;
}
tim wrote:
> ...das bedeutet doch quarzfrequenz von 3.6864 MHz. hab ich recht?
Wenn das da drauf steht, dann ja. Allerdings läuft der Controller auch
nur dann mit dem Quarztakt, wenn die Fusebits entsprechend gesetzt sind.
>dieses programm soll einfach ein zeichen, das vom tastatur über >hyperterminal eingegeben wird, nur empfangen zu ins programm >zurückgeben. Soweit richtig. Aber ich meinte, das
1 | /* Wait for data to be received */
|
2 | while (! (UCSRA & (1 << RXC) ) ); |
sorgt dafür, dass du hier SOLANGE wartest, bis ein Zeichen KORREKT empfangen wurde.. (Deshalb kann er hier mehr oder weniger lange festhängen)
ja, ich stecke hier noch fest. hab versuch zeichen einzugeben aber es passiert nix.
Welchen Hyperterminal verwendest Du? Wird denn das gesendete Zeichen ausgegeben?
hyperterminal von windows xp und die ausgabe vom zeichen > läuft alles in ordnung und dann hab ich versucht zeichen einzugeben. aber es ist nix passiert, wobei es so nur das gleiches zeichen auf dem terminal zurückgeben.
Probier mal den im Anhang. Der ist viel Konfortabler. Bei mir hat das mit dem Windows Terminal auch nie funktioniert.
vielen dank. es hat geklappt. aber es ist wirklich kömisch dass mit dem hyperterminal net fkt.
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.