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

Atmega8 problem z wyświetlaczem LED 7 segmentowym

25 Sty 2009 09:57 3648 6
  • Poziom 33  
    Witam
    Mam banalny program, po włączaniu zasilania startuje licznik czasu, program prawie działa nie do końca dobrze.
    Atmega8 steruje wyświetlaczem LED (segmenty) z portu D, poszczególne cyfry od najbardziej znaczącej W4,W3,W2,W1 sterowane z portu B, z portu B jest też sterowanie jasnością wyświetlaczy (PWM) i buzerem.
    Ogólnie licznik liczy ale buzer mimo wyłączenie piszczy :cry: chyba w takt przemiatania cyfr i na W4 świeci się segment g (środkowa kreska) jeśli tylko na innej dowolnej cyfrze jest ona aktywna.
    Zegar jest poganiany z T2 i kwarca 32,...kHz.
    Chyba się nie wyspałem ale nie wiem dlaczego te dwa błędy wystpują.
    Code:
     'program licznika sekund, sterowanie LED 7 segmentowe
    
    $regfile = "m8def.dat"
    $crystal = 4000000
    $hwstack = 32
    $swstack = 8
    $framesize = 24


    Config Portd = Output                                       'sterowanie segmentów LED
    Config Pinb.0 = Output                                      'sterowanie W3
    Config Pinb.1 = Output                                      'sterowanie PWM
    Config Pinb.2 = Output                                      'sterowanie buzer
    Config Pinb.3 = Output                                      'sterowanie W4
    Config Pinb.4 = Output                                      'sterowanie W1
    Config Pinb.5 = Output                                      'sterowanie W2
    W1 Alias Portb.4
    W2 Alias Portb.5
    W3 Alias Portb.0
    W4 Alias Portb.2

    Dim W As Byte
    Dim Sekunda As Byte
    Dim Minuta As Byte
    Dim Nr_wysw As Byte
    Dim Cyfra4 As Byte
    Dim Cyfra3 As Byte
    Dim Cyfra2 As Byte
    Dim Cyfra1 As Byte

    Sekunda = 0
    Minuta = 0

    Config Timer0 = Timer , Prescale = 256

    'Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Up , Compare B Pwm = Disconnect , Prescale = 1
    Config Timer2 = Timer , Async = On , Prescale = 128         'generowanie przerwań od T2 co 1 sekunda
    On Timer2 Myisr
    On Timer0 Mult_wysw
    Enable Interrupts
    Enable Timer2
    Disable Timer1
    Enable Timer0
    Load Timer0 , 20
    'Pwm1a = 220
    Portb.1 = 0
    Portb.2 = 1

    Do

    Loop

    End



    Myisr:

    If Sekunda < 58 Then
       Incr Sekunda
       Else
       Sekunda = 0
       Incr Minuta
    End If

    Cyfra4 = Minuta / 10
    Cyfra3 = Minuta Mod 10
    Cyfra2 = Sekunda / 10
    Cyfra1 = Sekunda Mod 10
    Return

    Mult_wysw:
    Load Timer0 , 20
    Set W1
    Set W2
    Set W3
    Set W4

    Select Case Nr_wysw

       Case 0:
       Portd = Lookup(cyfra1 , Kody7seg)
       Reset W1

       Case 1:
       Portd = Lookup(cyfra2 , Kody7seg)
       Reset W2

       Case 2:
       Portd = Lookup(cyfra3 , Kody7seg)
       Reset W3

       Case 3:
       Portd = Lookup(cyfra4 , Kody7seg)
       Reset W4
    End Select

    Incr Nr_wysw
       If Nr_wysw = 4 Then
       Nr_wysw = 0
       End If

    Return


    Kody7seg:
    'kody cyfr
    Data &B11000000 , &B11111001 , &B10100100 , &B10110000 , &B10011001,
    Data &B10010010 , &B10000010 , &B11111000 , &B10000000 , &B10010000


    Układowo z pewnością wszystko jest OK, na tej samej płytce działa program z zestawu AVT i nie ma problemów z wyświetlaczem.
  • Poziom 28  
    Używasz PWM z wyprowadzenia PORTB.1(wyjście PWM OC1A)
    A buzer z wyprowadzenia PORTB.(wyjście PWM OC1B).
    Teraz jeśli masz włączone PWM to na tych 2 wyprowadzeniach występuje przebieg PWM i stąd sygnał na buzerze.
    Tak mi się wydaje choć masz Compare B Pwm = Disconnect, więc dla pewności na chwile podłącz buzer gdzieś do portu C, albo zmień też na COMPARE B PWM NO_OUTPUT.
  • Poziom 33  
    Witam
    Buzera chwilowo nie używam, na dodatek zegar też wyłączyłem, więc jestem zaskoczony że coś piszczy, gdyby to było samo piezo to przypuszczałbym że jakieś zakłócenia na zasilaniu przenoszą się na port, ale to buzer z własnym generatorem więc moje zaskoczenie jest pełne, nie rozumiem tego chyba że na PWM pojawiają się impulsy z innego zegara?
    A co z segmentem "g" czwartej cyfry? możliwe by czterech działań na BYTE procesor nie wykonał w sekundę i przerwania zachodzą na siebie?
    Piotr
  • Poziom 28  
    Spróbuj zwiększyć czas multipleksu wyświetlacza.Teraz jak dobrze policzyłem masz około 2ms na cyfrę.
    Zrób około 4m/cyfrę.
    Ja nie używam
    Code:
    Load Timer0 , 20


    Spróbuj bezpośrednio załadować
    Code:
    Timer0=195
    (około 4ms)

    P.S. Pod który pin masz podłączony segment G?
  • Poziom 33  
    Witam
    Segment G podpięty pod PD6, zmiana wartości w LOAD powoduje tylko zmianę częstotliwości brzęczenia buzera, na segment G nie ma wpływu, no może tylko nieznaczny na jasność, cały W4 jest lekko jaśniejszy od innych.
    Piotr
  • Poziom 28  
    A może masz podpięty programator ISP na płytce...odłącz go od układu...dziwne objawy...ale mi zagadkę zadałeś :)

    Może podłączenie W4 do PORTB.3 też ma związek z tym że ten pin też może generować(a może w twoim przypadku generuje) PWM.
    Spróbuj użyć opcji DISCONNECT dla Timera2.
  • Poziom 33  
    Witam
    Pogłębię zagadkę, procesor do programowania wyjmuję z podstawki :)
    więc nie ma wpływu programatora na działanie układu, fusy przepisałem z działającego układu z AVT więc są ok, bo tamten układ używa identycznych przerwań od zegarów i działa.
    Twoja sugestia co do PB.3 jest trafna jak mi się wydaje, bo to OC2 :) natomiast nie są to efekty timera T2 bo ten generuje przerwania co sekundę a segment G świeci bez mrugania, czyli albo T1 albo T0, aczkolwiek nie ustawiałem na żadnym z nich PWM.
    Chyba muszę pogrzebać w manualu i poustawiać to z poziomu rejestrów, dzięki za zwrócenie uwagi na PB.3
    Piotr
    EDIT
    Już wiem co trzeba ale nie wiem jak, poczytałem o rejestrach ale z poziomu BASCOMa nie wiem jak to zrobić :cry:
    T1 ma pracować w Fast PWM na wyjście OC1A, OC1B ma być normalnym wyjściem, co do OC2 niestety nic nie znalazłem, może jakiś biegły asemblerowiec mógłby pomóc jakąś wstawką?
    Cięcie płytki raczej nie wchodzi w rachubę, jeśli komuś pomoże listing w C do podobnej konfiguracji to mogę wkleić kawałek.
    Code:
    PORTB|=0b00111111;
    
        DDRB|=0b00111111;
        PORTD=255;
        DDRD=255;
        PORTC=0b11111000;
        DDRC=0b00000100;
        TCCR0=1<<CS01|1<<CS00;
        ICR1=31;
        OCR1A=0;
        TCCR1A=(1<<COM1A1)|(1<<COM1A0)|(1<<WGM11);
        TCCR1B=(1<<WGM13)|(1<<WGM12)|(1<<CS11);
        ASSR|=1<<AS2;
        OCR2=63;
        while (ASSR&(1<<OCR2UB))
          ;
        TCCR2=1<<WGM21|1<<CS22;
        while (ASSR&(1<<TCR2UB))
          ;
        TIMSK=(1<<OCIE2)|(1<<TOIE0);
        TIFR&=~((1<<OCF2)|(1<<TOV2));
        ADMUX=(1<<REFS0)|(1<<ADLAR);
        ADCSRA=(1<<ADEN)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS0);