Mikrokontrolery - Jak zacząć?

... czyli zbiór praktycznej wiedzy dot. mikrokontrolerów.

czwartek, 3 marca 2011

EPP: Eliminacja drgań styków by omicronNs

Autor: omicronNs
Redakcja: dondu


Tematem dot. zadania eliminacji drgań styków klawiatury.


Eliminacja drgań styków przycisków mechanicznych, generalnie polega na odczytaniu stanu przycisku, a następnie odczytaniu go ponownie po pewnym czasie ok 5-20ms, jak to ma miejsce w przykładzie z zadania.


Jednak taka realizacja eliminacji drgań styków ma podstawową wadę – program staje w miejscu (pętli oczekującej) na te kilka - kilkanaście milisekund, a dla mikrokontrolera to wieczność (przy taktowaniu 8MHz daje to 40.000-160.000 zmarnowanych cykli procesora!). Dlatego należy podejść do problemu z trochę innej perspektywy.


Układ testowy zaprojektowałem tak:


Plik Eagle: schemat.zip 

Procesor Atmega8 wyposażony jest w sprzętowy 8-bitowy timer/counter Timer0. Można go z powodzeniem wykorzystać do naszego celu. Użyjemy przerwanie od przepełnienia tego licznika, w którym:
  1. sprawdzimy stan pinów z przyciskami, 
  2. w następnym przerwaniu wpiszemy je do zmiennej stan_przyciskow, ale tylko wtedy, gdy aktualny stan pinów jest taki sam jak poprzedni, 
  3. w przeciwnym wypadku wartość zmiennej  stan_przyciskow pozostanie nietknięta.

W efekcie zmienna stan_przyciskow zawsze zawiera aktualną informację nt. wciśniętych przycisków, ale ignorowane są szybkie zmiany ich stanów, które mogłyby zakłócić pracę pozostałej części programu.

W tym przykładzie timer0 pracuje z 256-krotnym prescalerem, co daje przerwanie co ok. 8ms:


więc opóźnienie między zmianą stanu pinu, a uaktualnieniem zmiennej stan_przyciskow będzie zawierać się w granicach 8-16ms, w zależności od tego, w którym momencie nastąpi rzeczywista zmiana logicznego stanu pinu.

Efekt końcowy jest taki, że czas jaki procesor wykorzystuje na obsługę pinów spadł do wartości 5,5us (44cykle) jest to zmiana o 99,945% w stosunku do opóźnienia programowego, a sam algorytm wykonuje się w tle i możemy o niej zapomnieć.
/*
* Data:                 18.02.2012
* Autor:                omicronNs
* E-Mail:               omicronns[maupa]gmail.com
* Opracowano dla:       http://mikrokontrolery.blogspot.com 
* Tytuł:                Szkielet programu z zaimplementowaną eliminacją drgań
*                       styków przycisków
* Procesor:             Atmega8
* F_CPU:                8MHz
*
* Przyciski podłączone do portu B piny PB0-PB3 (4 przyciski)
*/



#include <avr/io.h>
#include <avr/interrupt.h>


volatile uint8_t stan_przyciskow;

ISR(TIMER0_OVF_vect)
{
  static uint8_t stan_przyciskow_stary = 0, stan_przyciskow_nowy;

  //Pobranie stanu przycisków, i wpisanie do zmiennej
  //stan_przyciskow_nowy w taki sposób, że 1 oznacza wciśnięty
  //ponieważ przyciski zwierają do masy (GND) należy odwrócić odczytaną
  //wartość z portu gdzie przyciski są podłączone
  stan_przyciskow_nowy = (~PINB & 0b00001111);

  //jeżeli stan przycisków jest taki sam jak poprzednio
  if(stan_przyciskow_stary == stan_przyciskow_nowy)
     stan_przyciskow = stan_przyciskow_nowy;   //to aktualizuj zmienną glonalną
  
  //zapamietaj nowy stan
  stan_przyciskow_stary = stan_przyciskow_nowy;
}

int main(void)
{
  //Konfiguracja pinów
  DDRB = 0b11110000;
  PORTB = 0xff;

  //Uruchomienie timera0, odblokowanie przerwań
  TCCR0 |= (1<<CS02);
  TIMSK |= (1<<TOIE0);
  sei();

  //pętla główna
  while(1)
  {
     //Tutaj Twój program
  }
}
Projekt AVR Studio z plikiem C: drgania.zip 

Komentarz Dondu:
To jeden z najprostszych i skutecznych algorytmów eliminacji drgań styków, który dodatkowo charakteryzuje się krótkim kodem wynikowym. Jego stosowanie polecam w szczególności początkującym, ze względu na jego nieskomplikowany kod ułatwiający zrozumienie jego działania.

Zobacz inne rozwiązania problemu drgań styków:

Oceń artykuł.
Wasze opinie są dla nas ważne, gdyż pozwalają dopracować poszczególne artykuły.
Pozdrawiamy, Autorzy
Ten artykuł oceniam na:

6 komentarzy:

  1. Jak będzie wyglądał taki kod dla bascoma?

    OdpowiedzUsuń
  2. Niestety tego na blogu nie znajdziesz, bo tutaj tylko język C.
    Pytaj na Elektrodzie

    OdpowiedzUsuń
  3. Co zrobić jeśli chciałbym przy wciśnięciu dowolnego przycisku np. zwiększyć zmienną a o 1. Jeśli zinkremenduję ją w pętli if(stan_przyciskow_stary == stan_przyciskow_nowy) to inkremenduje się ona w nieskończoność. Czy ktoś jest w stanie mi pomóc?

    OdpowiedzUsuń
    Odpowiedzi
    1. Zgadza się, ponieważ w powyższym przykładzie przerwanie jest wywoływane ze stałym odstępem czasowym wynoszącym około 8ms. Musisz to uwzględnić w swoim programie i dodać rozpoznawanie faktu, że nastąpiło naciśnięcie przycisku.

      Możesz to zrobić porównując w pętli głównej stan zmiennej stan_przyciskow zapamiętując jej poprzedni stan i inkrementować Twoją zmienną "a" tylko w przypadku, gdy stan zmiennej stan_przyciskow wskazuje na naciśnięcie przycisku, a nie jego przytrzymanie.

      Usuń
    2. a jak przy takim kodzie napisac program zapalajacy i gaszacy diode z jednego przycisku?? Moze mi ktos pomoc??

      Usuń

Działy
Działy dodatkowe
Inne
O blogu




Dzisiaj
--> za darmo!!! <--
1. USBasp
2. microBOARD M8


Napisz artykuł
--> i wygraj nagrodę. <--


Co nowego na blogu?
Śledź naszego Facebook-a



Co nowego na blogu?
Śledź nas na Google+

/* 20140911 Wyłączona prawa kolumna */
  • 00

    dni

  • 00

    godzin

  • :
  • 00

    minut

  • :
  • 00

    sekund

Nie czekaj do ostatniego dnia!
Jakość opisu projektu także jest istotna (pkt 9.2 regulaminu).

Sponsorzy:

Zapamiętaj ten artykuł w moim prywatnym spisie treści.