Important announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
d1w_read() gibt den Typ uint8_t zurück. Mit dem oberen Durchlauf erhalte
ich als Rückgabe den Wert 0x01 (printf "hb: 1"). Die Berechnung von temp
ergibt das falsche Ergebnis von Dezimal 2246. In der binärschreibweise
erkennt man den Fehler:
0000 1000 1100 0110
->|
Das 0x01 kommt nicht wie durch tempHB<<8 an die 8te Stelle.
Wenn ich aber nun anstelle
uint8_t tempHB = d1w_read();
folgendes ersetze
uint8_t tempHB = 0x01;
, erhalte ich das richtige Ergebnis von Dezimal 454 und in der
binärschreibweise:
000 0001 1100 0110
->|
tempHB hat wie im oberen Durchlauf auch den Wert von 0x01 (printf: "hb:
1").
Was ist denn da los? Ich kann mir das absolut nicht erklären. Beidesmal
ist tempHB = 0x01, nur einmal wird der Wert durch die Funktion
zugewiesen, und einmal direkt.
Hier noch die Funktion d1w_read():
uint8_t d1w_read() {
uint8_t data = 0x00;
for (uint8_t i = 0; i < 8; i++) {
// set DDR to output
D1W_DDR |= (1 << D1W_DQ);
// put signal low
D1W_PORT &= ~(1 << D1W_DQ);
// hold down for at least 1us
_delay_us(1);
// release by DDR to input
D1W_DDR &= ~(1 << D1W_DQ);
// wait
_delay_us(10);
// read 1 (high)if (D1W_PIN & (1 << D1W_DQ)) {
data |= (1 << i);
// read 0 (low)
} else {
data &= ~(1 << i);
// wait until high//while (D1W_PIN & (1 << D1W_DQ));
}
// total slot at least 60us
_delay_us(55);
}
return data;
}
Ich bin absolut ratlos. Wird durch den Compiler irgendwas wegoptimiert?
Freue mich um jede Hilfe..
Gruß,
Kevin
Mit deinen Infor kann man das Problem nicht nachvollziehen, denn es ist
kein gültiger C-Code.
Um das Problem zu untersuchen, schaue dir den erzeugten Assembler-Code
oder ein Disassembly des erzeuigten o, elf oder hex an.
Ist dieser Code korrekt, dann liegt dein Problem woanners, zB
Stack-Überlauf, Controller ist Fehlpressung, ...
Ist der Code nicht korrekt, dann handelt es sich um einen Tool-Fehler
(Compiler, Linker, Assembler, ...)
Um das Problem nachzuvollziehen braucht man mindestens ein gültiges
(compilierbares) Stückchen C-Code, die Compiler-Version und die
Kommandozeilenoptionen.
Fehlpressung kann ich ausschließen, an einem zweiten AVR tritt der exakt
gleiche Fehler auf. Leider werde ich aus dem reinen Assembler-Code nicht
schlau (*.lss), da ich nicht Assembler spreche. Auch ein diff der beiden
lss-Dateien bringt mich nicht weiter.
Ich kann den Fehler aber noch einfacher reproduzieren:
Falsches Ergebnis (ds18b20_1.zip):
Es scheint, als würde die reine Ausgabe von printf() das Ergebnis
verändern. Aus z.b. einem 1d2 (richtig) wird ein 8d2, sobald ich das
printf weglasse.
Das C-File hängt auch im Anhang.
Anbei noch das Compiler-Log:
------ Build started: Project: DS18B20, Configuration: Release AVR ------
Build started.
Project "DS18B20.cproj" (default targets):
Target "PreBuildEvent" skipped, due to false condition; ('$(PreBuildEvent)'!='') was evaluated as (''!='').
Target "CoreBuild" in file "C:\Program Files (x86)\Atmel\AVR Studio 5.1\Vs\Compiler.targets" from project "Y:\work\avrstudio\Projects\DS18B20\DS18B20\DS18B20.cproj" (target "Build" depends on it):
Task "RunCompilerTask"
C:\Program Files (x86)\Atmel\AVR Studio 5.1\make\make.exe all
ser.c
Invoking: AVR/GNU C Compiler
"C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-gcc.exe" -funsigned-char -funsigned-bitfields -I"../../../../../git/rfm23-lib" -Os -fpack-struct -fshort-enums -Wall -c -std=gnu99 -MD -MP -MF "ser.d" -MT"ser.d" -mmcu=atmega328p -o"ser.o" "../../../../../git/rfm23-lib/ser.c"
Y:\work\git\rfm23-lib\ser.c(10,1): initialization from incompatible pointer type
Finished building: ../../../../../git/rfm23-lib/ser.c
DS18B20.c
Invoking: AVR/GNU C Compiler
"C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-gcc.exe" -funsigned-char -funsigned-bitfields -I"../../../../../git/rfm23-lib" -Os -fpack-struct -fshort-enums -Wall -c -std=gnu99 -MD -MP -MF "DS18B20.d" -MT"DS18B20.d" -mmcu=atmega328p -o"DS18B20.o" ".././DS18B20.c"
Finished building: .././DS18B20.c
Building target: DS18B20.elf
Invoking: AVR/GNU C Linker
"C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-gcc.exe" -o DS18B20.elf ser.o DS18B20.o -Wl,-Map="DS18B20.map" -Wl,-lm -mmcu=atmega328p
Finished building target: DS18B20.elf
"C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-objcopy.exe" -O ihex -R .eeprom -R .fuse -R .lock -R .signature "DS18B20.elf" "DS18B20.hex"
"C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-objcopy.exe" -j .eeprom --set-section-flags=.eeprom=alloc,load --change-section-lma .eeprom=0 --no-change-warnings -O ihex "DS18B20.elf" "DS18B20.eep" || exit 0
"C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-objdump.exe" -h -S "DS18B20.elf" > "DS18B20.lss"
"C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-size.exe" -C --mcu=atmega328p "DS18B20.elf"
AVR Memory Usage
----------------
Device: atmega328p
Program: 2256 bytes (6.9% Full)
(.text + .data + .bootloader)
Data: 38 bytes (1.9% Full)
(.data + .bss + .noinit)
Done executing task "RunCompilerTask".
Done building target "CoreBuild" in project "DS18B20.cproj".
Target "PostBuildEvent" skipped, due to false condition; ('$(PostBuildEvent)' != '') was evaluated as ('' != '').
Target "Build" in file "C:\Program Files (x86)\Atmel\AVR Studio 5.1\Vs\Avr.common.targets" from project "Y:\work\avrstudio\Projects\DS18B20\DS18B20\DS18B20.cproj" (entry point):
Done building target "Build" in project "DS18B20.cproj".
Done building project "DS18B20.cproj".
Build succeeded.
========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========
> avr-gcc DS18B20.c -S -Os -std=gnu99 -mmcu=atmega328p
gibt:
> DS18B20.c:13:17: fatal error: ser.h: No such file or directory
Ausserdem ist avr-gcc 3.3 asbach uralt. Hol dir mal was neues.
Dein Fehler sieht nach PR46779 aus, gefixt in 4.6.2 oder neuer und auch
in 4.5.4.
Johann L. schrieb:> Ausserdem ist avr-gcc 3.3 asbach uralt. Hol dir mal was neues.
Ich hatte mich auch zunächst über diese ominöse "Version" 3.3.1.27
gewundert, da sie ja mit AVRStudio5.1 so gar nicht zusammenpasst.
Aber bei genauerem Hingucken ist das nicht die gcc-Version, sondern die
Atmel-Versionsnummer ihrer eigenen Toolchain.
Da ich auch das AVRStudio5.1 drauf habe, habe ich mal nachgeschaut:
C:\>"C:\Program Files\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-gcc" -v
Using built-in specs.
COLLECT_GCC=C:\Program Files\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr-gcc
COLLECT_LTO_WRAPPER=c:/program files/atmel/avr studio 5.1/extensions/atmel/avrgcc/3.3.1.27/avrtoolchain/bin/../libexec/gcc/avr/4.5.1/lt
o-wrapper.exe
Target: avr
Configured with: /usr/local/avr32studio/hudson/workspace/avr8-gnu-toolchain/src/gcc/configure LDFLAGS=-L/storage/hudson/workspace/avr8-
gnu-toolchain/avr8-gnu-toolchain-win32_x86/lib CPPFLAGS= --target=avr --host=i686-pc-mingw32 --build=x86_64-pc-linux-gnu --prefix=/stor
age/hudson/workspace/avr8-gnu-toolchain/avr8-gnu-toolchain-win32_x86 --libdir=/storage/hudson/workspace/avr8-gnu-toolchain/avr8-gnu-too
lchain-win32_x86/lib --enable-languages=c,c++ --with-dwarf2 --enable-doc --disable-shared --disable-libada --disable-libssp --disable-n
ls --with-mpfr=/storage/hudson/workspace/avr8-gnu-toolchain/avr8-gnu-toolchain-win32_x86 --with-gmp=/storage/hudson/workspace/avr8-gnu-
toolchain/avr8-gnu-toolchain-win32_x86 --with-mpc=/storage/hudson/workspace/avr8-gnu-toolchain/avr8-gnu-toolchain-win32_x86 --enable-wi
n32-registry=avrtoolchain --enable-fixed-point --with-pkgversion=AVR_8_bit_GNU_Toolchain_3.3.1_466 --with-bugurl=http://www.atmel.com
Thread model: single
gcc version 4.5.1 (AVR_8_bit_GNU_Toolchain_3.3.1_466)
Frank M. schrieb:> Ist also gcc 4.5.1.
Um PR46779 auszuschliessen, musst du in deinen erzeugten Code schauen
oder ein Update auf 4.5.4, 4.6.2, 4.6.4 oder 4.7.1 machen.
Von 4.6.3 oder 4.7.0 rate ich aus anderen Gründen ab.
Johann L. schrieb:> Frank M. schrieb:>>> Ist also gcc 4.5.1.>> Um PR46779 auszuschliessen, musst du in deinen erzeugten Code schauen> oder ein Update auf 4.5.4, 4.6.2, 4.6.4 oder 4.7.1 machen.
Du verwechselst mich gerade mit dem TO, ich wollte eigentlich nur diese
Info beisteuern ;-)
> Von 4.6.3 oder 4.7.0 rate ich aus anderen Gründen ab.
Hm, ich habe hier auch u.a. die 4.7.0. auf meinem Rechner - auch wenn
ich meist die 4.3.3 (WinAVR20100110) verwende. Könntest Du erläutern,
was an der 4.7.0 zu bemängeln ist? Ist denn die 4.7.1 okay?
Gruß,
Frank
Frank M. schrieb:> Johann L. schrieb:>> Von 4.6.3 oder 4.7.0 rate ich aus anderen Gründen ab.>> Hm, ich habe hier auch u.a. die 4.7.0. auf meinem Rechner - auch wenn> ich meist die 4.3.3 (WinAVR20100110) verwende. Könntest Du erläutern,> was an der 4.7.0 zu bemängeln ist? Ist denn die 4.7.1 okay?
avr-gcc 4.7 hat ein paar neue Features:
- ATXmega Support
- Named Address Spaces wie __flash etc.
- AVR-spezifische Built-Ins wie __buitin_avr_sei()
- 24-Bit Integers
Bei diesen neuen Features gabs ein paar Bugs, die zu falschem Code
führen:
- PR52506, PR52461: ISRs für Xmegas > 64KiB RAM, d.h. mit EBI
- PR53033: wenn man mit memcpy 3 Bytes kopiert (nur Xmega)
- PR52484, PR52507, PR52505: Probleme mit dem 24-Bit Address Space
__memx
- PR51527: Manche binäre Operanden auf __int24 mit Konstanten,
die ausserhalb dem Bereich vom __int24 liegen und nicht auf __int24
gecastet wurden.
- PR53256: Die AVR-Libc enthält Makros für ISR, die Attribut-
Kombinationen verwenden, die nie dokumentiert/spezifiziert waren,
zB eine Funktion gleichzeitig als interrupt und als signal zu
attributieren. Um das zu beheben musste die Semantik von interrupt
und signal im Compiler geändert werden, da es der AVR-Libc nicht
möglich ist, das ISR-Makro anders zu schreiben.
- PR52737: -mtiny-stack wird als Multilib-Option verwendet, was ein
Design-Fehler war. Ab 4.7.1 wird -msp8 als Multilib-Option genommen.
- PR52692: AVR-spezifische Built-Ins funktionieren nicht mit LTO
Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
Groß- und Kleinschreibung verwenden
Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang