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

zbyt długi czas reakcji na naciśnięty przycisk

Joahim_Skywalker 19 Lip 2010 20:03 1041 4
REKLAMA
  • #1 8309204
    Joahim_Skywalker
    Poziom 12  
    Witam. Poniżej przedstawiam kod, który jest synchronizowany z siecią elektroenergetyczną, a następnie na drabince r2r generuję 3 przebiegi prostokątne, przesunięte względem siebie o 120 stopni. Dodatkowo chcę regulować przesunięciem fazowym wszystkich przebiegów jednocześnie względem sygnału synchronizującego. Wszystko działa, ale jak zacznę zwiększać opóźnienie to za każdym razem przycisk trzeba trzymać dłużej, aby przesunięcie fazowe się zwiększyło i odwrotnie. Czy można zrobić w ten sposób, aby reakcja była prawie natychmiastowa?

    
    ISR(INT0_vect)//wlaczenie przerwania zewnetrznego, wchodzi sygnal z detektora 0
    {
    //generowanie sygnalu sterujacego w fazie z detektorem zera		
    int_in++;//licznik przerwan pochodzacych od detektora zera
     if (int_in==1) _delay_ms(time_del);	
    	
    	if (int_in<okres)// zmiana liczby okresow
    	{
    		
    		PORTA=napiecie_znam;//wlacza napiecie znamionowe  
    	}
    
    		else{	
    		if (int_in==okres) //opoznienie chwili czasowej
    		{
    	 	_delay_ms(time_del);
    		}
    		if (int_in<okres*2)
    		{	
    			PORTA=licznik; //zaladuj wartosc ustawionego licznika
    			
    		}
    			
    			}
    
    //generowanie sygnalu przesunietego o 120 stopni wzgledem detektora zera
    
    
    if (int_in1==1) _delay_ms(time_del); _delay_us(700); _delay_ms(6);
    	
    	if (int_in<okres)// jesli nastapi przerwanie wlacz napiecie znamionowe
    	{
    		
    		PORTB=napiecie_znam;//wlacza napiecie znamionowe  
     	
    	}		
    		
    		else{	
    		if (int_in==okres) _delay_ms(time_del);  _delay_us(700); _delay_ms(6);
    		if (int_in<okres*2)
    		{	
    			
    			PORTB=licznik; //zaladuj wartosc ustawionego licznika
    			
    		}
    
    			}
    
    			//=240 stopni==
    
    
    if (int_in==1) _delay_ms(time_del); _delay_ms(6); _delay_us(700);	
    if (int_in<okres)// jesli nastapi przerwanie wlacz napiecie znamionowe
    	{
    		
    		PORTC=napiecie_znam;//wlacza napiecie znamionowe  
     	
    	}
    		
    		
    		else{	
    		if (int_in==okres) _delay_ms(time_del);  _delay_us(700); _delay_ms(6); 
    		if (int_in<okres*2)
    		{	
    			
    			PORTC=licznik; //zaladuj wartosc ustawionego licznika
    			
    			}
    			if(int_in>=okres*2-1) int_in=0; //zeruj licznik przerwan
    
    
    			}
    
    
    
    }
  • REKLAMA
  • Pomocny post
    #2 8309555
    janbernat
    Poziom 38  
    Należy zapomnieć o używaniu:
    _delay- w przerwaniu
    _delay_ms(time_del)- od zmiennej
    _delay- w ogóle.
    I zacząć korzystać z timerów.
  • REKLAMA
  • #3 8309608
    Joahim_Skywalker
    Poziom 12  
    Czyli powinienem napisać sobie procedury opóźniające i je wywoływać w przerwaniu? Proszę mnie poprawić jeśli moje myślenie jest błędne gdyż nie jestem zaawansowanym programistą avr.
  • REKLAMA
  • Pomocny post
    #4 8309686
    janbernat
    Poziom 38  
    Ja też :D
    W przerwaniu zewnętrznym należy tylko ustawiać jakąś flagę- ew. zwiększać.
    I w zasadzie nic więcej.
    A któryś z timerów ustawić tak aby co jakiś czas- xxms czy xxus generował przerwanie od przepełnienia albo CTC.
    Ustawić na najmniejszy wymagany odcinek czasu.
    W tym przerwaniu też ustawiać tylko flagę albo inkrementować- zależnie od potrzeb.
    A obsługa ustawień portów w main- po sprawdzeniu ustawień flag z przerwań.
    Wiem co należy zrobić- ale jak to napisać to trudniej.
  • #5 8314725
    Joahim_Skywalker
    Poziom 12  
    Uzupełnienie informacji od Kolegi janbernat znalazłem tutaj Link
REKLAMA