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

ATMega128 - Świecenie 2 diodami na raz ze zmienną częstotliwością

marines081 18 Wrz 2014 22:34 960 6
REKLAMA
  • #1 13971747
    marines081
    Poziom 10  
    Witam.
    Chciałbym prosić o pomoc w uporaniu się z problemem. Posiadam kod, który świeci "na sucho" Diodą D0, Diodą D1 po wciśnięciu klawisza na klawiaturze (zablokowane zworką na jedną kolumnę), Diodą D2 po wciśnięciu drugiego klawisza i diodą D3 po wciśnięciu 2 klawiszy na raz. Zależałoby mi na dodaniu linijki kodu, który przy pomocy 3 klawisza zaświeci 2 diody na raz, każdą o innej częstotliwości. Pozdrawiam. Mój kod poniżej:
    Spoiler:
    / Main program

    void system_init(void){
    DDRB = 0x00; //definiowanie wejscia
    PORTB = 0xFF;
    }
    int main(void) {
    system_init();
    DDRE = 0xFF; //definiowanie wyjscia
    PORTE = 0xFF; //co do podlaczenia to 4 kabelki z B dajemy do "rows" klawiatury, a z E do diod (albo na odwrot, //ale na 99% tak)

    //program mial wygladac tak: nie wcisniete nic - mruga D0, wcisniety jeden klawisz - mruga D1, Wcisniety drugi klawisz - //mruga D2, wcisniete oba - mruga D3

    while(1) {
    if((bit_is_set(PINB,0))&&(bit_is_set(PINB,1))){ //jesli zaden z przyciskow nie jest wcisniety
    PORTE = 0xff; //zgaszenie wszystkich diod
    _delay_ms(200); //opoznienie
    PORTE ^=0x01; //zapalenie D0
    _delay_ms(200); //opoznienie
    PORTE ^=0x00; //zgaszenie D0
    }

    if((bit_is_clear(PINB,0))&&(bit_is_set(PINB,1))){ //jesli pierwszy klawisz jest wcisniety, a drugi nie
    PORTE = 0xff; //identycznie jak wyzej
    _delay_ms(200);
    PORTE ^= 0x02;
    _delay_ms(200);
    PORTE ^= 0x00;

    }

    if((bit_is_clear(PINB,1))&&(bit_is_set(PINB,0))){
    PORTE = 0xff;
    _delay_ms(200);
    PORTE ^=0x04;
    _delay_ms(200);
    PORTE ^=0x00;
    }

    if((bit_is_clear(PINB,0))&&(bit_is_clear(PINB,1))){
    PORTE = 0xff;
    _delay_ms(200);
    PORTE ^=0x08;
    _delay_ms(200);
    PORTE ^=0x00;
    } // system behaviour
    }
    }


    Płytka:
    ATMega128 - Świecenie 2 diodami na raz ze zmienną częstotliwością
    Z pinów E idzie wyprowadzenie na diody, z B na klawiaturę.
  • REKLAMA
  • #2 13971770
    olelek
    Poziom 24  
    Użyj znacznika Syntax. Do takiego działania wykorzystaj Timer sprzętowy, utwórz zmienną, która przy każdym przerwaniu od timera będzie zwiększała się o 1. W pętli głównej dla każdej z diod LED sprawdzaj, czy wartość zmiennej jest podzielna przez wybrany okres mrygania:
    if(!(zmienna_licznikowa % 500)) PORTE ^=0x01;

    Powyższy kod zmieni stan diody LED co 500 przerwań timera (np. co 1ms). W ten sposób nie blokujesz mikroprocesora funkcjami _delay_ms();

    Jak widzisz, jest to trochę więcej niż 1 linijka kodu, ale nie jest to znowu takie trudne.
  • REKLAMA
  • #3 13971794
    marines081
    Poziom 10  
    Dziękuję za odpowiedź. A jeśli chodzi o wprowadzenie linii kodu na funkcjach delay, by przy pomocy 3 klawisza zaświeciły 2 diody na raz, każda o innej częstotliwości, to masz jakiś pomysł? Jestem trochę nogą w tym temacie, gdyż skupiam się na innej dziedzinie, a ta linijka kodu jest mi niezbędna do projektu. Pozdrawiam
  • #4 13971808
    olelek
    Poziom 24  
    Na Atmega128 masz 4 timery sprzętowe i aż żal ich nie wykorzystać. Program na funkcjach delay() jest maksymalnie zły i nieelastyczny, do tego stopnia że nawet nie umiem sobie wyobrazić jak by to miało być napisane.

    Podaj, z jaką częstotliwością taktujesz mikrokontroler, oraz z jakimi częstotliwościami mają migać diody.
  • REKLAMA
  • #5 13971820
    marines081
    Poziom 10  
    F_CPU 16000000UL więc mniemam, że na 16MHz. Częstotliwość migania jest obojętna. Z góry przepraszam za mój brak wiedzy i dziękuję za zaangażowanie w temat.
  • Pomocny post
    #6 13971855
    olelek
    Poziom 24  
    Kod piszę "na sucho", więc lepiej sprawdź czy działa.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Timer0 wywołuje przerwanie prawie co 1ms (dokładnie to co 1.0200 mSec). Wstaw powyższy kod do programu, w funkcji main() na początku daj wywołanie funkcji timer0_init(), a tablicą okresy_migania_ledow[4] ustalasz, jak szybko mają migać ledy. Z resztą programu myślę że sobie poradzisz.

    Poniżej masz dowód, że się da nawet dla większej ilości led'ów:


  • REKLAMA
  • #7 13971865
    marines081
    Poziom 10  
    Dziękuję. :)
    Pozdrawiam
REKLAMA