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

Sekwencja klawiszy w C, atmega8

szefopiotr 01 Gru 2008 19:08 1425 6
REKLAMA
  • #1 5805776
    szefopiotr
    Poziom 9  
    Witam, mam problem z poniższym programem,który jest częścią większego kodu. Chce aby wejść w aplikacje, konieczne bylobyby wcisniecie odpowiednio w sekwencji :3 razy przycisk 1, 2 razy przycisk 2.

    Po wpisaniu tej sekwencji program ma przejść do dalszych instrukcji w mainie. Jesli kolejnosc sekwencji zostanie pomylona program wraca do poczatku wpisywania.

    Program niedziala jednak poprawnie, nie jest chyba to problem drgania stykow bo opoznienie po wcisnieciu przyciskow wynosi 200ms(dawalem tez 500) i obojetnie jak nie zmieniam to problem sie powtarza.

    Wydaje mi sie ze wina lezy w tej czesci kodu(struktura powtarz sie parokrotnie):
    
    	while(c!=1)
    						{
    							if ((PINC&0x02)==0x00)
    							{ zm++;
    							  c=1;
    							  _delay_ms(opoznienie2);
    							  
    							}
    						}
    										}
    poniewaz gdy przerobie strukture switch do tylko jednego case to zabezpieczenie dziala, ale tak co 3,4 wcisniecie przycisku(tzn. wlacza sie dosc losowo),co przy sekwencji jest niedopuszczalne, bo automatycznie wraca do poczatku kodu.

    Jak moge przerobic program zeby dzialal poprawnie?? Bede wdzieczny za pomoc...

    Oto caly program:
    #define opoznienie2 200
    int zm=0;
    
    void zabezpieczenie(zm)
    {
    	switch(zm)  
    	{
    				case 0: while(c!=1)
    						{
    							if ((PINC&0x02)==0x00)
    							{ zm++;
    							  c=1;
    							  _delay_ms(opoznienie2);
    							  
    							}
    						}
    				
    						
    				
    				
    				case 1: 
    						while(c!=2)
    						{
    							if ((PINC&0x02)==0x00)
    							{ zm++;
    							  c=2;
    							  _delay_ms(opoznienie2);
    							 
    							  
    							}
    							
    							if ((PINC&0x01)==0x00)
    							{ zm=0;
    							  c=2;
    							  _delay_ms(opoznienie2);
    							 
    							  
    							}
    						}
    				
    						
    						
    				
    				case 2:
    						while(c!=3)
    						{
    							if ((PINC&0x02)==0x00)
    							{ zm++;
    							  c=3;
    							  _delay_ms(opoznienie2);
    							 
    							  
    							}
    							
    							if ((PINC&0x01)==0x00)
    							{ zm=0;
    							  c=3;
    							  _delay_ms(opoznienie2);
    							 
    							  
    							}
    						}
    				
    				
    						
    						
    						
    				
    				case 3:
    						while(c!=4)
    						{
    							if ((PINC&0x02)==0x00)
    							{ zm=0;
    							  c=4;
    							  _delay_ms(opoznienie2);
    							 
    							  
    							}
    							
    							if ((PINC&0x01)==0x00)
    							{ zm++;
    							  c=4;
    							  _delay_ms(opoznienie2);
    							 
    							  
    							}
    						}
    				
    				case 4:
    						while(c!=5)
    						{
    							if ((PINC&0x02)==0x00)
    							{ zm=0;
    							  c=5;
    							  _delay_ms(opoznienie2);
    							 
    							  
    							}
    							
    							if ((PINC&0x01)==0x00)
    							{ zm++;
    							  c=5;
    							  _delay_ms(opoznienie2);
    							 
    							  d=1;
    							  
    							}
    						}
    						break;
    	}
    
    
    
    
    
    }
    
    void main(void)
    {
    	while(d!=1)
    	{
    	zabezpieczenie(zm);
    	}
    
    }
    


    Proszę poprawić tytuł wiadomości - regulamin p.11.1
    [zumek]
  • REKLAMA
  • #2 5806034
    dawid512
    Poziom 32  
    Osobiście zawsze stosuje 100ms może i tobie pomoże.
  • REKLAMA
  • #3 5807074
    fazolek
    Poziom 12  
    Pierwsze co widzę to nie podciągasz linii klawiszy, drze mogą źle ugie po odczekaniu drgań zrób sprawdzanie puszczenia klawisza i odczekaj ale dużo krócej jakieś 10ms tak dla 100% pewności- Na tym etapie masz tak, że jak wciśniesz i przytrzymasz to masz sekwencje od nowa do wpisania ale to sprawa kosmetyczna. Zrób w każdym while'u wyświetlanie zmiennej zm na jakichś diodach .
  • REKLAMA
  • #4 5807524
    szefopiotr
    Poziom 9  
    już sobie poradziłem,po prostu w strkturze case nie moge zmieniac zmiennej "zm" tylko musze to robic w programie glownym,bo jesli robie to w case to po jednokrotnym przejsciu przez petle znowu ja zeruje.

    Swoja droga dlaczego nie moge zmieniac "zm" w casie nawet jesli jest zadeklarowana jako volatile??
  • REKLAMA
  • #5 5807648
    Dr.Vee
    VIP Zasłużony dla elektroda
    Bo nie rozumiesz jak działa konstrukcja switch/case w języku C. Nie martw się, wielu początkujących programistów sobie na tym zęby połamało ;)

    Kruczek polega na tym, że po każdym case powinna być instrukcja break - inaczej wykonane zostaną instrukcje z kolejnej etykiety:
    switch (1) {
      case 1: printf("jeden\n");
      case 2: printf("dwa\n"); break;
    }

    W tym kodzie zostaną wypisane oba napisy, a nie tylko jeden. Taki sam problem masz w swoim kodzie.

    Oczywiście są sytuacje, gdzie ominięcie break się przydaje, ale należy to udokumentować komentarzem, żeby było wiadomo, że to nie pomyłka :)

    Pozdrawiam,
    Dr.Vee
  • #6 5808906
    szefopiotr
    Poziom 9  
    Wiesz tutaj problem polegal na czym innym, przypadkowo przekleilem kod bez break'ow bo wlasnie sprawdzalem jak dziala:). Bardziej chodzilo mi o to ze jak zmieniam "zm" w poszczegolnym casie to po sprawdzeniu warunku program mi ja zeruje(mimo ze mam zadeklarowana jako volatile). Jesli natomiast zmieniam ja w programie glownym (main) to wszystko jest ok. Tu jest moj kod juz poprawny jakby kogos ineresowalo, a ja bylbynm dalej wdzieczny za odpowiedz czemu nie moge zmieniac zmiennej "zm" w case??

    Pozrawiam

    volatile char zm=0;
    void zabezpieczenie(zm)
    {
    	switch(zm)  
    	{			
    				
    				case 0: 
    						if ((PINC&0x02)!=0x02)
    						{ 
    							_delay_ms(opoznienie2);
    							c=1;
    							e++;
    						}
    						
    						if ((PINC&0x01)!=0x01)
    						{ 
    							_delay_ms(opoznienie2);
    						
    							e++;
    						}
    						break;
    				
    				case 1: 
    						if ((PINC&0x02)!=0x02)
    						{ 
    							_delay_ms(opoznienie2);			
    							c=2;
    							e++;
    						}
    						
    						if ((PINC&0x01)!=0x01)
    						{ 
    							_delay_ms(opoznienie2);
    							c=0;
    							e++;
    						}
    				
    						break;
    						
    				
    				case 2: 
    						if ((PINC&0x02)!=0x02)
    						{ 
    							_delay_ms(opoznienie2);
    							c=3;
    							e++;							
    						}
    						
    						if ((PINC&0x01)!=0x01)
    						{ 
    							_delay_ms(opoznienie2);
    							c=0;
    							e++;
    						}
    							
    						break;
    						
    				
    				case 3: 
    						if ((PINC&0x01)!=0x01)
    						{ 
    							_delay_ms(opoznienie2);	
    							c=4;
    							e++;
    						}
    						
    						if ((PINC&0x02)!=0x02)
    						{ 
    							_delay_ms(opoznienie2);
    							c=0;
    							e++;
    						
    						}
    				
    						break;
    			
    				case 4: 
    						if ((PINC&0x01)!=0x01)
    						{ 
    							_delay_ms(opoznienie2);
    							c=5;
    							e++;
    							
    						}
    						
    						if ((PINC&0x02)!=0x02)
    						{ 
    							_delay_ms(opoznienie2);
    							c=0;
    							e++;
    						
    						}
    				
    						break;
    					
    				case 5: 
    						if ((PINC&0x02)!=0x02)
    						{ 
    							_delay_ms(opoznienie2);
    							c=6;
    							e++;							
    						}
    						
    						if ((PINC&0x01)!=0x01)
    						{ 
    							_delay_ms(opoznienie2);
    							c=0;
    							e++;
    						
    						}
    				
    						break;
    
    void main(void)
    { 
    	Inicjalizacja_portow(); //Inicjalizacja systemu
        lcd_init();          
        LCD_clr();
    	
    	
    	while(d!=1)                //warunek startu,wprowadzenia sekwencji
    	{   
    		LCD_xy(0,0);
    		write_text("**  WPROWADZ  **");
    		LCD_xy(0,1);
    		write_text("->KOD  DOSTEPU<-");
    		zabezpieczenie(zm);
    		
    		if (c==0)
    		{
    		 zm=0;
    		} 
    		
    		if (c==1)
    		{
    		 zm=1;
    		}
    	
    		if (c==2)
    		{
    		 zm=2;
    		}
    	
    		if (c==3)
    		{
    		 zm=3;
    		}
    		
    		if (c==4)
    		{
    		 zm=4;
    		}
    		
    		if (c==5)
    		{
    		 zm=5;
    		}
    		
    		if (c==6)
    		{
    		 d=1;
    		 zm=0;
    		 c=0;
    		}
    	
    		if (e==7)
    		{   LCD_clr();
    			LCD_xy(0,0);
    			write_text("!!!BLEDNY KOD!!!");
    			_delay_ms(1000);
    			c=0;
    			zm=0;
    			e=0;
    		}
    	}
    	
    					
    				
    	
    
    
    
    	}	
    
    }
  • Pomocny post
    #7 5808942
    Dr.Vee
    VIP Zasłużony dla elektroda
    Masz takie same nazwy zmiennej globalnej i parametru przekazywanego do funkcji. W tej sytuacji lokalna zmienna przysłania globalną - czyli zmieniasz wartość kopii parametru przekazanego do funkcji. Możesz albo zrezygnować z parametru, zwracać wartość z funkcji, albo przekazać wskaźnik na zmienną.

    Jeszcze lepszym rozwiązaniem (z programistycznego punktu widzenia) byłoby zaprojektowanie funkcji:
    bool sprawdz_kod(int nr_przycisku)
    {
        /* sprawdź, po wcisnieciu przycisku sekwencja jest ok */
        /* jesli tak, zwroc true */
        /* jesli nie, aktualizuj wewnetrzny stan i zwroc false */
    }
    Pozdrawiam,
    Dr.Vee
REKLAMA