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



Teraz jest 30 mar 2026, o 04:26


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 10 ] 
Autor Wiadomość
PostNapisane: 3 sie 2015, o 11:28 
Offline
Nowy

Dołączył(a): 16 gru 2014
Posty: 8
Pomógł: 0

Witam na forum

Piszę w ramach wprawki prostą bibliotekę modbus (ATMEGA 8), i mam dwa pytanka :
- w celu ułatwienia dostępu do struktury w której trzymam ramkę odebraną/do nadania używam wielopoziomowej unii. Czy taka konstrukcja jakoś bardzo pogarsza wydajność programu?

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





- w przerwaniu generowanym po odbiorze danej przez UART, przy pierwszej danej odebranej ustawiam parametry dla TIMER0 tak aby generował przerwanie po około 3ms, jeśli nie wykonam kasowania (wpisanie 1) rejestru TIFR |= (1<<TOV0) to według objawów działania programu po pierwszym odebranym znaku generowane jest przerwanie TIMER0, następne znaki odbierane są już poprawnie, po wykonani kasowania flagi TOV0 (jak w poniższym kodzie) działa dobrze. Nie znalazłem w datasheeet do A8 żadnej informacji która naprowadziłaby mnie skąd bierze się ten problem, ale w niektórych rozwiązaniach w necie kasowanie TOV0 jest również stosowane, w programie nie wykorzystuje poza tym innych timerów.
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


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




i makra

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



pozdrawiam Jurek



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 sie 2015, o 13:21 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27450
Lokalizacja: Szczecin
Pomógł: 1045

roll99 napisał(a):
Czy taka konstrukcja jakoś bardzo pogarsza wydajność programu?

Wręcz przeciwnie - to jest WZORCOWE PODEJŚCIE ;) aż się miło patrzy. Tzn mówię o takim zastosowaniu unii i struktur - nie wnikam w stronę merytoryczną.

roll99 napisał(a):
TIFR |= (1<<TOV0)

UWAGA! tak się nie kasuje flag przerwań - KONIECZNIE napisz to tak:

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

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 sie 2015, o 13:31 
Offline
Nowy

Dołączył(a): 16 gru 2014
Posty: 8
Pomógł: 0

Dziękuje :) za pochwałę Mistrza (nie ironicznie ;) )dotyczącą unii - prace trwają więc sprawa rozwojowa :) .

a co jest złe w zapisie ?
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


czy nie ustawi to flagi TOV0 na jeden, wiem że nie można zapisać do rejestru TIFR zera (przynajmniej w ATMEGA 8) i pewnie zapis TIFR = (1<<TOV0) nie ustawi pozostałych flag na zero.

pozdrawiam Jurek



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 sie 2015, o 13:37 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27450
Lokalizacja: Szczecin
Pomógł: 1045

Sam do niedawna często zapominałem o tym i pisałem bodajże nawet w książce kasowanie flag przerwań z tym OR ... ale to akurat w tym przypadku jest niestety błędne :(

tu: http://www.atmel.com/webdoc/AVRLibcRefe ... tbits.html masz dokładniejsze wyjaśnienie

------------------------ [ Dodano po: 26 minutach ]

roll99 napisał(a):
(przynajmniej w ATMEGA 8)

w KAŻDYM AVR przy kasowaniu flag przerwań

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 sie 2015, o 14:07 
Offline
Nowy

Dołączył(a): 16 gru 2014
Posty: 8
Pomógł: 0

No tak jak pisałem, obie metody są OK, Twoja o jedną instrukcję wydajniejsza, bardziej interesuje mnie dlaczego jak nie wyzeruję tej flagi to po odebraniu pierwszego znaku odpala mi przerwanie od przepełnienia TIMER0 :(, długo nad tym siedziałem - efekt był taki ze slave odpowiadał dwiema ramkami raz po pierwszym znaku a drugi raz po reszcie odebranej ramki (ramki odbiorczej nie analizowałem tylko sprawdzałem czy cos zostało odebrane czyli czy przerwanie od TIMER0 zostało odpalone a flaga stanu ustawiona na MB_DONE_RX a ustawiała się ona tylko w procedurze obsługi TIMER0 po przepełnieniu czyli po upływie 3-4 ms od odbioru ostatniego znaku.

pozdrawiam Jurek



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 sie 2015, o 14:23 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27450
Lokalizacja: Szczecin
Pomógł: 1045

mirekk36 napisał(a):
No tak jak pisałem, obie metody są OK, Twoja o jedną instrukcję wydajniejsza,

Widzę, że niedokładnie przeczytałeś link który ci podałem bo tu w ogóle nie chodzi o wydajność (oszczędność instrukcji)

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 sie 2015, o 14:40 
Offline
Nowy

Dołączył(a): 16 gru 2014
Posty: 8
Pomógł: 0

mirekk36 napisał(a):
Widzę, że niedokładnie przeczytałeś link który ci podałem bo tu w ogóle nie chodzi o wydajność (oszczędność instrukcji)


No tak ale poza tym OR (plus odczyt stanu poprzedniego) różnicy w efekcie i ewentualnych działaniach ubocznych nie ma - chyba że źle czytam.
Cytuj:
... so there is no risk of any race condition that might accidentally clear another interrupt request bit. So instead of writing TIFR |= _BV(TOV0); /* wrong! */ simply use TIFR = _BV(TOV0);

pozr Jurek



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 sie 2015, o 15:15 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27450
Lokalizacja: Szczecin
Pomógł: 1045

roll99 napisał(a):
chyba że źle czytam.

Źle czytasz i kompletnie nie rozumiem po co się upierasz .... Tym bardziej, że sam producent procków tobie to pisze...

Robiąc operację OR możesz niechcący kasować inne flagi przerwań w tym samym rejestrze

a ten cytat z "so there is no risk" odnosi się właśnie do = a nie do |=

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 sie 2015, o 15:29 
Offline
Nowy

Dołączył(a): 16 gru 2014
Posty: 8
Pomógł: 0

OK masz rację ...
pozdr Jurek



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 3 sie 2015, o 22:44 
Offline
Nowy

Dołączył(a): 16 gru 2014
Posty: 8
Pomógł: 0

Problem polegał na tym że inicjalizowałem tzn. ustawiałem źródło i podział dla TIMER0 w programie głównym, i od tego momentu rozpoczynało się zliczanie przepełniając pewnie wiele razy TIMER0 co powodowało ustawienie flagi TOV0 w rejestrze TIFR. W obsłudze przerwania odbioru znaku tylko ustawiałem licznik na wartość początkową i włączałem przerwanie od przepełnienia TIMER0 i w tym momencie następował obsługa przerwania (bo wcześniej była ustawiona flaga TOV0). Dalsze znaki odbierane były jakby w "drugiej paczce" bo od tego momentu TIMER0 już był opanowany i liczył tak jak zakładałem. Wyjście to wyzerowanie flagi TOV0 w TIFR oczywiście TIFR = (1<<TOV0) - jak poprawił mnie mirek36, lub inicjalizacja TIMER0 każdorazowo w przerwaniu po odbiorze pierwszego znaku oraz wyłączenie przerwania od TIMER0 i stopowanie licznika - "odłączenie od źródła impulsów" i ustawienie na wartość początkową po wystąpieniu przerwania od TIMER0. Pierwszy sposób łatwiejszy i krótszy.
Inicjalizacja parametrów TIMERA w programie głównym w wielu innych przypadkach może nie wpływać na dziwne zachowanie się programu (jedna więcej pętla obsługi zdarzeń itp.) tu jednak był dość duży reżim jeśli chodzi o poprawną jego pracę.
pozdr Jurek
temat można zamknąć



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: 10 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników 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:  
cron
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO