logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Obsluga przycisków dla stopera... Ja to zrobic?

juve112 21 Sty 2009 18:44 1515 10
REKLAMA
  • #1 6033190
    juve112
    Poziom 10  
    Witam...
    Mam taki problem...
    Musze zaprogramować stoper w AVR Studio...

    Napisałem juz głowny program do odliczania czasu ale nie wiem jak mam
    obsłużyć przycisk do zatrzymywania odliczania...

    Napisałem formułę obsługującą ale ona działa tylko wtedy gdy cały czas trzymam wciśnięty przycisk... Gdy go puszczę czas leci dalej...

    I mam teraz taka prośbę... Czy ktoś wie ?
    Jak powinna wyglądać formuła, która zatrzymywała by odliczanie czasu po wciśnięciu i puszczeniu przycisku? Tak jak w zwykłym stoperze...
    Co powinienem jeszcze dopisać?

    Ewentualnie jakaś podpowiedź jak by to mogło może wyglądac inaczej bo to akurat jest moja wersja i pewnie nie jest doskonała ;-)





    Kod programu:

    #include "czas.h"
    #include "harddef.h"
    #include "makra.h"
    #include "znaki.h"
    #include <avr/delay.h>
    uint8_t jednostki_msekund =  0, dziesiatki_msekund = 0,
         jednostki_sekund = 0, dziesiatki_sekund = 0,
    	 bufor1;
    
    
    if(!(PIN(SW) & 1<<SW_1))
    	{	                                - obsluga przycisku
                   }
    else	
    	
    
    void akt_czas(void){
    
    jednostki_msekund++; 
    if(jednostki_msekund == 10) 
      {
      jednostki_msekund = 0; 
      dziesiatki_msekund++;  
      if(dziesiatki_msekund == 10) 
        {
        dziesiatki_msekund = 0; 
        jednostki_sekund++; 
        if(jednostki_sekund == 10) 
          {
          jednostki_sekund = 0; 
          dziesiatki_sekund++; 
          if(dziesiatki_sekund == 10) 
            {
            dziesiatki_sekund = 0;   
            }
          }
        }
      }
    }
    
    void pokaz_czas(void){
    PORT(SEG) = 1<<SEG_1 | 1<<SEG_2 | 1<<SEG_3 | 1<<SEG_4;
       AktWysw++;
       switch(AktWysw){
       	case 1:
       	{
            PORT(LED)= Liczby[jednostki_msekund];
     		PORT(SEG) = WSeg[3];
         	break; // opuść instrukcję switch
       	}
       	case 2:
       	{
    		PORT(LED)= Liczby[dziesiatki_msekund]; 
     		PORT(SEG) = WSeg[2];
         	break; 
       	}
    	case 3:
     	{
     		PORT(LED)= Liczby[jednostki_sekund];
     		PORT(SEG) = WSeg[1];
         	break;
     	}
    	case 4:				
     	{
     		PORT(LED)= Liczby[dziesiatki_sekund];
     		PORT(SEG) = WSeg[0];
         	break;
     	}
    	case 5:
     	{
     		AktWysw=0;
     		break;
     	}
      }
    }
    
    void zerowanie(void){
    
    	     jednostki_msekund =  0;
    		 dziesiatki_msekund = 0;
         	 jednostki_sekund = 0; 
    		 dziesiatki_sekund = 0;
    }



    Post raportowany,
    należy stosować znacznik code.
    And!
  • REKLAMA
  • #2 6033572
    kasaidolar
    Poziom 19  
    To juz caly program? Masz przyciski na przerwaniach?
  • REKLAMA
  • #3 6033669
    juve112
    Poziom 10  
    No to jest akurat główny program tylko....

    A o co chodzi z tymi przyciskami na przerwaniach?

    Ich obsługa powinna być umieszczona również gdzieś w przerwaniach?



    Przerwania mama tutaj:

    
    #include <avr\io.h>	         // dostęp do rejestrów
    #include <inttypes.h>            // definicje typów uint8...
    #include <avr\signal.h>	  
    #include <avr\interrupt.h>	 // funkcje sei(), cli()
    #include "przycisk.h"
    
    #include "makra.h"
    #include "harddef.h"
    #include "czas.h"
    
    #define T0_INIT (256-15)
    #define T1_INIT (65536-5000)
    
    uint8_t bufor;
    
    
    int main(void)
    {
    
    	DDR(LED) = 0xff;
    	DDR(SEG) = 1<<SEG_1 | 1<<SEG_2 | 1<<SEG_3 | 1<<SEG_4;
    	DDR(SW) &= ~(1<<SW_1 | 1<<SW_2);
    
    	TCCR0 = 1<<CS02;
    	TIMSK = 1<<TOIE0 | 1 << TOIE1;
    	TCNT0 = T0_INIT;
    	TCNT1 = T1_INIT;
    	TCCR1A = 0x00;
    	TCCR1B |= (1<<CS11);
    	sei();			// włącz obsługę przerwań	
    	
    	for(;;);		// nieskończona pętla
    {
    
    }
    	return 0;
    
    }
    
    
    // procedury obslugi przerwania
    
    SIGNAL(SIG_OVERFLOW0)	
    {
    reset();
    	pokaz_czas();
    	TCNT0=T0_INIT;
    }
    
    
    SIGNAL (SIG_OVERFLOW1)
    {	
    	akt_czas();
    	
    	TCNT1 = T1_INIT;
    }
    
    
    
  • REKLAMA
  • #5 6033793
    juve112
    Poziom 10  
    No wlasnie nie wiem gdzie powinienem wstawić tą obsługę przycisków i jak ona mniej wiecej powinna wyglądać....

    Na pierwszym zamieszczonym przeze mnie kodzie programu zamieściłem wlasnie ten warunek z przyciskiem zaraz na początku po deklaracji bibliotek jak widać....

    Ale wlasnie nie mam pojecia ka ta obsuga powinna wyglądać...

    Dodano po 4 [minuty]:

    Szukałem przykładów jakichś deklaracji i obsługi przycisków i znalazłem na przykład coś takiego że ... wlasnie część tej obslugi była zamieszczona w nieskończonej petli main'a... A główny opis dzilania przycisków w osobnym pliku
  • #6 6033833
    Freddie Chopin
    Specjalista - Mikrokontrolery
    przeciez to jest proste zagadnienie z algorytmiki...

    pomijajac fakt, ze w C nie jest dopuszczalny kod poza funkcjami (czyli to co zrobiles jest totalnie zle), to skoro chcesz aby przyciski dzialaly w kazdej chwili, to chyba logiczne, ze nalezy ich obsluge wstawic tam gdzie program znajduje sie przez wiekszosc czasu (nieskonczona petla), albo do przerwania od tych przyciskow (albo kolejnego timera), tak aby mozna bylo to realizowac 'rownolegle'...

    4\/3!!
  • REKLAMA
  • #7 6034108
    juve112
    Poziom 10  
    Aha rozumiem...

    Ale teraz mam jeszcze sprawę wlasnie odnośnie tego aby po puszczeniu przycisku czas dalej nie był odliczany...

    Przy zastosowaniu takiego kodu
    
    if(!(PIN(SW) & 1<<SW_1))
       {                                   
                   }
    else    
    


    ja zwolnie przycisk czas dalej leci...

    Co zrobić aby czas pozostał zatrzymamy po zwolnieniu przycisku?


    Znalazłem niby wlasnie kawalek innego programu (obsluduje 2 przyciski ktore powoduja swiecenie sie jednego z 2 segmentow wyswietlacza na zmiane) ale nie wiem na jakiej zasadzie on dziala...

    
    void ObslPrzycisk(uint8_t maska, void(*proc) (void))
    {
    	if (!(PIN(SW) & maska))
    	{
    		_delay_loop_2(0x00ff);
    
    		while (!(PIN(SW) & maska))
    			proc();
    	}
    }
    void Pierwsza(void)
    {
    	PORT(SEG) |=1<<SEG_1 | 1<<SEG_2;
    	PORT(SEG) &=~(1<<SEG_3 | 1<<SEG_4);
    }
    void Druga(void)
    {
    	PORT(SEG) |=1<<SEG_3 | 1<<SEG_4;
    	PORT(SEG) &=~(1<<SEG_1 | 1<<SEG_2);
    }
    
    


    Dodano po 2 [minuty]:

    A to jego wywolanie w main'ie

    
    
    	ObslPrzycisk(1<<SW_1,Pierwsza);
    	ObslPrzycisk(1<<SW_2,Druga);
    
    
  • #8 6034137
    Freddie Chopin
    Specjalista - Mikrokontrolery
    no ale czemu sie dziwisz ze twoj kod nie dziala tak jak bys sobie zyczyl? dziala dokladnie tak jak napisales - jak dlugo trzymasz przycisk, tak dlugo program jest 'zawieszony' na pustym warunku. jesli chcesz zatrzymac odliczanie, to musisz cos FIZYCZNIE zatrzymac...

    4\/3!!
  • #9 6034188
    juve112
    Poziom 10  
    No kurcze wlasnie wiem tylko... No nie wiem jak mam to zrobic....
    Co wstawic w ten pusty warunek....
  • #11 6034403
    juve112
    Poziom 10  
    Hmmm Dobre pytanie...
REKLAMA