Skocz do zawartości

[C] Funkcja _delay_us() nie działa poprawnie


Mateusz

Pomocna odpowiedź

Witam.

Mam problem z funkcją _delay_us po napisaniu takiego kodu:

ISR(TIMER0_OVF_vect )
{
SetBit(PORTB,0);
_delay_us(20);
ClrBit(PORTB,0);
TCNT0 = 255-125;
}

Na wyjściu portu 0 ten pik ma szerokość 50ms. Nie potrafię zrozumieć dla czego. Mam zdefiniowany F_CPU

#define F_CPU 8000000UL
#include "ppm.h"
#include <util/delay.h>

Mikrokontroler atmega8L z wewn rezonatorem na 8MHz. Fuse bity L: C4 H: D9.

Link do komentarza
Share on other sites

Przerwanie wykonuje się minimalnie co 1ms. I wiem, że nie powinno się dawać delay w przerwaniu jednak gdyby tutaj zrobił to inaczej skomplikowałoby to kod.

------ Rebuild All started: Project: HeadSens, Configuration: Debug AVR ------

Build started.

Project "HeadSens.avrgccproj" (ReBuild target(s)):

Target "PreBuildEvent" skipped, due to false condition; ('$(PreBuildEvent)'!='') was evaluated as (''!='').

Target "CoreRebuild" in file "C:\Program Files (x86)\Atmel\AVR Studio 5.0\Vs\AvrGCC.targets" from project "D:\programowanie AVR\programy\HeadSens\HeadSens\HeadSens.avrgccproj" (target "ReBuild" depends on it):

Task "RunAvrGCC"

C:\Program Files (x86)\Atmel\AVR Studio 5.0\AVR ToolChain\bin\make.exe clean all

rm -rf atm8_comm/twimaster.o atm8_comm/UART_ATM8.o HeadSens.o hmc5883l.o mma7455l.o ppm.o atm8_comm/twimaster.d atm8_comm/UART_ATM8.d HeadSens.d hmc5883l.d mma7455l.d ppm.d libHeadSens.a HeadSens.hex HeadSens.eep HeadSens.lss HeadSens.map

twimaster.c

Invoking: AVR/GNU C Compiler

"C:/Program Files (x86)/Atmel/AVR Studio 5.0/AVR ToolChain/bin/avr-gcc.exe" -funsigned-char -funsigned-bitfields -O0 -fpack-struct -fshort-enums -g2 -Wall -c -std=gnu99 -mmcu=atmega8 -MD -MP -MF"atm8_comm/twimaster.d" -MT"atm8_comm/twimaster.d" -o"atm8_comm/twimaster.o" "../atm8_comm/twimaster.c"

Finished building: ../atm8_comm/twimaster.c

UART_ATM8.c

Invoking: AVR/GNU C Compiler

"C:/Program Files (x86)/Atmel/AVR Studio 5.0/AVR ToolChain/bin/avr-gcc.exe" -funsigned-char -funsigned-bitfields -O0 -fpack-struct -fshort-enums -g2 -Wall -c -std=gnu99 -mmcu=atmega8 -MD -MP -MF"atm8_comm/UART_ATM8.d" -MT"atm8_comm/UART_ATM8.d" -o"atm8_comm/UART_ATM8.o" "../atm8_comm/UART_ATM8.c"

Finished building: ../atm8_comm/UART_ATM8.c

HeadSens.c

Invoking: AVR/GNU C Compiler

"C:/Program Files (x86)/Atmel/AVR Studio 5.0/AVR ToolChain/bin/avr-gcc.exe" -funsigned-char -funsigned-bitfields -O0 -fpack-struct -fshort-enums -g2 -Wall -c -std=gnu99 -mmcu=atmega8 -MD -MP -MF"HeadSens.d" -MT"HeadSens.d" -o"HeadSens.o" ".././HeadSens.c"

In file included from .././HeadSens.c:10:0:

c:\program files (x86)\atmel\avr studio 5.0\avr toolchain\bin\../lib/gcc/avr/4.5.1/../../../../avr/include/util/delay.h(94,3): #warning "Compiler optimizations disabled; functions from won't work as designed"

.././HeadSens.c: In function 'main':

D:\programowanie AVR\programy\HeadSens\HeadSens\HeadSens.c(22,7): unused variable 'buf'

Finished building: .././HeadSens.c

hmc5883l.c

Invoking: AVR/GNU C Compiler

"C:/Program Files (x86)/Atmel/AVR Studio 5.0/AVR ToolChain/bin/avr-gcc.exe" -funsigned-char -funsigned-bitfields -O0 -fpack-struct -fshort-enums -g2 -Wall -c -std=gnu99 -mmcu=atmega8 -MD -MP -MF"hmc5883l.d" -MT"hmc5883l.d" -o"hmc5883l.o" ".././hmc5883l.c"

.././hmc5883l.c: In function 'HMC5883L_init':

D:\programowanie AVR\programy\HeadSens\HeadSens\hmc5883l.c(13,2): implicit declaration of function 'i2c'

.././hmc5883l.c: In function 'getHeadingHMC':

D:\programowanie AVR\programy\HeadSens\HeadSens\hmc5883l.c(35,2): implicit declaration of function 'i2c'

.././mma7455l.c: In function 'getHeadingMMA':

D:\programowanie AVR\programy\HeadSens\HeadSens\mma7455l.c(24,2): implicit declaration of function 'i2c_rep' D:\programowanie AVR\programy\HeadSens\HeadSens\hmc5883l.c 16 2 HeadSens

Warning 6 implicit declaration of function 'i2c' D:\programowanie AVR\programy\HeadSens\HeadSens\mma7455l.c 15 2 HeadSens

Warning 13 implicit declaration of function 'i2c_rep_start' D:\programowanie AVR\programy\HeadSens\HeadSens\mma7455l.c 24 2 HeadSens

Warning 14 implicit declaration of function 'i2c_readAck' D:\programowanie AVR\programy\HeadSens\HeadSens\mma7455l.c 25 2 HeadSens

Warning 15 #warning "Compiler optimizations disabled; functions from won't work as designed" c:\program files (x86)\atmel\avr studio 5.0\avr toolchain\bin\../lib/gcc/avr/4.5.1/../../../../avr/include/util/delay.h 94 3 HeadSens

A tak btw. co oznacza: implicit declaration? Rozumiem znaczenie jeżeli chodzi o ang 🙂 ale nie rozumiem o co chodzi 😃.

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Tak właśnie myślełem - lekceważysz warningi stojąc na 10 stopniu: Piekła Początkujących

... zaglądnij na ten stopień, by czasu nie tracić.

A wystarczy przeczytać:

Warning 1 #warning "Compiler optimizations disabled; functions from won't work as designed" c:\program files (x86)\atmel\avr studio 5.0\avr toolchain\bin\../lib/gcc/avr/4.5.1/../../../../avr/include/util/delay.h

Po kompilacji masz mieć 0 warningów - inaczej nie bierz się na C.

Link do komentarza
Share on other sites

implicit declaration niejawna deklaracja funkcji. Prawdopodobnie w pliku #include "ppm.h" nie ma deklaracji funkcji której używasz. Nie wiem czy dobrze zrozumiałem twoją wypowiedz ale jeśli chcesz obsługiwać przerwanie co 1ms i dawać w nim opóźnienie 20ms to nie ma prawa działać poprawnie.

Link do komentarza
Share on other sites

Nie wiem czy dobrze zrozumiałem twoją wypowiedz ale jeśli chcesz obsługiwać przerwanie co 1ms i dawać w nim opóźnienie 20ms to nie ma prawa działać poprawnie.

Daje 20µs, a nie 20ms, więc od biedy może być - robi to świadomie, więc nie ma problemu.

ISR(TIMER0_OVF_vect ) 
{ 
   SetBit(PORTB,0); 
   _delay_us(20); 
   ClrBit(PORTB,0); 
   TCNT0 = 255-125; 
}
Link do komentarza
Share on other sites

Tak właśnie myślełem - lekceważysz warningi stojąc na 10 stopniu: Piekła Początkujących

... zaglądnij na ten stopień, by czasu nie tracić.

A wystarczy przeczytać:

Warning 1 #warning "Compiler optimizations disabled; functions from won't work as designed" c:\program files (x86)\atmel\avr studio 5.0\avr toolchain\bin\../lib/gcc/avr/4.5.1/../../../../avr/include/util/delay.h

Po kompilacji masz mieć 0 warningów - inaczej nie bierz się na C.

Czytałem na temat tego warninga ale na necie pisali, że zawsze się pojawia. Do tego kod po optymalizacji dużo więcej waży a ja nie mogę sobie na to pozwolić. Ten warning wprowadza bardzo mały błąd.

For a delay of 300 ms the delay is close to 5% longer (13 ms) without optimization, and a trivial test program grows from 136 byte of flash to 3146 bytes..
Link do komentarza
Share on other sites

Czytałem na temat tego warninga ale na necie pisali, że zawsze się pojawia.

Do tego kod po optymalizacji dużo więcej waży a ja nie mogę sobie na to pozwolić.

Hmm, jak by to napisać żeby Ciebie nie urazić?

Może tak:

1. zobacz stopień 7 Piekiełka.

2. od kiedy włączenie optymalizacji zwiększa długość kodu? Po to jest optymalizacja, by właśnie kod skrócić. Oczywiście mogą być jakieś specyficzne przypadki ...

Musisz zdecydować, komu zaufać, datasheetom uC i manualowi GCC, czy zasłyszanym informacjom.

Mnie martwi jednak coś innego. To że wcześniej piszesz, iż wiesz, że przerwanie z delay jest nie teges, a teraz wychodzi na to, że to nie tylko testy ale ważny element całości Twojego projektu. Jeżeli tak, to zmień podejście do programowania, bo będziesz miał kłopoty szybciej niż sądzisz.

Powodzenia w Piekiełku!

Link do komentarza
Share on other sites

Ok przyznaje się do błędu. Po włączeniu optymalizacji a AVR studio kod zajmuje duuużo mniej miejsca 🙂 i delay_us działa poprawnie.

No i przerobiłem kod tak żeby delaya nie było w przerwaniu 😉

A skoro już o optymalizacji to czy ktoś wie czym różnią się optymalizacje 01, 02, 03, 0s?

0s - jest do optymalizacji przestrzeni kodu.

a reszta ?

Czemu tego nie używa się zawsze?

Link do komentarza
Share on other sites

Ok przyznaje się do błędu. Po włączeniu optymalizacji a AVR studio kod zajmuje duuużo mniej miejsca 🙂 i delay_us działa poprawnie.

No i przerobiłem kod tak żeby delaya nie było w przerwaniu 😉

Oby tak wszyscy szybko z piekiełka uciekali, to byśmy mniej klawisze zużywali 🙂

A skoro już o optymalizacji to czy ktoś wie czym różnią się optymalizacje 01, 02, 03, 0s?

0s - jest do optymalizacji przestrzeni kodu.

a reszta ?

Czemu tego nie używa się zawsze?

Manual GCC rodział: 3.10 Options That Control Optimization

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.