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

multipleksacja 3 wyświetlaczy w [C] - mrugająca "setka&

Tymek92 26 Maj 2009 00:24 1187 6
REKLAMA
  • #1 6575500
    Tymek92
    Poziom 10  
    Otóż mam taki kod programu który ma za zadanie liczyć do 999:

    #define FCPU 1000000
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>
    #define dziesiatkiON PORTB |=_BV(1);
    #define dziesiatkiOFF PORTB &= ~_BV(1);
    #define jednosciON PORTB |=_BV(2);
    #define jednosciOFF PORTB &=~_BV(2);
    #define setkiON PORTB |=_BV(0);
    #define setkiOFF PORTB &=~_BV(0);
    char x [10] = {0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9};
    volatile i;
    volatile wyswietlacz;
    volatile jednosci;
    volatile dziesiatki;
    volatile setki;
    volatile liczba;
    int wysw_dziesiatki;
    int wysw_jednosci;
    
    int main()
    {
    DDRB = 0xFF; // Ustawienie bitu LED jako wyjścia
    TCCR1B |= (1 << WGM12); // Ustawia timer w tryb CTC
    OCR1A = 3333; // Ustawia wartość pożądaną na 1Hz dla preskalera 64
    TCCR1B |= (1 << CS10); // Ustawia timer z preskalerem Fcpu/256
    TIMSK |= (1 << OCIE1A); // Zezwolenie na przerwania dla CTC
    sei(); // Zezwolenie globalne na przerwania
    DDRC = 0xFF;
    PORTC = 0x00;
    PORTB = 0x00;
    wyswietlacz=0;
    
    
    
    
    while(1)
    {
    dziesiatki = (liczba/10)%10;
    jednosci = liczba%10;
    setki = liczba/100;
    PORTB |=_BV(0);
    
     if (liczba == 999) 
    {
    liczba = 0;
    } 
    else
    {
    _delay_ms(100);
    liczba++;
    }
    
    
    }
    }
    ISR(TIMER1_COMPA_vect)
    {
    switch (i)
    {
    	case 2:
    		dziesiatkiOFF;
    		jednosciOFF;
    		setkiON;
    		PORTC = x[setki];
    		i=0;
    		break;
    	case 1:
    		jednosciOFF;
    		setkiOFF;
    		dziesiatkiON;
    		PORTC = x[dziesiatki];
    		i++;
    		break;
    	case 0:
    
    		dziesiatkiOFF;
    		setkiOFF;
    		jednosciON;
    		PORTC = x[jednosci];
    		i++;
    		setkiOFF;
    		break;
    		
    }
    
    }
    
    

    Problem jest taki ze dziesiątki i jedności działają poprawnie a na setkach są "przebicia" z tych dwóch poprzednich. moje pytanie brzmi jak to wyeliminować?? Gdy działają tylko 2 wyświetlacze wszystko jest OK. Kombinowałem już przestawianiem, opóźnieniem i nic. Proszę o pomoc.
  • REKLAMA
  • #2 6575787
    Konto nie istnieje
    Konto nie istnieje  
  • REKLAMA
  • #3 6578746
    Tymek92
    Poziom 10  
    Niestety to co napisałeś albertb nie sprawdza się ;/
    korzystam z Atmega8.
    Czy ma ktoś pomysł jak wyeliminować mruganie "setek" ??
  • #4 6578882
    Ravender
    Poziom 20  
       case 0:
    
          dziesiatkiOFF;
          setkiOFF;
          jednosciON;
          PORTC = x[jednosci];
          i++;
          setkiOFF;     <-------------- A TO TU PO CO?
          break; 


    Wydaje mi się również, że masz za duży przeplot. Obecnie jest to około 100Hz na wyświetlacz.. Zmień 3333 na 6666 to będizesz miał jakieś 50Hz.

    A ogólnie to najlepiej narazie zmniejsz prędkość na jak mniejszczą (np jedną sekundę) i obserwuj co się dzieje na wyświetlaczach
  • REKLAMA
  • #5 6579053
    rpal
    Poziom 27  
    Ravender napisał:

    A ogólnie to najlepiej narazie zmniejsz prędkość na jak mniejszczą (np jedną sekundę) i obserwuj co się dzieje na wyświetlaczach

    Miałem to samo napisać. Gdy odpałem ostatnio LCD właśnie tak postąpiłem. Ustawiłem długi okres wybierania cyfry i ustawiłem któryś z segmentów. Po kolei robiąc do dla wszystkich segmentów, raz sprawdziłem jak się sprawuje w ogóle wyświetlanie konkretnej cyfry a dwa wytestowałem czy nei ma jakiś zwarć. Tobie też to radzę. W kwesti zasadniczego wyświetlania, to w sumie prosta sprawa. Bo definiujesz sobei w pamięci jakiś bufor (o datkiej długości ile masz cyfr). W buforze zapisujesz obraz segmentów odwzorowany w pamięci czyli już po zamianie z wartości liczbową na taką która jest odpowiednia dla segmentów od a - g + kropka.
    Przerwanie licznika wybiera konkretna cyfrę, jednocześnie wysyłąjąc na port odpowiedzialny za zapalanie lub gaszenie segmentów konkretną danę z bufora. Wskażniki tu się bardzo dobrze spisują. Nie ma znaczenia co będzie pierwsze wybór cyfry czy obraz segmentó z bufora i tak oko tego nie zauważy.
  • REKLAMA
  • Pomocny post
    #6 6579938
    Konto nie istnieje
    Konto nie istnieje  
  • #7 6581057
    Tymek92
    Poziom 10  
    Dzięki Albert. Nie mogłem tego zauważyć ;/ to jest pozostałość po diodzie która wcześniej coś sygnalizowała... już działa wyśmienicie :)
REKLAMA