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

PWM LED załączanie i wyłączanie za pomocą jednego przycisku

john93 06 Kwi 2012 11:41 2335 9
REKLAMA
  • #1 10763055
    john93
    Poziom 10  
    Prosiłbym o pomoc (podpowiedź/fragment kodu) jak zrealizować załączanie/wyłączanie na 1 przycisku.
    #include <avr/io.h>
    #include <util/delay.h>
     
     
    #define PRZYCISK0 _BV(0)
    #define PRZYCISK1 _BV(1)
    #define PRZYCISK2 _BV(2)
    #define PRZYCISK3 _BV(3)
    #define LED _BV(3)
     
     
    int main(void)
    {
    DDRA = PRZYCISK0|PRZYCISK1|PRZYCISK2|PRZYCISK3;
    PORTA = PRZYCISK0|PRZYCISK1|PRZYCISK2|PRZYCISK3;
    DDRB |= LED;
     
     
    TCCR0 |= (1<<WGM01)|(1<<WGM00);
    TCCR0 |= (1<<COM01)|(1<<COM00);
    TCCR0 |= (1<<CS00);
     
    OCR0=255;
     
    while(1)
    {
     
     
     
    while(bit_is_clear(PINA,2)) OCR0 = 0; //wyłącz
     
     
     
    while(bit_is_clear(PINA,0) && OCR0>0) //ściemniacz
            {      
                    OCR0--;
                    _delay_ms(10);                           
            }
     
    while(bit_is_clear(PINA,1) && OCR0<255) //rozjaśniacz
            {      
                    OCR0++;
                    _delay_ms(10);                           
            }
     
    while(bit_is_clear(PINA,3)) OCR0 = 255; //załącz
     
     
     
    }
    }
    
  • REKLAMA
  • #2 10763125
    dondu
    Moderator na urlopie...
    Zapoznaj się z drganiami styków i przykładami eliminacji programowej: http://mikrokontrolery.blogspot.com/2011/04/przycisk-drgania-stykow-debouncing.html
    Na tej podstawie zrobisz sobie funkcjonalność którą potrzebujesz, wprowadzając dodatkowo jakąś zmienną mówiącą o stanie urządzenia (On - off).
  • REKLAMA
  • #3 10763149
    john93
    Poziom 10  
    dondu napisał:
    Na tej podstawie zrobisz sobie funkcjonalność którą potrzebujesz, wprowadzając dodatkowo jakąś zmienną mówiącą o stanie urządzenia (On - off).


    Z drganiami sobie poradzę bez problemu, mnie chodzi głównie o to w jaki sposób ta zmienna, miałaby o tym właśnie mówić..
  • #4 10763396
    zumek
    Poziom 39  
    john93 napisał:
    Z drganiami sobie poradzę bez problemu...

    Być może :D ale zanim to zrobisz, popraw konfigurację pinów do których podłączyłeś przyciski, bo możesz uszkodzić uC.
    Co do "jednoprzyciskowego" przełącznika, to przypomnij sobie o istnieniu operacji bitowej XOR.
    Np.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Ja wybrałbym możliwość 2(DDR) lub 3(TCCR), bo wtedy uC pamięta stan wypełnienia PWM po ponownym "załączeniu".
  • REKLAMA
  • #5 10763436
    dondu
    Moderator na urlopie...
    john93 napisał:
    Z drganiami sobie poradzę bez problemu, mnie chodzi głównie o to w jaki sposób ta zmienna, miałaby o tym właśnie mówić..

    Jak to możliwe, że z dość skomplikowaną sprawą drgań styków sobie poradzisz, a z operacją na jednym bicie lub całej zmiennej, już nie?
  • REKLAMA
  • #6 10763535
    john93
    Poziom 10  
    Dzięki za odpowiedzi.
    Poprawiłem kod:
    #include <avr/io.h>
    #include <util/delay.h>
     
    
    #define PRZYCISK0 _BV(0)
    #define PRZYCISK1 _BV(1)
    #define PRZYCISK2 _BV(2)
    #define PRZYCISK3 _BV(3)
    #define LED _BV(3)
    
    uint16_t on_off(void);
    
    
    int main(void)
    {
    DDRA = PRZYCISK0|PRZYCISK1|PRZYCISK2|PRZYCISK3;
    PORTA = PRZYCISK0|PRZYCISK1|PRZYCISK2|PRZYCISK3;
    DDRB |= LED;
    
     
    TCCR0 |= (1<<WGM01)|(1<<WGM00);
    TCCR0 |= (1<<COM01)|(1<<COM00);
    TCCR0 |= (1<<CS00);
     
    OCR0=255;
     
    while(1)
    {
    
    if(bit_is_clear(PINA,2)) 
    {	_delay_ms(80);
    	if(bit_is_clear(PINA,2))
    	DDRB^=LED;
    }
    
    while(bit_is_clear(PINA,1) && OCR0<255) //rozjaśniacz
    		{	_delay_ms(80);
                while(bit_is_clear(PINA,1) && OCR0<255)
    			{
                    OCR0++;
                    _delay_ms(10); 
    			}   			  
            }
    
    while(bit_is_clear(PINA,0) && OCR0>0) //ściemniacz
    		{	_delay_ms(80);
                while(bit_is_clear(PINA,0) && OCR0>0)
    			{
                    OCR0--;
                    _delay_ms(10); 
    			}   			  
            }
    
    
    
    }
    }
    
    
    
    


    Operację XOR znam, próbowałem kombinować właśnie XORem na rejestrze OCR0, ale nic sensownego nie wyszło.
    Ten myk DDR średnio się sprawdza (podobnie jak z OCR0), bo wystarczy ze chwilę dłużej przytrzyma się przycisk to dioda miga..
  • Pomocny post
    #7 10764407
    zumek
    Poziom 39  
    john93 napisał:
    ...Operację XOR znam, próbowałem kombinować właśnie XORem na rejestrze OCR0, ale nic sensownego nie wyszło.
    Faktycznie, zagalopowałem się :D
    john93 napisał:

    Ten myk DDR średnio się sprawdza (podobnie jak z OCR0), bo wystarczy ze chwilę dłużej przytrzyma się przycisk to dioda miga..

    To może ... wyłącz samopowtarzanie :?:
    Np.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #8 10764674
    john93
    Poziom 10  
    No teraz muzyka gra. :D
    Dzięki.

    A co miałeś na myśli, że przyciski są przy nieodpowiednich pinach?
    Dlaczego grozi to uszkodzeniem uP?
    _____________________________________
    edit.
    Zmieniłem teraz tylko tyle, że dioda od momentu podania zasilania nie świeci się od razu jak przedtem (zmieniłem tylko rejestr OCR0).
    Trochę zacząłem się zastanawiać nad sytuacją początkową dla kodu:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Według programu na samym starcie, dioda nie świeci prawda?
    A jednak świeci, tzn minimalnie - jakieś tam "światełko" jest. ;P
    Tylko skąd płynie przez nią jakiś tam "mikroprąd"?
    Jak można wyeliminować ten "defekt" żeby zupełnie nic od samego początku przez nią nie przechodziło?
    I pierwsze naciśnięcie wg kodu, powinno powodować jej załączenie, natomiast ma miejsce jej zgaszenie "do końca".
    Dalej dioda zachowuje się już normalnie.
  • #9 10765385
    mirekk36
    Poziom 42  
    Bo to są szpilki (glitch) o których mowa jest w nocie PDF. Tak tak to właśnie one zapewniają ten mikroprąd jak go nazwałeś ;) Aby to wyeliminować do końca zmienić fazę sygnału za pomocą bitów COMxx na przeciwną, wtedy szpilka przy maksymalnym świecieniu diody nie będzie absolutnie zauważalna. Albo można na czas wygaszania diody gdy OCR=0 wyłączać PWM i już ... a gdy większe od 0 to znowu go włączać.
  • #10 10765485
    john93
    Poziom 10  
    Jasna sprawa... Dzięki :)
REKLAMA