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

BASCOM 8535: Migotanie wyświetlacza LED przy wysyłaniu danych na RS-a

ostag 31 Gru 2006 20:36 2252 13
REKLAMA
  • #1 3391900
    ostag
    Poziom 18  
    Posty: 422
    Pomógł: 23
    Ocena: 56
    Witam
    Mam problemik, po krótce opis:
    na timerze0 zrealizowan aobsługa wyświetlacza (5x 7segmentów), odczyt klawiatury i zliczanie czasu. W programie gółwnym co jakiś czas muszę wysłać coś na rs-a (sterowanie falownikiem). wszystko niby działa ale jak coś leci na rs-a to miga wyświetlaczem (potrafi zapalić ten, który jest wygaszony, całkiem nie zatrzymuje wyświetlania, zapala wygaszone segmenty). Czy jest na to jakaś rada??

    Pozdrawiam
    Grzegorz
  • REKLAMA
  • #2 3391918
    teedd
    Poziom 19  
    Posty: 219
    Pomógł: 24
    Ocena: 2
    Witam.
    Oczywiście, że jest na to rada. Ale musimy mieć o czym rozmawiać :)
    Szczęśliwego Nowego Roku - teedd
  • REKLAMA
  • #3 3391929
    ostag
    Poziom 18  
    Posty: 422
    Pomógł: 23
    Ocena: 56
    No dobra, załączam swoje wypociny (12 lat przerwy w programowaniu.... )

    $regfile = "m8535.dat"
    $crystal = 16000000
    $baud = 9600

    Config Portc = Output
    Config Pina.2 = Output 'buzer
    Config Pina.3 = Output 'katody Diod
    Config Pina.4 = Output 'w1
    Config Pina.5 = Output 'w2
    Config Pina.6 = Output 'w3
    Config Pina.7 = Output 'w4

    Config Portb = Input ' wejście klawiatury
    Set Portb 'pullup rezystory



    Config Timer0 = Timer , Prescale = 256


    Declare Sub Pobr_znaku(cyfra As Byte)

    On Timer0 Mult_wysw

    Dim A As Byte , B As Byte , C As Byte
    Dim D As Byte , E As Byte , C1 As Byte 'dane do wyświetlenia
    Dim F As Byte , O As Byte
    Dim G As Bit , H As Bit
    Dim S As Bit


    Dim Nr_wysw As Byte 'nr zapalonego wyświetlacza

    Dim Kr1 As Bit , Kr2 As Bit , Kr3 As Bit
    Dim Kr4 As Bit

    Dim Wart As Word 'liczba do wyświetlenia

    Dim Key As Byte 'zmienna klawiatury
    Dim Keytime As Word
    Dim Key2 As Bit
    Dim Key1 As Byte 'zmienna pomocnicza klawiatury
    Dim I As Byte 'zmienna do for
    Dim J As Byte 'zmienna do for

    Dim Time1 As Word ' s na przerwaniu
    Dim Time2 As Word
    Dim Time3 As Long ' minuty
    Dim Speed1 As Eram Byte
    Dim Woda1 As Eram Byte
    Dim Woda As Byte 'prędkość
    Dim Speed As Byte
    Dim Ma As Bit
    Dim Wa As Bit
    Speed = Speed1
    Woda = Woda1


    W1 Alias Porta.4
    W2 Alias Porta.5
    W3 Alias Porta.6
    W4 Alias Porta.7
    W5 Alias Porta.3

    Set Portd.5
    Time1 = 0
    Time2 = 0



    Enable Interrupts
    Enable Timer0
    Load Timer0 , 20

    'program

    H = 0
    Speed = Speed1
    Ma = Woda.1
    Wa = Woda.0

    Wait 5
    E.4 = Woda.1
    E.3 = Woda.0
    Do

    D = 17
    F = Speed \ 20
    If F = 0 Then C = 20 Else C = F
    F = F * 20
    F = Speed - F
    B = F \ 2
    F = Speed Mod 2
    A = F * 5

    F = Not Key1

    If F = 0 Then H = 0

    Reset Porta.2
    Select Case F

    Case 192: '150/300
    If H = 0 Then
    Set Porta.2
    G = Not G
    End If
    If G = 0 Then Speed = 60 Else Speed = 30
    H = 1


    Case 128: '+
    Set Porta.2
    If Key2 = 1 Then Speed = Speed + 4 Else Speed = Speed + 1
    If Speed > 180 Then Speed = 180
    If H = 1 Then Reset Porta.2

    H = 1
    Case 64: '-
    Set Porta.2
    If Key2 = 1 Then Speed = Speed - 4 Else Speed = Speed - 1
    If Speed < 10 Then Speed = 10
    If H = 1 Thenreset Porta.2
    H = 1
    Case 32: 'start
    If H = 0 Then Set Porta.2
    If S = 0 Then S = 1
    If Wa = 1 Then Set Portd.6
    If Ma = 1 Then Set Portd.5
    H = 1
    Print "start"
    Case 16: 'stop
    If H = 0 Then Set Porta.2
    S = 0
    Reset Portd.6
    Reset Portd.5
    H = 1
    Print "stop"
    Case 8: 'woda manual
    If H = 0 Then Set Porta.2
    Set Portd.6
    Do
    Loop Until Key1 <> 8
    Reset Portd.6
    H = 1
    Case 4: ' woda auto/mycie
    Time3 = 0
    Do
    Time3 = Time3 + 1
    ' Toggle E.5
    O = Not Pinb


    If Time3 > 100000 Then
    Ma = Not Ma
    E.4 = Ma
    Woda.1 = Ma
    Set Porta.2

    Exit Do
    Time3 = 200000
    End If

    Loop Until O <> 4
    If Time3 < 100000 Then
    Wa = Not Wa
    E.3 = Wa
    Woda.0 = Wa
    Set Porta.2

    End If
    Bitwait Pinb.2 , Set

    Woda1 = Woda
    Wait 1

    End Select

    '
    If Speed <> Speed1 And S = 1 Then Gosub Send

    If Speed <> Speed1 Then Speed1 = Speed 'Else



    Wait 1
    Loop



    'koniec programu
    Send:
    Print Speed
    ' wysyłanie danych do falownika
    Return






    Sub Pobr_znaku(cyfra As Byte)
    If Cyfra < 17 Then
    Portc = Lookup(cyfra , Kody7seg)
    Else
    Portc = 0
    End If
    End Sub

    Mult_wysw:
    'Disable Timer0
    Load Timer0 , 8
    Set W1
    Set W2
    Set W3
    Set W4
    Set W5
    Portd = 0
    Select Case Nr_wysw

    Case 0:

    Call Pobr_znaku(a)
    Portc.7 = Kr1
    Reset W1
    Key = Pinb
    If Key = 255 Then
    Keytime = 0
    Key2 = 0
    End If

    Case 1:

    Call Pobr_znaku(b)
    Portc.7 = Kr2
    Reset W2
    Key1 = Key And Pinb
    If Key1 = Pinb Then
    Keytime = Keytime + 1
    End If
    If Keytime > 3000 Then Key2 = 1


    Case 2:

    Call Pobr_znaku(c)
    Portc.7 = Kr3
    Reset W3

    Case 3:
    Call Pobr_znaku(d)
    Portc.7 = Kr4
    Reset W4

    Case 4:

    Portc = E
    Reset W5

    End Select
    Incr Nr_wysw
    If Nr_wysw = 5 Then
    Nr_wysw = 0
    End If

    'liczenie czasu
    Incr Time1
    If Time1 = 1501 Then
    Time1 = 0
    Incr Time2
    Toggle E.5
    End If

    'Enable Timer0
    Return

    Kody7seg:
    Data &B00111111 , &B00000110 , &B01011011 , &B01001111 , &B01100110 , &B01101101,
    Data &B01111101 , &B00000111 , &B01111111 , &B01101111 , &B01111001 , &B01111000,
    Data &B00011100 , &B01100111 , &B00111001 , &B01011100 , &B01011110

    Szczęśliwego Nowego Roku!!!
  • REKLAMA
  • #4 3391947
    teedd
    Poziom 19  
    Posty: 219
    Pomógł: 24
    Ocena: 2
    Witaj.
    Spoko - nie ma się czego wstydzić. Zaraz wybywam, ale obiecuję, że o ile będę jutro w formie, to postaram się coś pomóc.
    Wesołej zabawy - teedd

    Dodano po 28 [minuty]:

    Witaj.
    Zaraz wychodzę, ale mała rada. Kiedyś miałem coś podobnego. Spróbuj zwiększyć stos, np:
    $hwstack=40
    Pozdrowienia - teedd
  • REKLAMA
  • #5 3397947
    teedd
    Poziom 19  
    Posty: 219
    Pomógł: 24
    Ocena: 2
    Witam.
    Czy próbowałeś zwiększyć rozmiar stosu? Jak już pisałem wcześniej, miałem kiedyś taki problem. W obsłudze przerwania miałem generację liczby pseudolosowej. Zakres generowanej liczby nie pokrywał się z zadanym. Przeniesienie generacji z przerwania do pętli głównej likwidowało to dziwne zjawisko, niemniej jednak mi go nie wyjaśniało. Opisałem ten problem zarówno na tym forum, jak i na forum mcselec. W obu przypadkach dostałem podobne odpowiedzi - obsługa przerwania powinna być jak najprostsza, należy wprowadzić np. jakiś znacznik wystąpienia przerwania, śledzić go w głównej pętli i tam go obsługiwać. Dopiero zwiększenie rozmiaru stosu w stosunku do domyślnego rozmiaru (domyślnie $20) program zaczął pracować zgodnie z oczekiwaniami. Później otrzymałem wyjaśnienie problemu od AdrianJ na forum mcselec. Oto link do wątku:
    http://www.mcselec.com/index2.php?option=com_...&page=viewtopic&t=3087&highlight=
    Pozdrowienia - teedd
  • #6 3398420
    ostag
    Poziom 18  
    Posty: 422
    Pomógł: 23
    Ocena: 56
    No pomogło, ale i zaszkodziło
    Skoro to stos to nie powinno mieć to wpływu na szybkość programu, a tu zwolnienie ok 4 razy. Zwalnia tylko program główny, przerwanie działa tak samo szybko (miga diodką). Jeszcze jedna dziwna sprawa - po tej zmianie lubi zgubić dane z eeproma, wcześniej tego nie zaobserwowałem, a męczyłem go przez 2 dni.
    Dzięki za dotychczasowe porady i czekam na następne. Pozdrawiam
  • #7 3399141
    teedd
    Poziom 19  
    Posty: 219
    Pomógł: 24
    Ocena: 2
    Witam.
    No to już krok do przodu. Widzę, że używasz Mega8535 - w starym AT908535 był znany przypadek utraty danych z EEPROM - zwłaszcza z komórki o adresie 0, a tam właśnie przechowujesz zmienną SPEED1. Właśnie - przechowujesz, ale również zapisujesz. W dokumentacji Mega8535 jest opisane, w jakich przypadkach mogą wystąpić błędy związane z zapisem/odczytem EEPROM-u.
    Inną sprawą jest "spowolnienie" programu - to rzeczywiście jest bez sensu - przynajmniej dla mnie. Czym to się objawia - czemu akurat 4 razy, co się wykonuje 4 razy wolniej?
    teedd
  • #8 3399268
    ostag
    Poziom 18  
    Posty: 422
    Pomógł: 23
    Ocena: 56
    Co do eepromu to pod adresem 01 przechowuje 2 bity i one też się wysypały. o adresie 00 wiem ale jakoś to pominołem deklarując zmienne.
    W programie (nie wklejałem tego fragmentu) wyświetlam tekst "test" i następnie jest wait 10. ten czas jest już dłuższy ok 4 razy. Pętla programu też wykonuje się dużo dłużej, co widać po reakcji na przyciski.
    próbowałem też zadeklarować inną wartoś stosu, ale albo sie wykrzaczało wogóle, albo nie przynosiło żadnego rezultatu. Może mu brakować ramu??
    zmiennych w ramie jest ok 32 bajtów , wydaje mi się iż 480 bajtów na stos i inne potrzeby bascoma wystarczy. Czy do obsługi rs-a atmega potrzebuje któregoś timera? Pozdrawiam
  • #9 3399377
    teedd
    Poziom 19  
    Posty: 219
    Pomógł: 24
    Ocena: 2
    Witam.
    RAM-u nie powinno brakować, zresztą można się o tym przekonać naciskając ikonkę "rączka z kartką".
    Obsługa RS-232 nie wykorzystuje timerów, WAIT również nie.
    Spróbuj jeszcze zwiększyć $framesize i $swstack.
    Nie do końca czuję te parametry - w helpie mało o nich jest napisane, a i w praktyce mało ich używałem.
    teedd
    P.S. Jaką masz wersję Bascoma?
  • #10 3399886
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    Kolego ostag.
    Powiedz mi , dlaczego "odświeżasz" wyświetlacz z częstotliwością aż 7812.5 Hz :?: 60-100Hz na 1 cyfrę wystarczy , a u Ciebie wychodzi 1562.5Hz na cyfrę :?: Marnujesz niepotrzebnie "moce przerobowe" proca ;)
    Czy tylko to co widać w kodzie , wysyłasz RS-em :?:
    Ustaw stosy na
    
    $hwstack = 48
    $swstack = 32
    $framesize = 32
    


    Piotrek
  • #11 3401946
    ostag
    Poziom 18  
    Posty: 422
    Pomógł: 23
    Ocena: 56
    Z tym odświerzaniem to wynik eksperymentów, jakie wartości proponujesz?. Co do rs-a to jeszcze nie wybrałem konkretnego falownika, ale myśle że to będzie tylko podstawienie odpowiednich parametrów i będzie ok.
    A liczyłem warość timera tak:
    16000000Hz/256/250=250Hz (256 prescaler) na 5 wyświetlaczy
    czyli aby odliczać co 4 ms (1/250) to trzeba wpisać 6 do timer0 (256-250).
  • #12 3402817
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    ostag napisał:
    Z tym odświerzaniem to wynik eksperymentów, jakie wartości proponujesz?.

    Już pisałem 60-100 Hz. Przy 50Hz , wyświetlacze z którymi miałem do czynienia , migały kiedy patrzyło się na nie "kątem oka".
    ostag napisał:

    A liczyłem warość timera tak:
    16000000Hz/256/250=250Hz (256 prescaler) na 5 wyświetlaczy
    czyli aby odliczać co 4 ms (1/250) to trzeba wpisać 6 do timer0 (256-250).

    Przykro mi to stwierdzić , ale nie czytałeś (lub nie zrozumiałeś) , jak "działa" instrukcja Load Timer. Sprawdź proszę ponownie , opis w/w instrukcji :(

    Piotrek
  • #13 3403010
    ostag
    Poziom 18  
    Posty: 422
    Pomógł: 23
    Ocena: 56
    Tak jest napisane w "pogramowanie mikrokontrolerów avr w języku Bascom" str 181, jeśli źle zrozumiałem (nie wydaje mi się) o sorki i poproszę o prawidłowy tok liczenia, zgadzając się oczywiście na 50 Hz
  • #14 3404119
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    ostag napisał:
    Tak jest napisane w "pogramowanie mikrokontrolerów avr w języku Bascom" str 181, jeśli źle zrozumiałem (nie wydaje mi się) o sorki i poproszę o prawidłowy tok liczenia, zgadzając się oczywiście na 50 Hz

    Myślałem , że zajrzysz do pliku pomocy Bascoma :idea:
    Jeśli w książce jest napisane , że instrukcja Load Timer , X załaduje do tegoż licznika wartość X , to jest ewidentny błąd , aczkolwiek wątpię , że tak jest w istocie ;)
    Teraz krótko:
    Load Timer0 , 6 , jest równoznaczne z Counter0=(256-6) lub TCNT0=(256-6)
    W helpie jest tak:
    Load Timer , value ... It will do the calculation : (256-value)
    Czy teraz wszystko jasne :?:

    Piotrek

