Komisches Verhalten bei CPU-Frequenz und UART

OP #2270625
Lesenswert?

Hi,
ich habe ein sehr seltsames Problem.
Ich benutze eine Atmega168 mit internem Quarz und Clock durch 8, also 
mit 1 Mhz Frequenz.
Es ist voellig egal, was ich bei F_CPU, SYSCLOCK, X_TAL im Source 
einstelle, mein Uart laeuft nur mit 4800Baud. Ich verwende die Lib von 
Peter Fleury. Es ist auch egal, ob ich im Source 1 als Frequenz angebe 
oder eine utopische hohe Zahl und dann neu compilliere. Im Makefile gebe 
ich keine Frequenz an, sondern definitiv im Source.
Durch dieses komische Verhalten habe ich das Gefuehl, dass saemtliche 
Berechnungen fuer Timer, usw falsch sein muessten.

Was kann das sein?

Gruesse

Dusty
Gast #2270684
Lesenswert?

Stephan Kempa schrieb:
> Atmega168 mit internem Quarz
Wo hast Du den her? Extra von Atmel produzieren lassen?
Offiziel gibs sowas jedenfalls nicht.

Aber vermutlich läuft auch Dein Atmega168 wie alle anderen mit dem 
internen RC-Oszillator.

Schau ins Datenblatt, insbesondere die Abschnitte "19.8.3 Asynchronous 
Operational Range" und "19.11 Examples of Baud Rate Setting". Dann 
sollte Dir einiges klarer werden.
OP #2271080
Lesenswert?

Ich habe folgendes in meinem Source stehen, bevor irgendwelche anderen 
Header-Dateien eingebunden werden, also ganz am Anfang.
1
#ifndef F_CPU
2
#define F_CPU     1000000L
3
#endif
4
#define SYSCLOCK  F_CPU
5

6
#define XTAL          F_CPU

Bei der Lib von Peter Fleury wird der Uart mit diesem Aufruf 
initialisiert.
1
uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );

UART_BAUD_SELECT ist als folgendes Macro in der Lib definiert.
1
#define UART_BAUD_SELECT(baudRate,xtalCpu) ((xtalCpu)/((baudRate)*16l)-1)


Also wird die tatsaechliche Baudrate doch dadurch berechnet, oder lieg 
ich da falsch. Es ist aber egal, was ich bei F_CPU eintrage.
Durch diese Verhalten glaube ich halt, dass alle Berechnungen die auf 
F_Cpu bassieren dann falsch sind. Auch solche, wie _delay_ms und andere.
Moderator Persönliche Seite #2271100
Lesenswert?

Stephan Kempa schrieb:
> Ich habe folgendes in meinem Source stehen, bevor irgendwelche anderen
> Header-Dateien eingebunden werden, also ganz am Anfang.
>
1
> #ifndef F_CPU
2
> #define F_CPU     1000000L
3
> #endif
4
>

Kommentiere mal 2 Zeilen aus und ändere die mittlere auf 1L:
1
// #ifndef F_CPU
2
#define F_CPU     1L
3
// #endif

und schau nach, ob der Compiler dann meckert (irgendwas mit 
"redefined"). Wenn ja, wird das F_CPU irgendwo anders gesetzt. Das hat 
dann wg. dem "#ifndef F_CPU" Vorrang. Die Stelle gilt es dann zu finden.
Gast #2271104
Lesenswert?

Die richtige Baudrate wird durch das Makro aus der Taktfrequenz 
berechnet egal welchen Takt du einstellst (im Source). Wenn du 4800 Baud 
einstellst, wird diese abhängig vom CPU Takt berechnet. Und damit 
bleiben es immer 4800 Baud egal welchen Takt du einstellst.

ps: der interne Oszillator ist kein Quarz sondern ein RC Oszillator. 
Dieser ist stark Betriebsspannungabhängig (und auch Temperatur) und 
daher ungeeignet um eine Baudrate einzustellen. Es sei denn du benutzt 
die Baudrate deines PCs als Zeitnormal und stellst damit das AVR 
Zeitnormal nach (oder paßt den Baudraten Divisor an).
OP #2271108
Lesenswert?

@Frank
Das ist ja das Seltsame. Der Compiler meckert nix an. Hab das jetzt mal 
gemacht. Hier die Ausgaben des Compiler:
1
-------- begin --------
2
avr-gcc (GCC) 4.3.3    
3
Copyright (C) 2008 Free Software Foundation, Inc.
4
This is free software; see the source for copying conditions.  There is NO
5
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
6

7

8
Compiling: main.c
9
avr-gcc -c -mmcu=atmega168 -I. -gdwarf-2   -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=main.lst  -std=gnu99 -Wp,-M,-MP,-MT,main.o,-MF,.dep/main.o.d main.c -o main.o       
10

