Forum: Compiler & IDEs USART Initialisierungs Problem


von timebeast (Gast)


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:
1
#ifndef F_CPU
2
  #define F_CPU 4000000L
3
#endif
4
 
5
#define BAUD 9600L
6
 
7
// Berechnungen
8
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
9
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
10
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) // Fehler in Promille 
11
 
12
#if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))
13
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
14
#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:
1
  #define UBRR_VAL ((F_CPU/(BAUD*16L)-1)

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

Jetzt sagt er bei:
1
void USART_Init(void)
2
{
3
  UCSRC |= (1<<URSEL)|(3<<UCSZ0);    // Frame-Format: 8 Bit
4
 
5
  UBRRH = UBRR_VAL>>8;
6
7
  UBRRL = UBRR_VAL & 0xFF;
8
}

../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:
1
  UBRRH = UBRR_VAL>>8;
bzw.
1
 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
1
#include <avr/io.h>
2
#include <stdlib.h>
als includes mit drin...

Gruß
Ralf

: Gesperrt durch Moderator
von timebeast (Gast)


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

von Johannes M. (johnny-m)


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.

von TSSOP14 (Gast)


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

von timebeast (Gast)


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 ;-)

von timebeast (Gast)


Lesenswert?

Hallo,
also das Problem ist immer noch vorhanden. Hab mal den gesamten Code aus 
dem Tutorial für einen ATmega zusammen kopiert:
1
#include <avr/io.h>
2
#include <stdlib.h>
3
4
#ifndef F_CPU
5
  #define F_CPU 8000000L    // Systemtakt in Hz, das L am Ende ist wichtig, NICHT UL verwenden!
6
#endif
7
 
8
#define BAUD 9600L          // Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!
9
 
10
// Berechnungen
11
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
12
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
13
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) // Fehler in Promille 
14
 
15
#if (BAUD_ERROR>10) || (BAUD_ERROR<-10))
16
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
17
#endif
18
19
20
  /* USART-Init beim ATmega16 */
21
 
22
int main(void)
23
{
24
    UCSRB |= (1<<TXEN);                // UART TX einschalten
25
    UCSRC |= (1<<URSEL)|(3<<UCSZ0);    // Asynchron 8N1 
26
 
27
    UBRRH = UBRR_VAL >> 8;
28
    UBRRL = UBRR_VAL & 0xFF;
29
30
return 0;
31
}

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:
1
 #if (BAUD_ERROR>10) || (BAUD_ERROR<-10))
ändern in:
1
 #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:
1
 (BAUD_ERROR<-10)
die -10 will er nicht,...Warum nicht????

von Andreas K. (a-k)


Lesenswert?

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

von timebeast (Gast)


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?

von Andreas K. (a-k)


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).

von timebeast (Gast)


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.

von Andreas K. (a-k)


Lesenswert?

> -DF_CPU=8000000UL

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

von timebeast (Gast)


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

von Andreas K. (a-k)


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.

von timebeast (Gast)


Lesenswert?

naja, so ähnlich hab ich´s jetzt auch gemacht. Ich hab einfach den 
Include-Wächter rausgelöscht also statt:
1
#ifndef F_CPU
2
  #define F_CPU 8000000L    
3
#endif
einfach nur:
1
  #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.

von Andreas K. (a-k)


Lesenswert?

Das Gemecker wirst du mit #undef los.

von Dominik F. (forlix) Benutzerseite


Lesenswert?

So gehts auch ohne Warnung mit F_CPU über die Projekteinstellungen:

1
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
2
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))
3
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000)
4
5
#if (BAUD_ERROR+10>20) || (BAUD_ERROR+10<0)
6
  #error "USART baud error larger than 1%"
7
#endif

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

von Frank M. (ukw) (Moderator) Benutzerseite


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-Tutorial/Der_UART

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

Die obigen Formeln muss sich keiner mehr antun.

von Dominik F. (forlix) Benutzerseite


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.