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

Wieszanie się Atmegi przy rozłączaniu przekaźnika

Krzysiek_Z 04 Paź 2010 13:52 1756 8
REKLAMA
  • #1 8582219
    Krzysiek_Z
    Poziom 11  
    Cześć,
    mam problem ze zwieszaniem się programu, a dokładniej przy przejściu do podmenu włączania i wyłączania przekaźnika, kilka razy włączy się i wyłączy dobrze a potem program zachowuje się jakby jeden z przycisków się zaciął (w tym przypadku akurat wychodzi mi z menu) i przestaje reagować... Gdzieś na elektrodzie wyczytałem, że to prawdopodobnie sprawa źle zaprojektowanej płytki, wiec wrzucam ją i pytam czy o rzeczywiście ona jest przyczyną tego problemu oraz jak go rozwiązać.
  • REKLAMA
  • #2 8582688
    arktik1
    Poziom 27  
    Pokaż schemat, może jest to kwestia zakłóceń spowodowanych przez przekaźnik.
  • REKLAMA
  • #3 8582710
    Krzysiek_Z
    Poziom 11  
    Schemat jest w załączniku, z tym, że do AVCC podłączone jest jeszcze 5V i przekaźnik podpięty jest dopiero za zworką ON/OFF
  • REKLAMA
  • REKLAMA
  • #5 8585362
    Konto nie istnieje
    Konto nie istnieje  
  • #6 8586253
    Fajfer2
    Poziom 20  
    Rezystor pull-up od resetu chyba powinien być podłączony zaraz do pinu nr 7
    przy kondensatorze C9. Rezystor ten obecnie tworzy dość szeroką pętlę z masą uC (w dodatku w pobliżu przekaźnika). Pin AVCC musi być podłączony do zasilania nawet jeśli nie wykorzystujesz ADC.
  • #7 8587645
    Krzysiek_Z
    Poziom 11  
    AVCC jest podłączone do 5V mostkiem z kawałka nogi od rezystora na płytce.
    Dziś już nie mam jak przelutować tego rezystora, postaram się to zrobić jutro. Póki co wrzucam programik, może rzeczywiście coś jest w programie skopane...

    Main:
    
    int main(void)
    {
    
    	DDRC = 0xFF;
    	PORTC = 0xFF;
    	DDRB &= !((1<<PB2)|(1<<PB3)|(1<<PB4)|(1<<PB5));
    	DDRB |= ((1<<SP1)|(1<<K1));
    	PORTB |= ((1<<PB2)|(1<<PB3)|(1<<PB4)|(1<<PB5));
    
    	TCCR1B |= (1 << WGM12); 
    	OCR1A = 1875; 		
    	TCCR1B |= ((1 << CS10) | (1 << CS11)); 
    	TIMSK1 |= (1 << OCIE1A); 	
    
    	sei();
    
    	LCD_Initalize();
    	LCD_Clear();
    
    	Menu();
    
    	while(1);
    	return(0);
    }
    


    Funkcja sterująca przekaźnikiem:
    
    #define K1 PB0
    char RELAY_ON = 0; //zmienna globalna
    
    void Output_12V_Settings(void)
    {
    	LCD_Clear();
    	Print("Gniazdo HV");
    	LCD_GoTo(0,1);
    	LCD_WriteData(0xA5);
    	Print("Zasilanie ");
    
    	if(Relay_ON == 1)
    	{
    		Print("wl.");
    	}
    	else
    	{
    		Print("wyl.");
    	}
    
    	while(Pressed_Key!=4)
    	{
    		LCD_GoTo(11,1);
    		Press_B();
    		if(Pressed_Key == 1 | Pressed_Key == 2)
    		{
    			Beep();
    			if(Relay_ON == 1)
    			{
    				Relay_ON = 0;
    				Print("wyl.");
    
    			}
    			else
    			{
    				Relay_ON = 1;
    				Print("wl. ");
    			}
    		}
    
    	}
    
    
    	if(Relay_ON != 1)
    	{
    		//_delay_ms(1000);
    		PORTB &= !(1<<K1);
    		//_delay_ms(2000);
    	}
    	else
    	{
    		PORTB |= (1<<K1);
    	}
    
    
    	Beep();
    }
    


    Obsługa przycisków:
    
    //Przyciski
    #define B1 4//PB2 //4
    #define B2 8//PB3 //8
    #define B3 16//PB4 //16
    #define B4 32//PB5 //32
    
    char Pressed_Key = 0;
    volatile int Key_Release_Time;
    
    void Press_B(void)
    {
    	Pressed_Key = 0;
    	while( !(!(PINB & B1)|!(PINB & B2)|!(PINB & B3)|!(PINB & B4)) );
    
    	while(Key_Release_Time>0);
    	if( !(PINB & B1)) Pressed_Key = 4; else
    	if( !(PINB & B2)) Pressed_Key = 1; else
    	if( !(PINB & B3)) Pressed_Key = 2; else
    	if( !(PINB & B4)) Pressed_Key = 3; else
    	Pressed_Key=0;
    	
    	
    	Key_Release_Time = 40;
    }
    


    I jeszcze przerwanie:
    
    ISR(TIMER1_COMPA_vect)
    {
    	if(Key_Release_Time>0)
    	{
    		Key_Release_Time--;
    	}
    	else
    	{
    		Pressed_Key = 0;
    	}
    }
    
  • #8 8587822
    mieczotronix
    Poziom 16  
    Trudno powiedzieć, co akurat powoduje błędne działanie, ale jest tutaj kilka błędów:

    - zmienna Pressed_Key też powinna być volatile
    - Key_Relase_Time w Press_B powinna mieć przypisaną wartość przed while
    po sprawdzeniu przycisków przypisujesz jej wartość 40 i jeśli przerwanie nadal chodzi to po 40-tu przerwaniach wyzeruje znowu Pressed_Key, jakby nic nie naciśnięto.
    Logiczniej byłoby Pressed_key zerować po (nie)obsłużeniu klawiszy w Output_12V_Settings
  • #9 8598308
    Krzysiek_Z
    Poziom 11  
    Przepraszam, że tyle nie pisałem, jednak między czasie zablokowałem sobie procesor... Błąd okazał się być błędem programowym, wylutowałem przekaźnik oraz nawet rezystor R1. Program nadal wiesza się w tym samym momencie. Jest to moment kiedy wchodzimy do ustawienia wyjścia i przełączamy z WŁ. na WYŁ. Proszę więc bardziej doświadczonych kolegów programistów o pomoc w znalezieniu tego błędu.

    Dodano po 2 [godziny] 48 [minuty]:

    Odpowiem sam sobie... Błąd był spowodowany tym, że chciałem wyzerować wyjście PB0 poprzez PORTB &= !(1<<PB0) a nie PORTB &= ~(1<<PB0)...
REKLAMA