11
Compiling: general.c
12
avr-gcc -c -mmcu=atmega168 -I. -gdwarf-2   -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=general.lst  -std=gnu99 -Wp,-M,-MP,-MT,general.o,-MF,.dep/general.o.d general.c -o general.o                                                                                                             
13

14
Compiling: io.c
15
avr-gcc -c -mmcu=atmega168 -I. -gdwarf-2   -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=io.lst  -std=gnu99 -Wp,-M,-MP,-MT,io.o,-MF,.dep/io.o.d io.c -o io.o                 
16

17
Compiling: uart.c
18
avr-gcc -c -mmcu=atmega168 -I. -gdwarf-2   -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=uart.lst  -std=gnu99 -Wp,-M,-MP,-MT,uart.o,-MF,.dep/uart.o.d uart.c -o uart.o       
19

20
Compiling: vt100.c
21
avr-gcc -c -mmcu=atmega168 -I. -gdwarf-2   -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=vt100.lst  -std=gnu99 -Wp,-M,-MP,-MT,vt100.o,-MF,.dep/vt100.o.d vt100.c -o vt100.o  
22

23
Compiling: sonic.c
24
avr-gcc -c -mmcu=atmega168 -I. -gdwarf-2   -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=sonic.lst  -std=gnu99 -Wp,-M,-MP,-MT,sonic.o,-MF,.dep/sonic.o.d sonic.c -o sonic.o  
25

26
Linking: main.elf
27
avr-gcc -mmcu=atmega168 -I. -gdwarf-2   -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=main.o  -std=gnu99 -Wp,-M,-MP,-MT,main.o,-MF,.dep/main.elf.d main.o general.o io.o uart.o vt100.o sonic.o   --output main.elf -Wl,-Map=main.map,--cref    -lm -Ttext=0x0000                                 
28

29
Creating load file for Flash: main.hex
30
avr-objcopy -O ihex -R .eeprom main.elf main.hex
31

32
Creating load file for EEPROM: main.eep
33
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
34
        --change-section-lma .eeprom=0 -O ihex main.elf main.eep
35
avr-objcopy: --change-section-lma .eeprom=0x0000000000000000 never used
36

37
Creating Extended Listing: main.lss
38
avr-objdump -h -S main.elf > main.lss
39

40
Creating Symbol Table: main.sym
41
avr-nm -n main.elf > main.sym
42

43
Size after:
44
main.elf  :
45
section            size      addr
46
.text              4646         0
47
.bss                266   8388864
48
.stab              8580         0
49
.stabstr            962         0
50
.debug_aranges      192         0
51
.debug_pubnames     856         0
52
.debug_info        4540         0
53
.debug_abbrev      1632         0
54
.debug_line        3757         0
55
.debug_frame        784         0
56
.debug_str         1161         0
57
.debug_loc         1790         0
58
.debug_ranges       144         0
59
Total             29310
60

61

62

63
Errors: none
64
-------- end --------

Kein einziger Fehler.


@Uwe
Ans Macro wird aber doch F_CPU uebergeben. Also muesste doch bei 
aenderung auch das Ergebniss anders sein, oder seh ich den Wald vor 
lauter Baeumen nicht?
Beispiel:
F_CPU=1000000L
((1000000)/((4800)*16l)-1)=12.020833
F_CPU=8000000L
((8000000)/((4800)*16l)-1)=103.166
Gast #2271527
Lesenswert?

Bei den Mega48/88/168/328 liegt das Register UBRR bei 0xC4.

Die Fleury-Routinen kennen ich nicht. Schreiben die denn auch an diese 
Adresse?
Oder sprechen diese die Adresse 0x09 an, wo zum Beispiel UBRR vom 
ATmega16 und anderen ATmegas liegt?
Persönliche Seite #2271585
Lesenswert?

Wenn du UART_BAUD_RATE auf 4800 stellst bekommst du egal für welches 
F_CPU immer eine Baudrate von 4800 das ist ja der Sinn der Berechnung. 
Wenn du eine andere Baudrate möchtest, musst du UART_BAUD_RATE 
entsprechend definieren.

>>F_CPU=1000000L
>>((1000000)/((4800)*16l)-1)=12.020833
>>F_CPU=8000000L
>>((8000000)/((4800)*16l)-1)=103.166

damit wird der Wert für den Baudratenteiler berechnet, der bei 
steigender CPU Frequenz größer werden muss um die gleiche Baudrate zu 
erhalten.
Gast #4211370
Lesenswert?

Für 1 MHz würd ich den UART aber auch nur mit 4800 baud betreiben, weil 
sonst die Abweichung größer 1% wird (siehe vorherige Antwort).
Hier eine Übersicht, welche Baudraten man mit welcher CPU Frequenz 
einstellen kann, ohne über 1% zu kommen:
 1MHz: 4800
 2MHz: 9600
 3MHz: 14400
 4MHz: 19200
 6MHz: 28800
 8MHz: 38400, 56000
 9MHz: 56000
11MHz: 38400, 57600, 115200
12MHz: 57600
...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren