AVR przytrzymanie klawisza

Masz problem z Arduino? Tutaj możesz szukać pomocy.
ODPOWIEDZ
Gaspar
Młodszy majsterkowicz
Posty: 15
Rejestracja: 8 lis 2014, 23:42

AVR przytrzymanie klawisza

Post autor: Gaspar » 20 lis 2014, 21:06

Witam,
mam taki program :

Kod: Zaznacz cały

#include <avr/io.h>
#include <util/delay.h>

#define LED1 (1<<PB0)
#define LED2 (1<<PB1)
uint8_t KLAWISZ_WCISNIETY;

#define KLAWISZ (1<<PD7)

int main(void) {

    DDRB  |= LED1 | LED2; //Ustawienie pinów sterujących diodami
    PORTB |= LED2; //Ustawienie stanu wysokiego na wyjściu sterującym LED2


    DDRD  &=~ KLAWISZ; //Ustawienie pinu klawisza jako wejście
    PORTD |=  KLAWISZ; //włączenie rezystora podciągającego
    KLAWISZ_WCISNIETY = 0;

   while (1) //Pętla główna
   {
    		  if(!KLAWISZ_WCISNIETY && !(PIND & KLAWISZ)){
    			  KLAWISZ_WCISNIETY = 1;
    			  PORTB |=LED1;
    			  PORTB &=~LED2;
    		  }
    			  else if(KLAWISZ_WCISNIETY && (PIND & KLAWISZ)){
    				  KLAWISZ_WCISNIETY = 0;
    				  PORTB |=LED2;
    				  PORTB &=~LED1;
    			  	  }
    		  	  }

}



Chciałbym żeby przy przytrzymaniu klawisza dłużej niż 2sek zaświeciły się obie diody. Mam pomysł żeby wykorzystać timer tylko nie mam pojęcia jak. Wyobrażam sobie to tak :

Kod: Zaznacz cały

if(przycisk wcisniety){
Włączenie timera
Instrukcja A
jeżeli timer doliczy do końca (2 sek) to ustawi zmienną "czas" na 1.
if(przycisk wciśniety +czas){
Instrukcja B
}
}
else (klawisz nie wciśniety){
Inctrukcja C
reset timera i zmiennej "czas"
}
czy takie coś ma szanse działać ? jak napisać taki program ? Na 100% są jakieś rozwiązania bo przecież często potrzeba zrobić A po wciśnieciu przycisku, a B po przytrzymaniu przycisku. Program piszę w C na AVR w eclipse ( nie na andruino).
Dzięki za pomoc.

Co miesiąc do wygrania nagrody o wartości ponad 1600 zł!


stiven
Złota rączka
Posty: 1581
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: AVR przytrzymanie klawisza

Post autor: stiven » 20 lis 2014, 21:50

To jest forum arduino, nie wiem czy znajdzie się tu ktoś, kto będzie w stanie pomóc w czystym C.
Awatar użytkownika
djbuh
Majsterkowicz
Posty: 232
Rejestracja: 9 gru 2012, 19:45
Lokalizacja: Bytom
Kontakt:

Re: AVR przytrzymanie klawisza

Post autor: djbuh » 20 lis 2014, 22:02

Przy wciśnięciu przycisku startujesz timer i odliczasz nim 2 s. Po odliczeniu sprawdzasz stan przycisku ponownie. Jeśli jest wciśnięty załączasz diody.

Jeżeli chcesz po pojedynczym wciśnięciu wykonywać instrukcję A, a po przytrzymaniu instrukcję B to polecam podzielić czas oczekiwania na krótsze odcinki. Wtedy przy wciśnięciu przycisku startujesz timer, odliczasz czas np. 100 ms i po każdym odliczeniu sprawdzasz stan przycisku. Jeżeli jest wciśnięty to inkrementujesz jakąś zmienną. Wykonanie tego 20 razy da Ci czas równy 2 s. Jeżeli zmienna będzie zawierała liczbę mniejszą niż 20 to wykonujesz instrukcję A, jeżeli równą 20 to instrukcję B. Musisz tylko pamiętać o tym, aby sprawdzać, czy zmienna zawiera 20, jeśli tak, to kończysz odliczanie timerem i wykonujesz instrukcję B. W przeciwnym razie program będzie cały czas inkrementował zmienną, i możesz sobie tak trzymać przycisk przez nawet 25 sekund, dopiero po puszczeniu program wykona instrukcję B, lub nawet A, gdy zmienna się przepełni, a tego nie chcemy. Jeżeli po np. 500 ms puścisz przycisk to program wyłapie to i wykona instrukcję A od razu (ale z dokładnością do 100 ms, co jest raczej wystarczające) i nie będzie czekał do pełnych 2 s.
Awatar użytkownika
Nefarious19
Starszy majsterkowicz
Posty: 373
Rejestracja: 4 cze 2014, 23:04

