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



Teraz jest 25 cze 2026, o 21:06


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 14 ] 
Autor Wiadomość
PostNapisane: 24 lis 2016, o 20:26 
Offline
Nowy

Dołączył(a): 20 paź 2016
Posty: 20
Pomógł: 0

Panowie (a może też panie),

czy jest taka szansa, aby uC wchodził mi do procedury przerwania ISR(TIM0_COMPA_vect)
mimo że TCNT0 nie osiągnął wartości wpisanej do OCR0A?

Czy ja o czymś nie wiem?

Tak mi się dzieje w Proteusie, przy Attiny 13, w debugerze.

Pozdrawiam
KK



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 25 lis 2016, o 13:40 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 26 mar 2014
Posty: 356
Lokalizacja: Pruszków
Pomógł: 15

Może nie włączyłeś trybu CTC i przerwanie dostajesz z przepełnienia.

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


U mnie po takim ustawieniu timera przerwanie działa prawidłowo.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 25 lis 2016, o 17:11 
Offline
Nowy

Dołączył(a): 20 paź 2016
Posty: 20
Pomógł: 0

Robie tak samo, potem debugguje dalej...a procek wchodzi mi do ISR(TIM0_COMPA_vect) przy TCNT0 = 0 :O



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 25 lis 2016, o 20:17 
Offline
Użytkownik

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

krzysiekk napisał(a):
...a procek wchodzi mi do ISR(TIM0_COMPA_vect) przy TCNT0 = 0


A jakiej wartości TCNT0 się spodziewasz? Przecież w trybie CTC w momencie ustawienia flagi przerwania od porównania OCF0A jednocześnie jest zerowany rejestr TCNT0.

Spójrz do noty katalogowej na rysunek 11-11 na stronie 69 to zrozumiesz, dlaczego w momencie wejścia w procedurę obsługi przerwania rejestr TCNT0 musi być równy 0.

Możesz spróbować ustawić przerwanie od porównania z OCR0B (oczywiście ustawiając wcześniej wartość tego rejestru na wartość mniejszą od OCR0A). Wtedy po wejściu do procedury obsługi przerwania wartość TCNT0 będzie o 1 wyższa od wartości OCR0B.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 25 lis 2016, o 21:44 
Offline
Nowy

Dołączył(a): 20 paź 2016
Posty: 20
Pomógł: 0

Ok, ale gdy nie ustawie trybu CTC, to nie powinno mi zerowac timera i po wejsciu w procedure obslugi tego przerwania TCNT0 powinno miec wartość o 1 większa niż OCR0A. Czy to sie zgadza?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 25 lis 2016, o 22:23 
Offline
Użytkownik

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

Mogą się zdarzyć sytuacje, gdy tak nie będzie, ale za dużo pisania, żeby to wytłumaczyć, a bez kodu trudno zgadywać przyczynę zachowania symulatora, które opisałeś (w dodatku niezbyt dokładnie).

Nie mam tutaj zamiaru bronić Proteusa. Nie znam tego programu i nie wiem, na ile poprawnie symuluje mikrokontrolery AVR. Ja tylko próbuję skorygować Twój tok rozumowania ;)



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 lis 2016, o 12:55 
Offline
Nowy

Dołączył(a): 20 paź 2016
Posty: 20
Pomógł: 0

Pytam tak lakonicznie, ponieważ być może nie wiem o czymś, co jest w jakiś tam sposób naturalne.
Co do Proteusa...to ogolnie jakis dziwny jest ten symulator. Teraz na przykład ni stad ni zowąd wraca mi z procedury przerwania do main() i wykonuje
tam instrukcje inicjalizacyjne, jakby został reset wywołany. A w progranie nigdzie nie dałem żadnego resetu. Gdy natomiast wchodze do sumulatora w trybie
dissassembly,to symulacja nie wychodzi mi do main(). Nic już nie rozumiem, a poziom frustracji rośnie.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 lis 2016, o 14:51 
Offline
Użytkownik

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

krzysiekk napisał(a):
Pytam tak lakonicznie, ponieważ być może nie wiem o czymś, co jest w jakiś tam sposób naturalne.

To co opisujesz nie jest oczywiście naturalne. Nie musi jednak wynikać z błędnej symulacji, lecz np. ze źle napisanego kodu. Przykładowo ten mikrokontroler ma stosunkowo mało pamięci RAM, więc łatwo doprowadzić do sytuacji, kiedy dane programu nadpisują stos. A na stosie są przecież między innymi adresy powrotu z funkcji czy też z procedury obsługi przerwania i wtedy mogą się dziać różne dziwne rzeczy.

Możemy sobie tutaj tak gdybać nie wiadomo jak długo bez skutku, jednak myślę, że raczej nikt Ci nie pomoże znaleźć przyczyny problemów, dopóki nie przedstawisz kodu.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 lis 2016, o 17:09 
Offline
Nowy

Dołączył(a): 20 paź 2016
Posty: 20
Pomógł: 0

Robie teraz podejscie z symulatorem Atmel Studio i jego stimulifile do debuggera. A kod...

Program jest odbiornikiem kodu manchester. Kod napisałem sam, bez posiłkowania się
książkami, stad pewnie niestandardowo to robię i pewnie niejednokrotnie wyważam otwarte już przez innych drzwi, popełniając przy tym liczne błędy. Odbiornik ten ma docelowo służyć do komunikacji radiowej, na razie jednak w proteusie symulacje robie tak, że jeden uC podłączony jest wyjściem do wejścia INT0 (PB1) drugiego uC, którego kod jest poniżej. Jak odbierze poprawną daną, ma zaświecić diodę.


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: 26 lis 2016, o 19:32 
Offline
Nowy

Dołączył(a): 20 paź 2016
Posty: 20
Pomógł: 0

Znalazlem przyczyną, dlaczego wychodzil mi do main(). Pracowałem nad inną wersją kodu i miałem
ustawione to tak, że włączone było przerwanie od rejestru A, a wektor procedury przerwania
byl ISR(TIM0_COMPB_vect) ... wersja kodu powyżej nie ma tego błędu.

Wychodzenie do main już jest naprawione, natomiast wciaż nie moge odnaleźć przyczyny,
dlaczego wywołuje mi się przerwanie ISR(TIM0_COMPA_vect) mimo że nie TCNT0 osiąga
wartości wpisanej do rejestru OCR0A...



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 26 lis 2016, o 19:33 
Offline
Użytkownik

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

Nie analizowałem dokładnie kodu, jednak na początek miałbym taką uwagę.

Zauważyłem, że wyłączasz przerwania, po czym ponownie je włączasz.

Po pierwsze we funkcji przerwania_wylacz() robisz to niepoprawnie (powinno być & zamiast |). Poza tym dla uzyskania większej czytelności lepiej zrobić 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.

Wtedy nie ma wątpliwości jaki bit ustawiasz czy też zerujesz.

Po drugie, wyłączenie przerwań jest często błędnie interpretowane. Ustawienie czy też zerowanie (akurat w tym przypadku) bitu OCIE0B w rejestrze TIMSK0 oznacza tylko wyłączenie zezwolenia na przerwanie. Timer cały czas zlicza impulsy (TCNT0) i kiedy jego wartość zrówna się z wartością rejestru OCR0B zostanie ustawiona flaga OCF0B w rejestrze TIFR0. W tej sytuacji procedura obsługi przerwania nie zostanie uruchomiona, ponieważ zezwolenie jest wyłączone, jednak flaga jest ustawiona i zostaje zapamiętana. Kiedy ponownie włączysz zezwolenie na to przerwanie (OCIE0B w TIMSK0), procedura jego obsługi zostaje natychmiast uruchomiona niezależnie od aktualnego stanu licznika TCNT0, bo przecież flaga została już ustawiona wcześniej.

Flaga zostaje wyzerowana dopiero wtedy, gdy przerwanie zostanie obsłużone (przez procedurę obsługi) lub gdy wyzerujemy ją programowo. Ewentualnym rozwiązaniem wydawałoby się może wyłączenie zliczania przez licznik (by uniknąć ustawienia flagi), ale to i tak nie zawsze zagwarantuje, że flaga nie zostanie ustawiona. Dlatego moim zdaniem lepszym rozwiązaniem (przynajmniej w tym przypadku) jest programowe zerowanie flagi tuż przed zezwoleniem na przerwanie:
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: 26 lis 2016, o 20:05 
Offline
Nowy

Dołączył(a): 20 paź 2016
Posty: 20
Pomógł: 0

Rewelacja!!!! Serdecznie Ci dziękuję.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 27 lis 2016, o 20:31 
Offline
Nowy

Dołączył(a): 20 paź 2016
Posty: 20
Pomógł: 0

No i zrobiłem, na symulatorze proteusa dziala dobrze. Tzn nadajnik i odbiornik komunikują się
ze sobą. Po nadaniu paczki danych przez nadajnik, odbiornik odczytuje je, porównuje z wartością wpisaną w odbiornik i przełącza diodę na stan przeciwny. Po załadowaniu natomiast wsadów do
realnych układów, tzn nadajnika i odbiornika i po połączeniu ich - na razie - przewodem sygnałowym i masą układ odbiornika nie przełącza diody. Niestety nie jestem w stanie w warunkach domowych sprawdzić poprawności wysyłanej ramki danych, bo nie mam oscyloskopu...więc puki co nic nie ruszę dalej :/



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 29 lis 2016, o 20:22 
Offline
Nowy

Dołączył(a): 20 paź 2016
Posty: 20
Pomógł: 0

Koledzy, walczę dalej z tym odbiornikiem Manchester. Sprawdziłem na oscyloskopie - nadajnik nadaje poprawnie. Na symulatorze proteusa działa dobrze nadawanie i odbieranie. Dioda w while() przełącza się. Natomiast na rzeczywistym układzie nie działa. Gdzieś jest jakiś babol. Tylko gdzie. Mam wrażenie, że procesor sie zawiesza, bo wstawiając przełączanie diody w kod przerwania od INT0 albo w kod przerwania od porownania z OCR0A dioda zaswieca sie, przy nastepnych ramkach danych już świeci i ani mrugnie.

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  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 14 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 2 gości


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