atmega32 i czestotliwość pracy...

witam, w swoich walkach z tymze prockiem, doszedłem do problemu, z którym nie potrafie sobie poradzić, i który mnie szczerze zadziwia. otóż, zamontowałem zewnetrzny kwarc 12MHz, odpowiednio ustawilem fusebity , no i myslałem ze teraz juz bede mial stabilny pomiar czasu... no ale lipa - nie jestem w stanie sensownie zaprogramować delay-a. pomijajac rózne pomysły z timerem, z których niewiele mi sie udalo wykrzesać, doszedłem do wniosku ze do pomiaru opóźnień rzedu kilkudziesieciu us, wysatrczy pętla for. no i zrobiłem petle: for(int x=0;x<120;x++); ale niebardzo mi to chcialo to działać, więc postanowilem to przebadać, i wsadziłem to w pętle for(int y=0;y<10000;y++) { for(long int x=0;x<120000;x++); } i okazało się ze czas wykonywania takiej operacji trwa ok 13sek....

o co tu chodzi? nie powinienem raczej przepełniać zmiennych, nie mam pojęcia ile cykli trwa wykonywanie pętli for(long int x=0;x<120000;x++); ale wydaje mi się ze gdyby to był 1 cykl, to wtedy całość powinna trwać jakies 1200000000 cykli a to chyba jest niemozliwe na takim kwarcu w tym czasie ;) powiedzcie co tu jest zle, i ewentualnie jak inaczej sensownie zrobić kontrolowane opoznienie?

Reply to
nuclear
Loading thread data ...

i ewentualnie jak inaczej sensownie zrobić

formatting link

Reply to
Kamillos

Witam,

Dnia 20.02.07 (wtorek), 'Kamillos' napisał(a):

Funkcja _delay_ms jest niezła - kiedyś miałem gotowy prosty program i chciałem dodać tylko opóźnienie, użyłem jej i mi 2kB flasha zabrakło. :) Jak się później okazało (zerknąłem w kod), wykonuje ona zmiennoprzecinkowe operacje na argumencie, a to sporo miejsca zabiera. Może po włączeniu jakiś optymalizacji kompilator (GCC) wrzuciłby gotowe wartości, bo argumenty funkcji były zawsze stałe i takie same...

Reply to
Dykus

Dykus snipped-for-privacy@spamywp.pl pisze:

Dziwne, u mnie wszystko jest ok.

Reply to
Patryk Sielski

nuclear napisał(a):

Zapewne została zoptymalizowana przez kompilator, i tak cud że cokolwiek trwa ;). Jakiego rzędu chcesz robić opóźnienia?

Reply to
Maksymilian Dutka

wymagane czasy to 10-300us, z dokladkoscia kilku us, w sumie to mogłem takm wsadzisć jakąś nic nie robiącą funkcję pod tą pętlą, to by juz chyba nie optymalizował tego ;) no ale teraz doszedłem do wniosku ze zaprzęgnę do tego timer, tylko jeszcze nie udało mi sie tego zrobić. zaożenie ejst takie, ze mam zmienną timer; przerwaniami z timera ją incrementuję, w celu zmierzenia czasu zerję zmienną i czekam az osiagnie wymaganą wartość. no i jakoś mi sie tego jeszczenie udało osiągnąć.. oto co napisałem

long int timer;

///////////////////////////////timer2 ustawienia // wpisanie wartosci koncowej OCR2=60; // ustawienie trybu pracy licznika TCCR2 = 0b00001001; // odblokowanie przerwania od licznika TIMSK = 0b10000000; // globalne odblokowanie przerwań sei(); //////////////////////////timer2 ustawienia end

SIGNAL (SIG_OUTPUT_COMPARE2) { timer++; }

no i po takich założeniach nie przechodzi pętli

while(timer<50000);

wiecie dlaczego tem licznik nie chce ruszyc i dawać przerwań?

Reply to
nuclear

W dniu 20-02-2007 23:03, Dykus napisał:

Się czyta dokumentacje, się wie :-) Bo dokumentacja jasno mówi, że rzeczywiście obliczenia na floatach są, ale tylko wtedy, kiedy optymalizacje ustawione są na o0, czyli żadne. Włączenie któregokolwiek z poziomów dramatycznie redukuje rozmiar kodu wynikowego.

Reply to
Krzysiek

nuclear napisał(a):

Daj volatile przed long int timer;

Ja bym jednak timera nie pchał do tego. Zrób raczej coś w stylu:

void Delay_uS(int us) { for(;us>0;us--) { asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); asm volatile ("nop"); } }

liczbę nop-ów musisz dobrać eksperymentalnie.

Reply to
Maksymilian Dutka

A dlaczego? Zachce mu się zrobić coś na przerwaniach i cały koncept się rozsypie. Poza tym w międzyczasie można robić też inne rzeczy, np

  1. ustaw timer
  2. zrób coś niewielkiego
  3. sprawdź czy już, jak nie, to goto 1

pozdrawiam

majek

Reply to
Marek Wodzinski

Witam,

Dnia 21.02.07 (środa), 'Krzysiek' napisał(a):

Dzięki za informacje. To było moje pierwsze starcie z C na AVR, bardzo prosty układ (na dowolny procek pod ręką) i nawet nie chciało mi się czytać dokumentacji do tych delay-ów, szybciej było zrobić swoje... ;)

Reply to
Dykus

zrobiłem to na timerze, pięknie liczy, dokładnie itp, jest jedno ale - w innym przerwaniu (int1) mam funkcje która wykorzystuje delay-a, w momenicie wyzwolenia tegoż przerwania, cały program ulega zawieszeniu - dobrze wnioskuje ze w trakcie działania int1, przerwanie z licznika nie zostanie obsłużone? czyli jednak zostaje mi zrobić to mniej dokladnie - na nopach?

Reply to
nuclear

Dobrze. Niedobrze, że wykorzystujesz delay w przerwaniu. Przerwanie powinno być jak najkrótsze. Jak potrzebujesz robić jakieś cudactwa, to zastanów się nad tym, żeby tylko w przerwaniu zapamiętać początek liczenia, ustawić flagę, a resztę już zrobić w głównej pętli. Możesz jeszcze odblokować przerwania i pozwolić na przerwanie przerwania, ale wtedy powinieneś mieć jakiś sheduler, bo jak dostaniesz kolejne przerwanie od INT1, to może Ci się wszystko pokiełbasić. Nie wiem co robisz w tym przerwaniu, ale pewnie da się to zrobić bez tego delaya:-)

pozdrawiam

majek

Reply to
Marek Wodzinski

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.