Re: Odp: AVR przytrzymanie klawisza

Post autor: Nefarious19 » 21 lis 2014, 03:05

stiven pisze:To jest forum arduino, nie wiem czy znajdzie się tu ktoś, kto będzie w stanie pomóc w czystym C.
A gdzie tu jest tak napisane?
stiven
Złota rączka
Posty: 1581
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: AVR przytrzymanie klawisza

Post autor: stiven » 21 lis 2014, 10:54

Dział forum nazywa się "Arduino (i inne mikrokontrolery)".
Awatar użytkownika
Nefarious19
Starszy majsterkowicz
Posty: 373
Rejestracja: 4 cze 2014, 23:04

Re: AVR przytrzymanie klawisza

Post autor: Nefarious19 » 21 lis 2014, 12:17

stiven pisze:"Arduino (i inne mikrokontrolery)".

A Arduino to nie AVR? to też procesor AVR na niebieskiej płytce. A jak piszesz programy na Arduino to w jakim języku je piszesz? Bo ja np w C/C++.


Wracając do tematu. Trzeba troszkę poprawić obsługę drgań styków ale nie jest źle. Tu poradniki:

3 częściowy artykuł o eliminacji drgań styków, poczytaj a nie piszesz kod na pałe.

CZ. 1
CZ. 2
CZ.3

co do Twojego problemu, ja bym to zrobił tak. Odpalasz timer sprzętowy w tryb licznika CTC lub Normal. Ustawiasz tak żeby generował przerwanie co 100ms. Tworzysz sobie zmienną globalną volatile bo będziesz jej używał w przerwaniu, będzie to licznik. Tworzysz zmienną która przechowuje stan klawisza czyli czy jest 1 czy 0. Gdy klawisz wciśniety będzie Twoja zmienna od info o klawiszy równa się 1. sprawdzasz w pętli i w przerwaniu czy tak jest. W warunku wstawiasz timer programowy który po 20 tyknieciach zapali Ci obie diody. 20*100ms = 2 sekundy. Jak działa timer programowy?

ustawiasz timer by generował podstawe czasu, np co 100ms. tworzysz zmienną globalną licznikową. W programie równym dajesz warunek że jeżeli jest ona równa 0 to:

1. wstawiasz do niej swoją wartość
2. robisz to co chesz żeby się wykonywało co taki czas jaki sobie wymyśliłeś a ten czas będzie równy twoja zmienna razy podstawa czasu.

w przerwaniu sprwdzasz czy zmienna jest większa od 0 i jeżeli tak to ją zmniejszasz o 1.

oto kod dla Ciebie;)

Kod: Zaznacz cały


/*
 * main.c
 *
 *  Created on: 21 lis 2014
 *      Author: Rafał
 */

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



#define LED1 (1<<PB0)
#define LED2 (1<<PB1)
#define KLAWISZ (1<<PD7)

//zmienne globalne których nie inicjalizujemy bo inicjowane są automatycznie zerami
volatile uint8_t licznik;
uint8_t KLAWISZ_WCISNIETY;
uint8_t klawisz_info; //zmienna do przechowywania informacji czy klawisz jest wciśnięty
uint8_t ilosc_tykniec;

void inicjalizuj_timer_0(void);

int main(void) {

    DDRB  |= LED1 | LED2; //Ustawienie pinów sterujących diodami
    PORTB |= LED2; 		  //Ustawienie stanu wysokiego na wyjściu sterującym LED2


    DDRD  &=~ KLAWISZ;    //Ustawienie pinu klawisza jako wejście
    PORTD |=  KLAWISZ;    //włączenie rezystora podciągającego

    inicjalizuj_timer_0();

    sei(); // zezwalamy na przerwania

   _delay_ms(10); //czekamy na podciągnięcie wszystkiego co trzeba

   while (1) //Pętla główna
   {
            if(  !KLAWISZ_WCISNIETY && !( PIND & KLAWISZ )  )
            {	
               klawisz_info = 1;
               KLAWISZ_WCISNIETY = 1;
               PORTB |=LED1;
               PORTB &=~LED2;
               
               
            }else if( KLAWISZ_WCISNIETY && (PIND & KLAWISZ) )
            		{	
            			klawisz_info = 0;
            			KLAWISZ_WCISNIETY++; // eliminacja drgań styków;
            			PORTB |=LED2;
            			PORTB &=~LED1;
              		}

            if (klawisz_info == 1) //jeżeli klawisz jest wciśnięty to:
                {	//jeżeli licznik = 0 (dzieję się tak co 2000ms
            	        
                        if (!licznik)
                        {
            		
            		PORTB |= LED1 | LED2;
            	        }
            		
            }else licznik = 20;
            
    }

}

//funkcja do inicjalizacji timera0 w ATmega8 w tryb Normal by tykał 10ms
void inicjalizuj_timer_0(void)
{
	TCNT0 = 179;					  //wpisujemy do rejestru TCNT0 początkową wartośc 179.
	TCCR0 |= (1<<CS02) | (1<<CS00);   //preskaler na 1024
	TIMSK |= (1<<TOIE0);			  //odblokowanie przerwania od przepełnienia
}

//procedura obsługi przerwania
ISR(TIMER0_OVF_vect)
{
	//do rejestru TCNT0 wpisujemy od razu naszą wartośc
	TCNT0 = 179;
	//jeżeli klawisz wcisniety
	if (klawisz_info == 1) {
	if (licznik) licznik--;//jeżeli licznik większy od zera, zmniejsz o 1.
	}

}




Kod napisałem bez testowania bo nie chciało mi się składać układu. Napisany jest dla ATmegi8. Jakby coś nie działało, napisz dokłądnie co to będziemy myśleć.
stiven
Złota rączka
Posty: 1581
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: AVR przytrzymanie klawisza

Post autor: stiven » 21 lis 2014, 13:41

Nefarious19 pisze: A Arduino to nie AVR? to też procesor AVR na niebieskiej płytce. A jak piszesz programy na Arduino to w jakim języku je piszesz? Bo ja np w C/C++.
No dobrze, ale zauważ taką rzecz, możesz znać C/C++, umiesz programować w arduino ide, ale to nie oznacza automatycznie, że potrafisz programować mikrokontrolery w czystym C. Żeby programować w czystym C musisz wiedzieć dużo więcej, na przykład znać strukturę rejestrów danego mikrokontrolera (przy programowaniu arduino nie trzeba, chociaż w niektórych sytuacjach taka wiedza się przydaje, na przykład do skorzystania z timerów). Gdyby twórca tego forum miał na myśli ogólnie programowanie mikrokontrolerów, to by tak nazwał ten dział forum, a to, że w nawiasie jest o innych mikrokontrolerach, to na pewno dlatego, bo inne mikrokontrolery też można programować jak arduino (jeśli się odpowiednio przygotuje arduino ide). Zawartość tego forum też o tym świadczy. Dlatego ja zwróciłem tylko uwagę, że otrzymanie pomocy w pisaniu programu w czystym C, może być tutaj utrudnione, a istnieją fora, na których są osobne działy o programowaniu w czystym C i w arduino.
Awatar użytkownika
Nefarious19
Starszy majsterkowicz
Posty: 373
Rejestracja: 4 cze 2014, 23:04

Re: AVR przytrzymanie klawisza

Post autor: Nefarious19 » 21 lis 2014, 13:51

Autor postu zadał pytanie dotyczące programu w C na mikrokontrolerze AVR. Jeżeli traktować Arduino jako mikrokontroler sam w sobie to innym mikrokontrolerem jest np ATmega, ATtiny, ATXmega, ARM, STM, PIC etc.a nazwa działu w nawiasie (inne mikrokontrolery) może być dowolnie interpretowana. Jeżeli komuś przeszkadza że pomogłem (mam nadzieję) Koledze w napisaniu programu w "czystym C" to proszę to zgłosić do moderatora. Nie przeczytałem nigdzie że to forum jest tylko dla Arduino.

Mea culpa
ODPOWIEDZ

Strony partnerskie: