mikrocontroller.net

Forum: Compiler & IDEs USART Initialisierungs Problem


Autor: timebeast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

bin gerade dabei die USART Schnittstelle eines ATmega32 zum laufen zu 
bekommen. Unter ASM gar kein Problem, läuft prima...aber man will sich 
ja weiter bilden, von daher nun das ganze in C.

Der Code des Tutorials funktioniert nicht ein Stück,

Problem eins:
#ifndef F_CPU
  #define F_CPU 4000000L
#endif
 
#define BAUD 9600L
 
// Berechnungen
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) // Fehler in Promille 
 
#if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
#endif

da wirft er mir schon den Fehler aus "Baudrate grösser..."
liegt offensichtlich an der Warning darüber:
../RS232_header.h:17:40: warning: the right operand of "<" changes sign 
when promoted
Sprich er kommt wohl nicht mit der "-10" klar... keine Ahnung warum??

Ich hab dann die Berechnung nach guter alter ASM manier geändert auf:
  #define UBRR_VAL ((F_CPU/(BAUD*16L)-1)

wunderbar, kein Fehler mehr,... an der Stelle.

Jetzt sagt er bei:
void USART_Init(void)
{
  UCSRC |= (1<<URSEL)|(3<<UCSZ0);    // Frame-Format: 8 Bit
 
  UBRRH = UBRR_VAL>>8;

  UBRRL = UBRR_VAL & 0xFF;
}

../RS232_routines.c:9: error: expected ')' before ';' token
../RS232_routines.c:12: error: expected ';' before '}' token

Die erste Zeile (also UCSRC) setzt er mir noch, bei:
  UBRRH = UBRR_VAL>>8;  
bzw.
 UBRRL = UBRR_VAL & 0xFF;  
kommen dann die Fehler.
Irgendwie kommt er mit UBRRH/UBRRL nicht zurecht, oder so? Keine Ahnung.

Hab ich denn vergessen irgendwas zu includieren? Bisher hab ich
#include <avr/io.h>
#include <stdlib.h>
als includes mit drin...

Gruß
Ralf

: Gesperrt durch Moderator
Autor: timebeast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach ja, und wo ich schonmal dabei bin Fragen zu stellen:

Was bedeutet eigendlich dieses "L" hinter der F_CPU oder BAUD.
Variablentyp "Long" vielleicht?

Gruß Ralf

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zähl mal die Klammern in Deiner UBRR_VAL-Berechnung. Dann weißt Du, 
woher die Fehlermeldungen kommen.

Das L bedeutet, dass die Zahlen als Long-Werte (32 Bit) aufgefasst und 
dementsprechend auch die Berechnungen in Long gemacht werden. 
Andernfalls würde der Compiler die Berechnungen in 16 Bit machen 
(Default-Einstellung) und es käme u.U. Müll raus.

Autor: TSSOP14 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
im tut ist diese zeile :
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
auch drin ,
wo diese bei mir auch nicht funktioniert
er sagt immer fehler >1%

auch ist UBRR bei dieser berechnung um eins höher als bei der üblichen 
formel laut datanblatt

#define UBRR_VAL ( ( F_CPU / (BAUD*16L) -1) )

Autor: timebeast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Johannes M.:
Also ich zähle und zähle, aber das ist kein Fehler?!?!
Was meinst Du?

@TSSOP14:
ÄÄh, ja, oky, es haben also auch andere das Problem. Intressanter wäre 
es allerdings wenn Du verraten könntest wie Du´s gelöst hast ;-)

Autor: timebeast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
also das Problem ist immer noch vorhanden. Hab mal den gesamten Code aus 
dem Tutorial für einen ATmega zusammen kopiert:
#include <avr/io.h>
#include <stdlib.h>

#ifndef F_CPU
  #define F_CPU 8000000L    // Systemtakt in Hz, das L am Ende ist wichtig, NICHT UL verwenden!
#endif
 
#define BAUD 9600L          // Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!
 
// Berechnungen
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) // Fehler in Promille 
 
#if (BAUD_ERROR>10) || (BAUD_ERROR<-10))
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
#endif


  /* USART-Init beim ATmega16 */
 
int main(void)
{
    UCSRB |= (1<<TXEN);                // UART TX einschalten
    UCSRC |= (1<<URSEL)|(3<<UCSZ0);    // Asynchron 8N1 
 
    UBRRH = UBRR_VAL >> 8;
    UBRRL = UBRR_VAL & 0xFF;

return 0;
}

Läßt sich jedoch nicht durchcompelieren. Problem:
../RS232_Test.c:32:39: warning: the right operand of "<" changes sign 
when promoted
../RS232_Test.c:32:40: error: missing '(' in expression

Bisheriger Erfolg:
 #if (BAUD_ERROR>10) || (BAUD_ERROR<-10)) 
