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



Teraz jest 13 mar 2025, o 10:04


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 7 ] 
Autor Wiadomość
PostNapisane: 8 mar 2015, o 14:56 
Offline
Nowy

Dołączył(a): 04 sie 2014
Posty: 12
Pomógł: 0

Witam, chciałem dokonać obsługi klawisza bez delay'ów. Wciśnięcie klawisza miało wywoływać zewnętrzne przerwanie, które zezwalało na pracę przerwania wewnętrznego (od Timer0). Oto mój kod:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Wartość binarna zmiennej 'i' ma być wyświetlana na diodach, to działa i jest dobrze- problem jest z obsługą klawisza, a tak właściwie nieumiejętnie posłużyłem się przerwaniami i nie wiem co się dzieje. Otóż po wciśnięciu klawisza nic się nie dzieje. Jeżeli dodam inkrementację i w każdym przerwaniu to stan wzrasta, co jakaś sekundę? Czyli coś nie tak... na dodatek jeżeli trzymam klawisz to inkrementacjna ciągle zachodzi chociaż nie powinna (bo przerwanie zewnętrze wywoływane jest opadającym zboczem).
Może ktoś widzi błąd jaki popełniłem?
Dodam, że procesor to ATmega16 taktowana wewnętrznym zegarem 1MHz (takie polecenie).



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 mar 2015, o 15:46 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 23 wrz 2013
Posty: 162
Lokalizacja: Rbk
Pomógł: 5

A gdzie eliminacja drgań styków klawisza?
Może spróbuj do obsługi klawisza wykorzystać kod z tej strony: http://mirekk36.blogspot.com/2012/10/ob ... w-cd2.html


Pozdrawiam!



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 mar 2015, o 15:50 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 28 lut 2015
Posty: 26
Pomógł: 0

Cytuj:
GIFR &=~ (1<<INT0); // zeruj flagę timera


Do czego służy ta linia?

Kod:
while (1)
        {
                PORTA |= 0x0f;                  // wyzerowanie stanu diod
                PORTA &=~ i;                    // wyświetl wartosc na diodach
        }

Wie Pan jak to działa? I tak używa Pan timera, nie lepiej to tam umieścić? Zdarzenia są tak rzadko, że nie ma co męczyć uC.

Ogólnie to bym proponował Panu zacząć od metody dużo prostszej. Czyli ustawienie timera w tryb CTC, przerwanie co około 10ms. Co te 10ms porównywać stan klawisza ze stanem poprzednim, jeśli będzie inny, to rozpocząć zliczanie do 50ms i dopiero wtedy sygnalizować zmianę stanu przycisku. Koncepcyjnie dość proste.


Ds3 napisał(a):
A gdzie eliminacja drgań styków klawisza?
Może spróbuj do obsługi klawisza wykorzystać kod z tej strony: http://mirekk36.blogspot.com/2012/10/ob ... w-cd2.html


Pozdrawiam!

To tam akurat jest zaszyte. Proszę zerknąć w przerwanie timera.



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 mar 2015, o 16:06 

Pomógł: 0

Tak na szybko:
1. Bity "ISC10" i "ISC11" dotyczą przerwania INT1 nie INT0.
2. W rejestrze GIFR nie ma bitu INT0.
3. Flaga przerwania czyści się "z automatu" po wejściu w jego obsługę. Gdybyś z jakiś względów potrzebował zrobić to "ręcznie" to zerowanie następuje po wpisaniu jedynki.
4. Najpierw skonfiguruj wejście PD potem włącz przerwanie zewnętrzne.
5. Wyłączanie timera, włączanie INT0 i zerowanie flagi powinno być chyba poza wyrażeniem warunkowym związanym z PIND (w przerwaniu timera). Wydaje mi się, że miałoby to wtedy "większe" ręce i nogi.

@Ds3 - jak to gdzie? Może trochę pokręcona ale jak najbardziej jest (oparta o przerwanie timera).


Autor postu otrzymał pochwałę


Góra
  
cytowanie selektywne  Cytuj  
PostNapisane: 8 mar 2015, o 17:39 
Offline
Nowy

Dołączył(a): 04 sie 2014
Posty: 12
Pomógł: 0

Dziękuję za bieżące podpowiedzi, jednak ciągle program nie działa jak należy- poprawiłem błędy wskazane przez wwojtek, jednak ciągle coś nie tak. Myślę, że problem jest w przerwaniach od timer0, ponieważ jeżeli wrzucę zmianę diody w przerwaniu to dioda miga co jakąś sekundę- a z mojej logiki: 1MHz z procka / 1024 z preskalera to jakieś 0,001 sekundy.... przez to , że nie zlicza czasu nie inkrementuje zmiennej flag, i program nie rusza. Gdzie może być błąd? Źle policzyłem czas wywołania przerwania?



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 8 mar 2015, o 17:53 

Pomógł: 0

elerbe napisał(a):
jeżeli wrzucę zmianę diody w przerwaniu to dioda miga co jakąś sekundę
A nie "wrzucasz" czasem wewnątrz warunku ze zmienną "flag"? Wtedy by pasowało :)



Góra
  
cytowanie selektywne  Cytuj  
PostNapisane: 8 mar 2015, o 17:58 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 28 lut 2015
Posty: 26
Pomógł: 0

elerbe napisał(a):
Dziękuję za bieżące podpowiedzi, jednak ciągle program nie działa jak należy- poprawiłem błędy wskazane przez wwojtek, jednak ciągle coś nie tak. Myślę, że problem jest w przerwaniach od timer0, ponieważ jeżeli wrzucę zmianę diody w przerwaniu to dioda miga co jakąś sekundę- a z mojej logiki: 1MHz z procka / 1024 z preskalera to jakieś 0,001 sekundy.... przez to , że nie zlicza czasu nie inkrementuje zmiennej flag, i program nie rusza. Gdzie może być błąd? Źle policzyłem czas wywołania przerwania?


Procesor wchodzi w przerwanie z częstotliwościę 1Mhz/1024(prescaler)/256, czyli jakieś 4Hz.



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

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:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO