Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[ATMEGA][C] - Błąd w strukturze programu? PWM

ma85rek 05 Lut 2013 21:34 897 3
  • #1 05 Lut 2013 21:34
    ma85rek
    Poziom 2  

    Witam. Mam problem polegający na tym iż działanie programiku jest inne od zamierzonego. Otóż mam podłączone diody do wyjść Atmegi PB3 i PD7, które są sprzętowymi kanałami PWM. Za ich pomocą chcę aby podłączone diody były niezależnie od siebie w pętli rozjaśniane i ściemniane. Natomiast gdy uruchamiam ten program to jedna dioda zmienia swoją jasność tak jak powinna, a druga świeci normalnie. Próbując modyfikować program, uzyskałem co prawda efekt, że obie diody zmieniały swoją jasność, tylko że jedna po drugiej.

    Kod: c
    Zaloguj się, aby zobaczyć kod

    #include <avr/io.h>
    #include <util/delay.h>


    int main(void)
    {

    DDRB |= (1<<PB3); //kierunrk pinu PB3 - wyjście (dioda1)
    DDRD |= (1<<PD7); //kierunrk pinu PD7 - wyjście (dioda2)

    TCCR0 |= (1<<WGM01)|(1<<WGM00); //tryb Fast PWM
    TCCR0 |= (1<<COM01)|(1<<COM00); //clear OC0 at TOP
    TCCR0 |= (1<<CS00); //preskaler = 1

    TCCR2 |= (1<<WGM21)|(1<<WGM20); //tryb Fast PWM
    TCCR2 |= (1<<COM21)|(1<<COM20); //clear OC0 at TOP
    TCCR2 |= (1<<CS20); //preskaler = 1


    OCR2 = 5;
    OCR2 = 127;
    OCR2 = 255;

    OCR0 = 5;
    OCR0 = 127;
    OCR0 = 255;







    uint8_t i,a;
    while(1)

    {
    for(i=0;i<255;i++)
    {
    OCR0=i; //ściemnianie diody1
    _delay_ms(5);
    }
    for(i=255;i;i--)
    {
    OCR0=i; //rozjaśnianie diody1
    _delay_ms(5);
    }
    }



    {
    for(a=0;a<255;a++)
    {
    OCR2=a; //ściemnianie diody2
    _delay_ms(5);
    }
    for(a=255;a;a--)
    {
    OCR2=a; //rozjaśnianie diody2
    _delay_ms(5);
    }

    }


    }
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Zdaje sobie sprawę że dla zaawansowanych osób problem może być banalny jednak jako początkująca osoba proszę o wskazówki.

    0 3
  • Pomocny post
    #2 05 Lut 2013 21:39
    dondu
    Moderator Mikrokontrolery Projektowanie

    Witaj,

    ma85rek napisał:
    Próbując modyfikować program, uzyskałem co prawda efekt, że obie diody zmieniały swoją jasność, tylko że jedna po drugiej.

    Tak napisałeś program. Zanim mikrokontroler przejdzie do następnej pętli musi wykonać całą bieżącą.

    ma85rek napisał:
    Za ich pomocą chcę aby podłączone diody były niezależnie od siebie w pętli rozjaśniane i ściemniane.

    No to tak go trzeba napisać :)
    W Twoim powyższym zdaniu jest zawarta odpowiedź w postaci liczby pojedynczej słowa "pętla".

    Na razie Twój program to występujące po sobie kolejne pętle, które nigdy na raz się nie będą wykonywać.

    Zła koncepcja - musisz opracować inną.

    0
  • #3 05 Lut 2013 23:51
    ma85rek
    Poziom 2  

    nie wiem czy po "fachowemu" ale działa :) dzięki wielkie

    Kod: c
    Zaloguj się, aby zobaczyć kod

    #include <avr/io.h>
    #include <util/delay.h>


    int main(void)
    {

    DDRB |= (1<<PB3); //kierunrk pinu PB3 - wyjście (dioda1)
    DDRD |= (1<<PD7); //kierunrk pinu PD7 - wyjście (dioda2)

    TCCR0 |= (1<<WGM01)|(1<<WGM00); //tryb Fast PWM
    TCCR0 |= (1<<COM01); //clear OC0 at TOP
    TCCR0 |= (1<<CS00); //preskaler = 1

    TCCR2 |= (1<<WGM21)|(1<<WGM20); //tryb Fast PWM
    TCCR2 |= (1<<COM21)|(1<<COM20); //clear OC0 at TOP
    TCCR2 |= (1<<CS20); //preskaler = 1


    OCR2 = 5;
    OCR2 = 127;
    OCR2 = 255;

    OCR0 = 5;
    OCR0 = 127;
    OCR0 = 255;







    uint8_t i,a;
    while(1)

    {
    for(i=0,a=0;i<255,a<255;i++,a++)
    {
    OCR0=i,OCR2=a; //ściemnianie diody1 i diody2
    _delay_ms(5);
    }
    for(i=255,a=255;i,a;i--,a--)
    {
    OCR0=i,OCR2=a; //rozjaśnianie diody1 i diody2
    _delay_ms(5);
    }

    }


    }
    [/syntax]

    0
  • #4 06 Lut 2013 10:14
    BlueDraco
    Specjalista - Mikrokontrolery

    To wszystko powinno być zrobione w przerwaniu timera generującego PWM, bez żadnych "delay". Wtedy przynajmniej miałbyś determinizm czasowy działania.

    W procedurze obsługi przerwania odliczasz tyle przerwań, ile wchodzi na te 5 ms, a po odliczeniu - zmieniasz wypełnienia PWM. Wtedy rzeczywiście zmieniasz co 5 ms. Obecnie zmieniasz po 5 ms, kiedy program nie ma nic innego do roboty. Jeśli spróbujesz rozbudować program o jakiekolwiek inne funkcje, zmiany jasności będą następowały w dość losowych odstępach - tak się tego nie robi.

    W przyzwoicie napisanych programach delay może występować wyłącznie w procedurze inicjującej, nie podczas normalnej pracy.

    0