ändern in:
 #if (BAUD_ERROR>10) 

(Die Abweichung bei F_CPU von 8Mhz und 9600BAUD liegen bei 3,28645625 
Promill also nicht über 10 also geht es. Nebenbei die Berechnung von 
UBRR_VAL ergeben bei dem "clever runden" Algorytmus, Rechnung, Polynom 
genau 51,5833 und bei der "einfachen" Rechnung 51,083...)

Also, das Problem liegt hier dran:
 (BAUD_ERROR<-10) 
die -10 will er nicht,...Warum nicht????

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Welcher Compiler? Der aktuelle GCC kann's nicht sein, denn abgesehen von 
der fehlenden Klammer stört ihn daran nichts.

Autor: timebeast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AVR Studio, neuste Version. (->4.13, Build528 ->AvrPluginavrgccplugin 
1,0,0,7)

falls Dir das was sagt...

also damit funktionierts nicht...

und, ja die Klammer, war halt zu Testzwecken draußen,...tja, und nun?

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, ich hab halt deinen Code oben genommen und durch den Compiler 
gejagt. Nach der Korrektur der Klammer fand er (WinAVR 20070525) nichts 
daran auszusetzen.

Die Version vom AVR Studio ist übrigens herzlich uninteressant. Gefragt 
ist die Version vom Compiler (avr-gcc --version).

Autor: timebeast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
naja, das Problem ist, das mit der GCC Version ist nicht so richtig 
ersichtlich, beim ersten Mal kompelieren hat Studio nach WinAVR gefragt, 
also hab ich WinAVR 20070525 installiert. Danach hat er nicht mehr 
rumgemeckert, also schätze ich, das AVR Studio jetzt halt auch die 
avr-libc von WinAVR benutzt in der neusten Version. Geht trotzdem 
nicht...

Build started 7.10.2007 at 18:23:28
avr-gcc.exe  -mmcu=atmega32 -Wall -gdwarf-2       -DF_CPU=8000000UL -O1 
-fsigned-char -MD -MP -MT RS232_routines.o -MF dep/RS232_routines.o.d 
-c  ../RS232_routines.c
In file included from ../RS232_routines.c:1:
../RS232_header.h:21:40: warning: the right operand of "<" changes sign 
when promoted
../RS232_header.h:22:4: error: #error Systematischer Fehler der Baudrate 
grösser 1% und damit zu hoch!
make: *** [RS232_routines.o] Error 1
Build failed with 1 errors and 1 warnings...

ist die Ausgabe.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> -DF_CPU=8000000UL

Na also. Mach -DF_CPU=8000000L draus und schon geht's.

Autor: timebeast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Supi, funktioniert.

Das Problem ist halt das AVR Studio das makefile selbstständig erstellt. 
Tja, standartmäßig steht da wohl ein unsingned long drin, sehr nervig, 
aber großes Lob an Andreas Kaiser, Held der Stunde!!! :-)

Danke
Ralf

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du kannst auch deine Makros umbauen:
  #define F_CPU_SIGNED ((long)F_CPU)
und dies statt F_CPU verwenden.

Probier mal aus, ob das Studio ein Suffix L (Projekteinstellungen) nicht 
durchreicht.

Autor: timebeast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
naja, so ähnlich hab ich´s jetzt auch gemacht. Ich hab einfach den 
Include-Wächter rausgelöscht also statt:
#ifndef F_CPU
  #define F_CPU 8000000L    
#endif
einfach nur:
  #define F_CPU 8000000L

danach hat AVR STudio einmal kurz rumgemerkt von wegen 
Reinitialisierung, aber jetzt geht´s. Er hat nun auch die F_CPU 
Einstellung aus dem makefile rausgenommen wie´s aussieht.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Gemecker wirst du mit #undef los.

Autor: Dominik Friedrichs (forlix) Benutzerseite
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
So gehts auch ohne Warnung mit F_CPU über die Projekteinstellungen:

#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-1000)

#if (BAUD_ERROR+10>20) || (BAUD_ERROR+10<0)
  #error "USART baud error larger than 1%"
#endif

Falls jemand noch ne bessere Lösung hat, immer her damit...

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dominik Friedrichs schrieb:
> Falls jemand noch ne bessere Lösung hat, immer her damit...

Der Thread ist fast 6 Jahre alt. Was Du da machst, ist Leichenfledderei.

Bessere Lösung s. aktuelles Tutorial:

  http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

Auszug:
#include <avr/io.h> 
#define F_CPU 1000000 /* evtl. bereits via Compilerparameter definiert */
#define BAUD 9600
#include <util/setbaud.h>

Die obigen Formeln muss sich keiner mehr antun.

Autor: Dominik Friedrichs (forlix) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, bin über Google nur auf das alte 
(http://www.mikrocontroller.net/articles/AVR-Tutorial:_UART) gestoßen...

Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.