Podsumowanie tematu

✨ Problem dotyczy migotania wyświetlacza LED (5x 7-segmentów) sterowanego przez timer0 w mikrokontrolerze Atmega8535 podczas wysyłania danych przez interfejs RS-232 do falownika. Migotanie objawia się zapalaniem wygaszonych segmentów i cyfr. Wskazano, że przyczyną mogą być błędy w obsłudze przerwań oraz niewłaściwe zarządzanie stosem. Zalecano zwiększenie rozmiaru stosu sprzętowego ($hwstack), stosu programowego ($swstack) oraz rozmiaru ramki ($framesize) w Bascom AVR, co częściowo pomogło, ale spowodowało spowolnienie działania programu głównego i problemy z zapisem danych do EEPROM, szczególnie pod adresami 0 i 1. Dyskutowano także o optymalnej częstotliwości odświeżania wyświetlacza – zalecane jest 60-100 Hz na cyfrę, a nie kilkukrotnie wyższe wartości, które marnują zasoby procesora i mogą powodować problemy z wyświetlaniem. Omówiono także prawidłowy sposób ładowania timera w Bascom AVR, gdzie instrukcja Load Timer0, X ustawia licznik na (256 - X), co wpływa na częstotliwość przerwań i odświeżania wyświetlacza. Wskazano, że obsługa RS-232 nie wymaga timerów, a funkcja WAIT nie powinna wpływać na prędkość programu. Problemy z EEPROM mogą wynikać z błędów w zapisie/odczycie zgodnie z dokumentacją Atmega8535. Sugerowano uproszczenie obsługi przerwań poprzez ustawianie flag i obsługę ich w pętli głównej zamiast wykonywania złożonych operacji w przerwaniu.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA