Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 21 kwi 2026, o 03:51


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 5 ] 
Autor Wiadomość
PostNapisane: 27 lip 2016, o 00:36 
Offline
Użytkownik

Dołączył(a): 12 kwi 2014
Posty: 39
Pomógł: 0

Witam,

mam pewien problem, który wydaje mi się banalny, ale nie daje mi spać.

Otóż, utworzyłem sobie funkcję delay_ms_x o ciele:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Ową funkcję wywołuję w pętli, która odpowiedzialna jest za animację a'la "loading" na LCD:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Ciało przerwania Timer'a 2:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Timer2 inicjalizuję na początku funkcji main:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Problem w tym, że raz po raz ten odstęp nie jest równy i co około 3 raz funkcja delay_ms_x kończy swoje instrukcje szybciej niż powinna.
Zmienna arm_bar_dur jest niezmienna. Nawet jak podmieniłem w wywołaniu funkcji argument na wartość liczbową zachowanie jest identyczne.
Proszę, pokażcie mi gdzie popełniam błąd.



Ostatnio edytowano 27 lip 2016, o 18:03 przez JungleMan, łącznie edytowano 1 raz

Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 27 lip 2016, o 00:38 
Offline
Moderator zasłużony dla forum.atnel.pl
Avatar użytkownika

Dołączył(a): 18 lip 2012
Posty: 3230
Lokalizacja: Kraków - obok FAB5 ATMEL'a
Pomógł: 91

topic7402.html

_________________
http://www.jaglarz.info



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 27 lip 2016, o 05:56 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

JungleMan napisał(a):
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Tak naprawdę to ta instrukcja jest równoważna:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Zwróć uwagę, że w tym momencie mikrokontroler porównuje z wartością 0 zmienną dwubajtową modyfikowaną w przerwaniu. Jako że jest to mikrokontroler 8-bitowy, nie zrobi tego w jednym takcie zegara, a między sprawdzaniem poszczególnych bajtów może wystąpić przerwanie, które wprowadzi nową wartość do tej zmiennej i operacja porównania będzie błędna. Możnaby spróbować wprowadzić zmienną pośrednią i zapewnić atomowy dostęp do zmiennej delay_cnt_ms, coś w stylu:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Autor postu otrzymał pochwałę


Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 27 lip 2016, o 18:01 
Offline
Użytkownik

Dołączył(a): 12 kwi 2014
Posty: 39
Pomógł: 0

Ogromne dzięki andrews. Nigdy bym na to nie wpadł.

Rozwiązałem to w następujący sposób:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 28 lip 2016, o 06:08 
Offline
Użytkownik

Dołączył(a): 07 cze 2016
Posty: 563
Pomógł: 143

Takie rozwiązanie też jest OK.

Pozwolę sobie jednak wytłumaczyć, na czym polega różnica między naszymi rozwiązaniami.
W Twoim przypadku akurat prawdopodobnie nie ma to większego znaczenia, ale czasami jest bardzo istotne, aby przerwania blokować na jak najkrótszy okres czasu, szczególnie jeśli korzystamy z większej ilości przerwań i niektóre z nich wymagają natychmiastowej (lub przynajmniej jak najszybszej) reakcji.

Rozwiązanie z dodatkową zmienną ma w takim przypadku przewagę, dlatego że przerwania są zablokowane tylko na czas odczytu/kopiowania zmiennej delay_cnt_ms. W Twoim rozwiązaniu, oprócz odczytu danej z RAM, musi być jeszcze wykonane porównanie zmiennej z wartością 0 i przypisanie wartości do zmiennej exit. To zajmie nieco więcej czasu, a przerwanie, które może w tym czasie nastąpić, będzie musiało zaczekać na obsługę do końca bloku ATOMIC_BLOCK.

Mam nadzieję, że nie potraktujesz tego jako złośliwą krytykę, bo nie to było moim zamiarem ;)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 5 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Majestic-12 [Bot] i 1 gość


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO