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

[atmega8][bascom] 7seg LED sterowanie z PORTB i PoC <<

mozgh 16 Sty 2009 23:43 6612 18
REKLAMA
  • #1 6010215
    mozgh
    Poziom 11  
    Witam.

    Na wstępie przepraszam za mało czytelną nazwę w temacie ale nie wiedziałem jak inaczej opisać mój problem w tak małej ilości znaków.

    Temat powinien brzmieć: [atmega8][bascom] Sterowanie 7-segmentowym wyświetlaczem LED przy pomocy portów B i C z odpowiednim przesunięciem bitowym. Próba rozwiązania problemu z mutipleksacją LED i odczytem z 1wire.

    Opiszę delikatnie założenia, z których wychodzę i co chciałbym uzyskać, a także czym już dysponuje.

    Chciałbym zbudować w oparciu o ATMEGA8 termometr z zegarkiem i zaprogramować go w języku BASCOM, a po przetestowaniu tego rozwiązania, spróbować napisać to samo w C. Układ dodatkowo musi co jakiś mały odstęp czasu wysyłać aktualną temperaturę z DSa lub klilku poprzez UART. A jako wzór czasu do zegarka będzie miał podłączony rezonator kwarcowy (zegarkowy).

    Do ATMEGA8 mam podłączone następujące elementy (wszystko na płytce prototypowej):

    - Tranzysotry do multipleksu są sterowane z PORTB.0 do PORTB.3.

    - Przyciski mają być na PORTB.4 i PORTB.5.

    - wyświetlacz LED 4x7-seg. Sterowanie wyświetlaniem cyfr odbywa się na portach PORTD.2 do PORTD.7 (linie do A do F) i PORTC.4, PORTC.5 (linie do G i DP).


    Zdecydowałem się na takie podłączenie wyświetlacza, gdyż:

    a. chciałem mieć możliwość wykorzystania UARTa na portach PD0 i PD1, więc z tego powodu nie mogłem sterować LEDem z całego PORTD.

    b. chciałem mieć możliwość podłączenia zew. rezonatora kwarcowego więc nie mogłem wykorzystać PB.6 i PB.7 no i z tego powodu PORTB odpadł.

    Aktualnie walczę z następującym problemem.

    Jak przy włączonym wyświetlaniu LED w multipleksie na timer0 zsynchronizować transmisje 1wire, aby nie pojawiały się błędy podczas odczytu danych raz na (20-40sek lub czasami częściej)

    Próbowałem sprawdzać wartość Timer0 przed przejściem w tryb komunikacji na 1wire. Ale nie udaje mi się dobrać odpowiedniej wartości. Albo źle podchodzę do tematu.

    Nie wiem również czy przy wyłączeniu przerwań podczas transmisji 1wire uda mi się utrzymywać np. timer1, który będzie pracował w oparciu o zbocze opadające zew. kwarcu.

    Czy, któryś z kolegów mogłby podpowiedzieć jak (i czy w ogóle) można usunąć błędy odczytu 1wire w takim projekcie i dodatkowo mieć stabilną współpracę z zew. rezonatorem kwarcowym, który ma być wzorcem czasu.

    Z góry dziękuje za wszelkie sugestie.

    Poniżej zamieszczam kod programu:

    
    $regfile = "m8def.dat"
    $crystal = 8000000
    $baud = 9600
    
    '-- Wejscia przycisków
    Config Portb.4 = Input
    Config Portb.5 = Input
    
    ' -- podciągnięcie
    Set Portb.4
    Set Portb.5
    
    ' -- porty sterowania segmentami LED
    Config Portd = Output
    Config Portc.5 = Output
    Config Portc.4 = Output
    
    ' -- tranzystory
    Config Portb.0 = Output
    Config Portb.1 = Output
    Config Portb.2 = Output
    Config Portb.3 = Output
    
    
    T4 Alias Portb.0
    T3 Alias Portb.1
    T2 Alias Portb.2
    T1 Alias Portb.3
    
    S1 Alias Pinb.4
    S2 Alias Pinb.5
    
    Wyswietlacz1 Alias Portd
    Wyswietlacz2 Alias Portc
    
    Declare Sub Rozloz
    Declare Sub Ds18b20
    
    Config 1wire = Portc.3
    
    '--- zmienne
    Dim A As Byte
    Dim Cyfra1 As Integer
    Dim Cyfra2 As Integer
    Dim Cyfra3 As Integer
    Dim Cyfra4 As Integer
    
    Dim Temp As Integer
    Dim Temp1 As Integer
    
    Dim T(9) As Byte
    
    Dim Bd As Integer
    Dim Ulamek As Integer
    Dim Calosc As Integer
    
    Dim Jakitimer0 As Byte
    
    Dim Symbol As Byte
    
    Dim I As Integer
    
    '-- przerwania
    Config Timer0 = Timer , Prescale = 64
    'Config Timer1 = Timer , Prescale = 1                        'konfiguracja liczników
    Enable Interrupts
    Enable Timer0
    On Timer0 Tajmer1
    
    
    Print "start programu"
    
    Cls
    
    I = 5
    
    Do
    
       Call Ds18b20
    
       Temp = Calosc
       Temp1 = Ulamek
       Call Rozloz
    
       Print "I = " ; I ; " Temperatura = " ; Calosc ; "." ; Ulamek ; " 'C" ; " Timer0 = " ; Timer0 ; " JakiTimer = " ; Jakitimer0
    
    Loop
    
    Sub Ds18b20
    
    
    If Timer0 =< 180 Then
    
    Jakitimer0 = Timer0
    
    Disable Interrupts
       1wreset
       1wwrite &HCC
       1wwrite &H44
    Enable Interrupts
    
       Waitms 750                                               'czas konwersji 750 ms
    
    Disable Interrupts
       1wreset
       1wwrite &HCC
       1wwrite &HBE
    Enable Interrupts
    
       T(1) = 1wread(9)
    
    
       If Err = 1 Then
          Wait 1
          Print "ERROR"
          Exit Sub
       End If
    
       Bd = Makeint(t(1) , T(2))
       Bd = Bd * 10
       Bd = Bd / 16
    
       Ulamek = Bd Mod 10
       Calosc = Bd / 10
    Else
       Jakitimer0 = Timer0
       Incr I
       Timer0 = 50
    End If
    
    End Sub
    
    '-- rozkladanie liczby na cyfry
    'Sub Rozloz
    '
    'Cyfra4 = Temp / 1000
    '
    'Temp = Temp Mod 1000
    '
    'Cyfra3 = Temp / 100
    '
    'Temp = Temp Mod 100
    '
    'Cyfra2 = Temp / 10
    '
    'Cyfra1 = Temp Mod 10
    '
    ''If Znaczek = 1 Then Cyfra4 = 14
    '''Else
    '''   Cyfra3 = Temp / 100
    '''End If
    '
    'End Sub
    
    Sub Rozloz
    
    
    If Err = 0 Then
       Temp = Temp Mod 100
    
       Cyfra4 = Temp / 10
    
       Cyfra3 = Temp Mod 10
    
       Cyfra2 = 16
    
       Cyfra1 = Temp1 Mod 10
    Else
       Cyfra4 = 10
       Cyfra3 = 11
       Cyfra2 = 11
       Cyfra1 = 11
    End If
    
    End Sub
    
    '---------------------- obsluga przerwania
    Tajmer1:
    
    Incr A
    If A = 4 Then A = 0
    
    Set T1
    Set T2
    Set T3
    Set T4
    
    Select Case A
    Case 0:
    Symbol = Lookup(cyfra1 , Dta)
    Wyswietlacz1 = Symbol * 4
    
    Symbol = Lookup(cyfra1 , Dta)
    Wyswietlacz2 = Symbol / 4
    
    Reset T1
    
    Case 1:
    
    Symbol = Lookup(cyfra2 , Dta)
    Wyswietlacz1 = Symbol * 4
    
    Symbol = Lookup(cyfra2 , Dta)
    Wyswietlacz2 = Symbol / 4
    
    'If Cyfra2 <> 0 Then Wyswietlacz = Lookup(cyfra2 , Dta)
    'Wyswietlacz = Lookup(cyfra2 , Dta)
    
    
    Reset T2
    
    Case 2:
    
    Symbol = Lookup(cyfra3 , Dta)
    Wyswietlacz1 = Symbol * 4
    
    Symbol = Lookup(cyfra3 , Dta)
    Wyswietlacz2 = Symbol / 4
    
    
    Reset T3
    
    Case 3:
    
    Symbol = Lookup(cyfra4 , Dta)
    Wyswietlacz1 = Symbol * 4
    
    Symbol = Lookup(cyfra4 , Dta)
    Wyswietlacz2 = Symbol / 4
    
    
    Reset T4
    
    End Select
    
    Return
    '---- koniec przerwania
    
    Dta:
    ' SEKWENCJA .GFEDCBA
    ' SEKWENCJA 11111111
    Data &B11000000 , &B11111001 , &B10100100 , &B10110000 , &B10011001
    Data &B10010010 , &B10000010 , &B11111000 , &B10000000 , &B10010000
    Data &B10000110 , &B11001110 , &B11110001 , &B11000111
    Data &B10111111 , &B11110111 , &B11101111
    'Data &B10000110
    
    
  • REKLAMA
  • Pomocny post
    #2 6010264
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • #3 6010879
    mozgh
    Poziom 11  
    Atom dzięki, że zwróciłeś mi uwagę na 1wread. Wcześniej wyłączałem przerwania na każdej komendzie 1wire, ale podczas testów i modyfikacji programu zapomniałem tego wstawić z powrotem.

    Jak dopiszę kod do obsługi Timer1 i kwarcu to się odezwę czy to działa jak powinno.
  • #4 6013576
    mozgh
    Poziom 11  
    Zmieniłem troszkę podłączenia wyświetlacza LED do atmegi.

    Teraz z mam tak:

    PORTD.4 = segment A
    PORTD.5 = segment B
    PORTD.6 = segment C
    PORTD.7 = segment D

    PORTC.2 = segment E
    PORTC.3 = segment F
    PORTC.4 = segment G
    PORTC.5 = segment DP

    Do portów XTAL1 i XTAL2 mam podłączony rezonator 32kHZ.

    Układ prawidłowo wyświetla temperaturę i przekazuje na UART zaprogramowany czas z zegarka.

    Jednak mam problem, który wiedziałem że wreszcie napotkam.

    Przy przesunięciu bitowym danych, na portach PORTC i PORTB, tak naprawdę wykorzystuje 2 porty. Tylko że część portów podczas tej operacji zeruje. Do tej pory nie miałem z tym problemu (UART i 1wire działa ok), ale teraz kiedy chce wykorzystać INT0 i INT1 do obsługi przycisków mam problem.

    Ciągłe ustawianie PORTB od 0 do 3 na "ZERO". Nie oddziaływuje widocznie na UART, ale generuje fałszywe wyzwolenia przerwania INT0 i INT1. I po konfiguracji INT0 program odrazu się zapętla, po uruchomieniu.

    Funkcja DEBOUNCE do obsługi zdarzeń z przycisków, również wariuje. Co chwile zmienna OPCJA zmienia wartość na mniejszą lub większą, co oznacza ze jest wykonywany skok do Switch1: i Switch2:.

    Czy zna ktoś jakiś elegancki i skuteczny sposób na sterowanie 8-segmentowym wyświetlaczem LED przy pomocy 8 linii ale z różnych portów mikrokontrolera.

    W moim przypadku nie mogę wykorzystać całego portu B lub D, gdyż potrzebuje niektórych linii do innego celu.

    Przesunięcie bitowe w lewo i prawo rozwiązuje problem częściowo, gdyż znaki wyświetlane są prawidłowo, ale niepotrzebnie zmienia status reszty portów ciągle na 0.

    
    Poniżej aktualny kod programu.
    $regfile = "m8def.dat"
    $crystal = 8000000
    $baud = 9600
    
    '-- Wejscia przycisków
    Config Portb.5 = Input
    Config Portb.4 = Input
    
    ' -- podciągnięcie
    Set Portb.5
    Set Portb.4
    
    ' -- porty sterowania segmentami LED
    Config Portd.4 = Output
    Config Portd.5 = Output
    Config Portd.6 = Output
    Config Portd.7 = Output
    
    Config Portc.5 = Output
    Config Portc.4 = Output
    Config Portc.3 = Output
    Config Portc.2 = Output
    
    ' -- tranzystory
    Config Portb.0 = Output
    Config Portb.1 = Output
    Config Portb.2 = Output
    Config Portb.3 = Output
    
    
    T4 Alias Portb.0
    T3 Alias Portb.1
    T2 Alias Portb.2
    T1 Alias Portb.3
    
    S1 Alias Pinb.5
    S2 Alias Pinb.4
    
    Wyswietlacz1 Alias Portd
    Wyswietlacz2 Alias Portc
    
    Declare Sub Rozloz
    Declare Sub Ds18b20
    
    Config 1wire = Portc.1
    
    '--- zmienne
    Dim A As Byte
    Dim Cyfra1 As Integer
    Dim Cyfra2 As Integer
    Dim Cyfra3 As Integer
    Dim Cyfra4 As Integer
    
    Dim Temp As Integer
    Dim Temp1 As Integer
    
    Dim T(9) As Byte
    
    Dim Bd As Integer
    Dim Ulamek As Integer
    Dim Calosc As Integer
    
    Dim Jakitimer0 As Byte
    
    Dim Symbol As Byte
    
    Dim I As Integer
    Dim I1 As Integer
    
    Dim Bledy As Integer
    
    Dim Opcja As Bit
    
    Dim Czas As Integer
    
    '-- przerwania
    Enable Interrupts
    
    Config Timer0 = Timer , Prescale = 64
    Enable Timer0
    On Timer0 Tajmer0
    
    Config Timer1 = Timer , Prescale = 1024
    Enable Timer1
    On Timer1 Tajmer1
    
    '[now init the clock]
    Config Date = Dmy , Separator = /
    Config Clock = Soft
    
    'Enable Int0
    'On Int0 Switch1
    
    'Enable Int1
    'On Int1 Switch2
    
    
    Date$ = "17/01/09"
    Time$ = "20:47:00"
    
    Print "start programu"
    
    Cls
    
    I = 0
    
    Do
    
    
       Call Ds18b20
    
       Temp = Calosc
       Temp1 = Ulamek
    
       Debounce S1 , 0 , Switch1 , Sub
       Debounce S2 , 0 , Switch2 , Sub
    
    
       Call Rozloz
    
       Print "I1= " ; I1 ; " bledy = " ; Bledy ; " Temperatura = " ; Calosc ; "." ; Ulamek ; " 'C" ; " OPCJA = " ; Opcja
       Print Date$ ; " : " ; Time$ ; " | " ; _hour ; ":" ; _min ; ":" ; _sec
    
    Loop
    
    Switch1:
    
       Toggle Opcja
    
    Return
    
    Switch2:
    
       Toggle Opcja
    
    Return
    
    Sub Ds18b20
    
    Jakitimer0 = Timer0
    
    Disable Interrupts
       1wreset
       1wwrite &HCC
       1wwrite &H44
    Enable Interrupts
    
       Waitms 750                                               'czas konwersji 750 ms
    
    Disable Interrupts
       1wreset
       1wwrite &HCC
       1wwrite &HBE
    Enable Interrupts
    
    Disable Interrupts
       T(1) = 1wread(9)
    Enable Interrupts
    
    
       If Err = 1 Then
          'Wait 1
          Print "ERROR-2"
          Incr Bledy
          Exit Sub
       End If
    
       Bd = Makeint(t(1) , T(2))
       Bd = Bd * 10
       Bd = Bd / 16
    
       Ulamek = Bd Mod 10
       Calosc = Bd / 10
    
    End Sub
    
    
    Sub Rozloz
    
    Select Case Opcja
    
    Case 0:
    If Err = 0 Then
       Temp = Temp Mod 100
    
       Cyfra4 = Temp / 10
    
       Cyfra3 = Temp Mod 10
    
       Cyfra2 = 16
    
       Cyfra1 = Temp1 Mod 10
    Else
       Cyfra4 = 10
       Cyfra3 = 11
       Cyfra2 = 11
       Cyfra1 = 12
    End If
    
    Case 1:
        Czas = _hour
        Czas = Czas Mod 100
    
        Cyfra4 = Czas / 10
        Cyfra3 = Czas Mod 10
    
        Czas = _min
        Czas = Czas Mod 100
    
        Cyfra2 = Czas / 10
        Cyfra1 = Czas Mod 10
    
    End Select
    
    End Sub
    
    '------ obsluga przerwania TIMER0
    Tajmer0:
    
    Incr A
    If A = 4 Then A = 0
    
    Set T1
    Set T2
    Set T3
    Set T4
    
    Select Case A
    Case 0:
    Symbol = Lookup(cyfra1 , Dta)
    Wyswietlacz1 = Symbol * 16
    
    Symbol = Lookup(cyfra1 , Dta)
    Wyswietlacz2 = Symbol / 4
    
    If Opcja = 1 Then Portc.5 = 0
    
    Reset T1
    
    Case 1:
    
    Symbol = Lookup(cyfra2 , Dta)
    Wyswietlacz1 = Symbol * 16
    
    Symbol = Lookup(cyfra2 , Dta)
    Wyswietlacz2 = Symbol / 4
    
    'If Cyfra2 <> 0 Then Wyswietlacz = Lookup(cyfra2 , Dta)
    'Wyswietlacz = Lookup(cyfra2 , Dta)
    
    If Opcja = 1 Then Portc.5 = 0
    
    Reset T2
    
    Case 2:
    
    Symbol = Lookup(cyfra3 , Dta)
    Wyswietlacz1 = Symbol * 16
    
    Symbol = Lookup(cyfra3 , Dta)
    Wyswietlacz2 = Symbol / 4
    
    
    Reset T3
    
    
    Case 3:
    
    Symbol = Lookup(cyfra4 , Dta)
    Wyswietlacz1 = Symbol * 16
    
    Symbol = Lookup(cyfra4 , Dta)
    Wyswietlacz2 = Symbol / 4
    
    Reset T4
    
    End Select
    
    Return
    '---- koniec przerwania Timer0
    
    '---- TIMER1
    Tajmer1:
       Incr I1
    Return
    
    Dta:
    ' SEKWENCJA .GFEDCBA
    ' SEKWENCJA 11111111
    Data &B11000000 , &B11111001 , &B10100100 , &B10110000 , &B10011001
    Data &B10010010 , &B10000010 , &B11111000 , &B10000000 , &B10010000
    Data &B10000110 , &B10101111 , &B10100011 , &B11000111
    Data &B10111111 , &B11110111 , &B11101111
    'Data &B10000110
    
  • Pomocny post
    #5 6013863
    Konto nie istnieje
    Poziom 1  
  • #6 6014999
    mozgh
    Poziom 11  
    Atom mogłbyś wyjaśnić ten kawałek kodu:

    
    In R16, Wyswietlacz1                                        
    andi R16, &B00001111                                        
    Lds R17, {Wyswietlacz1_2}                                   
    !or R16, R17                                                
    !Out Wyswietlacz1, R16
    


    Wygląda intrygująco... to jakaś ASMowa wstawka ?
  • REKLAMA
  • Pomocny post
    #7 6015094
    Konto nie istnieje
    Poziom 1  
  • #8 6017301
    mozgh
    Poziom 11  
    Atom, dziękuje ci bardzo za pomoc.

    Dzięki tej asemblerowej wstawce bez problemu mogę obsługiwać teraz INT0 i INT1. Nie mam pomysłu jeszcze jak zrobić obsługę 4 przycisków, ale i z dwoma przyciskami już coś można powalczyć. Na ATMEGA8 zostały mi wolne linie:

    PORTB.0
    PORTB.1

    PORTC.0

    Aktualnie poniższy kod:

    Pokazuje na przemian temperaturę i czas. Wybór opcji, co ma wyświetlać "toggluje" timer1 :).

    Dłuższym przytrzymaniem S1 zmienia się opcje menu do przodu, dłuższym S2 do tylu.

    S1 naciśnięty krótko zmienia parametr na +1, S2 naciśnięty krótko zmienia parametr -1.

    Obsługa przycisków nie jest najszczęśliwsza, ale nie mam pomysłu jak to zrobić inaczej.

    Opm= widoczny poprzez UART oznacza wybór opcji menu. Opm = 3 to ustawianie minut, Opm = 4 ustawianie godzin.

    Aktualnie bawię się na DEMO wersji BASCOM, więc kod tnę ile mogę aby mieścił się w 4kb.

    Jestem otwarty na wszelkie propozycje odnośnie tego kodu (Zegarko-Termometru-LED)

    Atom jeszcze raz dziękuje. :)

    
    $regfile = "m8def.dat"
    $crystal = 8000000
    $baud = 9600
    
    '-- Wejscia przycisków
    Config Portd.2 = Input
    Config Portd.3 = Input
    
    ' -- podciągnięcie
    Set Portd.2
    Set Portd.3
    
    ' -- porty sterowania segmentami LED
    Config Portd.4 = Output
    Config Portd.5 = Output
    Config Portd.6 = Output
    Config Portd.7 = Output
    
    Config Portc.5 = Output
    Config Portc.4 = Output
    Config Portc.3 = Output
    Config Portc.2 = Output
    
    ' -- tranzystory
    Config Portb.0 = Output
    Config Portb.1 = Output
    Config Portb.2 = Output
    Config Portb.3 = Output
    
    
    T4 Alias Portb.2
    T3 Alias Portb.3
    T2 Alias Portb.4
    T1 Alias Portb.5
    
    S1 Alias Pind.2
    S2 Alias Pind.3
    
    Wyswietlacz1 Alias Portd
    Wyswietlacz2 Alias Portc
    
    '-- pomysl i realizacja atom1477 (forum elektroda)
    Dim Wyswietlacz1_2 As Byte
    Dim Wyswietlacz2_2 As Byte
    
    
    Declare Sub Rozloz
    Declare Sub Ds18b20
    Declare Sub Przyciski
    Declare Sub Menu
    
    '-- 1wire
    Config 1wire = Portc.1
    
    '--- zmienne
    Dim A As Byte
    Dim Cyfra1 As Integer
    Dim Cyfra2 As Integer
    Dim Cyfra3 As Integer
    Dim Cyfra4 As Integer
    
    Dim Temp As Integer
    Dim Temp1 As Integer
    
    Dim T(9) As Byte
    
    Dim Bd As Integer
    Dim Ulamek As Integer
    Dim Calosc As Integer
    
    Dim Symbol As Byte
    Dim Czas As Integer
    
    Dim I1 As Integer
    
    Dim Bledy As Integer
    
    Dim Opcja As Bit
    
    Dim Opcjas As Integer
    Dim Opcjam As Byte
    Dim Przycisniecie1 As Bit
    Dim Przycisniecie2 As Bit
    
    Dim Zm As Bit
    
    Dim I As Byte
    
    '-- przerwania
    Enable Interrupts
    
    '-- timer0 multiplex LED
    Config Timer0 = Timer , Prescale = 64
    Enable Timer0
    On Timer0 Tajmer0
    
    '-- timer1 narazie toggle jeden zmiennej
    Config Timer1 = Timer , Prescale = 1024
    Enable Timer1
    On Timer1 Tajmer1
    
    '-- timer2 czas
    Config Date = Dmy , Separator = /
    Config Clock = Soft
    
    '-- obsluga przyciskow
    Enable Int0
    On Int0 Switch1
    
    '-- obsluga przyciskow
    Enable Int1
    On Int1 Switch2
    
    Date$ = "18/01/09"
    Time$ = "14:57:01"
    
    Print "."
    
    Cls
    
    
    Do
    
       Call Przyciski
    
       Call Menu
    
       Call Ds18b20
    
       Temp = Calosc
       Temp1 = Ulamek
    
       Call Rozloz
    
       Print "I1=" ; I1 ; " Bl=" ; Bledy ; " Te=" ; Calosc ; "." ; Ulamek ; " 'C" ; " OP=" ; Opcja
       Print _hour ; ":" ; _min ; ":" ; _sec
       Print "Ops = " ; Opcjas ; " Opm = " ; Opcjam
    
    Loop
    
    Switch1:
       Disable Int0
       Przycisniecie1 = 1
       Incr Opcjas
    
       Call Menu
    
    Return
    
    Switch2:
       Disable Int1
       Przycisniecie2 = 1
       Decr Opcjas
    
       Call Menu
    
    Return
    
    Sub Menu
    
       If Opcjam = 3 Then
          If Zm = 0 Then
             Opcjas = _min
             Zm = 1
          Else
             If Opcjas >= 60 Then Opcjas = 0
             _min = Opcjas
             Zm = 0
          End If
       End If
    
       If Opcjam = 4 Then
          If Zm = 0 Then
             Opcjas = _hour
             Zm = 1
          Else
             If Opcjas >= 24 Then Opcjas = 0
             _hour = Opcjas
             Zm = 0
          End If
       End If
    
    
    End Sub
    
    Sub Przyciski
    
       If Przycisniecie1 = 1 Then
    
          Przycisniecie1 = 0
    
       I = 0
    
       Do
    
          Incr I
          Waitms 10
    
       Loop Until S1 = 1 Or I >= 100
    
       If I >= 100 Then Incr Opcjam
    '   If I < 100 Then Incr Opcjas
    
       Enable Int0
    
       End If
    
       If Przycisniecie2 = 1 Then
    
          Przycisniecie2 = 0
    
       I = 0
    
       Do
          Incr I
          Waitms 10
    
       Loop Until S2 = 1 Or I >= 100
    
       If I >= 100 Then Decr Opcjam
     '  If I < 100 Then Decr Opcjas
    
       Enable Int1
    
       End If
    
    End Sub
    
    Sub Ds18b20
    
       Disable Interrupts
          1wreset
          1wwrite &HCC
          1wwrite &H44
       Enable Interrupts
    
          Waitms 750                                            'czas konwersji 750 ms
    
       Disable Interrupts
          1wreset
          1wwrite &HCC
         1wwrite &HBE
       Enable Interrupts
    
       Disable Interrupts
          T(1) = 1wread(9)
       Enable Interrupts
    
       If Err = 1 Then
          'Wait 1
          Print "ERROR-2"
          Incr Bledy
          Exit Sub
       End If
    
       Bd = Makeint(t(1) , T(2))
       Bd = Bd * 10
       Bd = Bd / 16
    
       Ulamek = Bd Mod 10
       Calosc = Bd / 10
    
    End Sub
    
    
    ''If Znaczek = 1 Then Cyfra4 = 14
    '''Else
    '''   Cyfra3 = Temp / 100
    '''End If
    
    Sub Rozloz
    
    Select Case Opcja
    
    Case 0:
       If Err = 0 Then
          Temp = Temp Mod 100
    
          Cyfra4 = Temp / 10
    
          Cyfra3 = Temp Mod 10
    
          Cyfra2 = 16
    
          Cyfra1 = Temp1 Mod 10
       Else
          Cyfra4 = 10
          Cyfra3 = 11
          Cyfra2 = 11
          Cyfra1 = 12
       End If
    
    Case 1:
        Czas = _hour
        Czas = Czas Mod 100
    
        Cyfra4 = Czas / 10
        Cyfra3 = Czas Mod 10
    
        Czas = _min
        Czas = Czas Mod 100
    
        Cyfra2 = Czas / 10
        Cyfra1 = Czas Mod 10
    
    End Select
    
    End Sub
    
    '------ obsluga przerwania TIMER0
    Tajmer0:
    
    Incr A
    If A = 4 Then A = 0
    
    Set T1
    Set T2
    Set T3
    Set T4
    
    Select Case A
    Case 0:
    
    '-- pomysl i realizacja atom1477 (forum elektroda)
    Symbol = Lookup(cyfra1 , Dta)
    Wyswietlacz1_2 = Symbol * 16
    
    Symbol = Lookup(cyfra1 , Dta)
    Wyswietlacz2_2 = Symbol / 4
    
    In R16, Wyswietlacz1
    andi R16, &B00001111
    Lds R17, {Wyswietlacz1_2}
    !or R16, R17
    !Out Wyswietlacz1, R16
    
    In R16, Wyswietlacz2
    andi R16, &B11000011
    Lds R17, {Wyswietlacz2_2}
    !or R16, R17
    !Out Wyswietlacz2, R16
    
    '-- włączenie kropek
    If Opcja = 1 Then Portc.5 = 0
    
    Reset T1
    
    Case 1:
    
    '-- pomysl i realizacja atom1477 (forum elektroda)
    Symbol = Lookup(cyfra2 , Dta)
    Wyswietlacz1_2 = Symbol * 16
    
    Symbol = Lookup(cyfra2 , Dta)
    Wyswietlacz2_2 = Symbol / 4
    
    In R16, Wyswietlacz1
    andi R16, &B00001111
    Lds R17, {Wyswietlacz1_2}
    !or R16, R17
    !Out Wyswietlacz1, R16
    
    In R16, Wyswietlacz2
    andi R16, &B11000011
    Lds R17, {Wyswietlacz2_2}
    !or R16, R17
    !Out Wyswietlacz2, R16
    
    '-- włączenie kropek
    If Opcja = 1 Then Portc.5 = 0
    
    Reset T2
    
    Case 2:
    
    '-- pomysl i realizacja atom1477 (forum elektroda)
    Symbol = Lookup(cyfra3 , Dta)
    Wyswietlacz1_2 = Symbol * 16
    
    Symbol = Lookup(cyfra3 , Dta)
    Wyswietlacz2_2 = Symbol / 4
    
    In R16, Wyswietlacz1
    andi R16, &B00001111
    Lds R17, {Wyswietlacz1_2}
    !or R16, R17
    !Out Wyswietlacz1, R16
    
    In R16, Wyswietlacz2
    andi R16, &B11000011
    Lds R17, {Wyswietlacz2_2}
    !or R16, R17
    !Out Wyswietlacz2, R16
    
    
    Reset T3
    
    
    Case 3:
    
    '-- pomysl i realizacja atom1477 (forum elektroda)
    Symbol = Lookup(cyfra4 , Dta)
    Wyswietlacz1_2 = Symbol * 16
    
    Symbol = Lookup(cyfra4 , Dta)
    Wyswietlacz2_2 = Symbol / 4
    
    In R16, Wyswietlacz1
    andi R16, &B00001111
    Lds R17, {Wyswietlacz1_2}
    !or R16, R17
    !Out Wyswietlacz1, R16
    
    In R16, Wyswietlacz2
    andi R16, &B11000011
    Lds R17, {Wyswietlacz2_2}
    !or R16, R17
    !Out Wyswietlacz2, R16
    
    
    Reset T4
    
    End Select
    
    Return
    '---- koniec przerwania Timer0
    
    '---- TIMER1
    Tajmer1:
       Incr I1
       Toggle Opcja
    Return
    
    Dta:
    ' SEKWENCJA .GFEDCBA
    ' SEKWENCJA 11111111
    Data &B11000000 , &B11111001 , &B10100100 , &B10110000 , &B10011001
    Data &B10010010 , &B10000010 , &B11111000 , &B10000000 , &B10010000
    Data &B10000110 , &B10101111 , &B10100011 , &B11000111
    Data &B10111111 , &B11110111 , &B11101111
    
  • Pomocny post
    #9 6017982
    Konto nie istnieje
    Poziom 1  
  • #10 6018396
    mozgh
    Poziom 11  
    Dzięki, jeszcze zauważyłem "CLS", który zawieruszył się podczas zabawy LCD.

    Mam miejsce na obsługę ujemnych temperatur i może coś jeszcze uda mi się dopisać :).
  • #11 6018879
    Konto nie istnieje
    Poziom 1  
  • #12 6024893
    mozgh
    Poziom 11  
    mogłbyś pokazać jakiś przykład obsługi przycisku w przerwaniu timera ? Nawet jakiś URL do innego projektu.
  • Pomocny post
    #13 6025267
    Konto nie istnieje
    Poziom 1  
  • #14 6025343
    dawid512
    Poziom 32  
    atom1477 napisał:
    
    Dim S1 As Byte
    Switch1 Alias PinB.1
    
    If Switch1 = 0 Then
      If S1 = 0 Then
        S1=1
    
        nop
        ...
        ...
        nop
      End If
    Else
      S1 = 0
    End If
    


    Jakoś nie widzę żebyś tu korzystał z przerwania od Timera...
  • Pomocny post
    #15 6027082
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • #16 6091942
    mozgh
    Poziom 11  
    atom1477 napisał:
    Może zamiast tego:
    
    Symbol = Lookup(cyfra4 , Dta) 
    Wyswietlacz1_2 = Symbol * 16 
    
    Symbol = Lookup(cyfra4 , Dta) 
    Wyswietlacz2_2 = Symbol / 4 
    
    In R16, Wyswietlacz1 
    andi R16, &B00001111 
    Lds R17, {Wyswietlacz1_2} 
    !or R16, R17 
    !Out Wyswietlacz1, R16 
    
    In R16, Wyswietlacz2 
    andi R16, &B11000011 
    Lds R17, {Wyswietlacz2_2} 
    !or R16, R17 
    !Out Wyswietlacz2, R16
    


    wstaw to:
    
    Wyswietlacz = Lookup(cyfra4 , Dta)   
    
    In R16, Wyswietlacz1 
    andi R16, &B00001111 
    Lds R17, {Wyswietlacz}
    !Swap R17
    andi R17, &B11110000 
    !or R16, R17 
    !Out Wyswietlacz1, R16 
    
    In R16, Wyswietlacz2 
    andi R16, &B11000011 
    Lds R17, {Wyswietlacz}
    lsr R17
    lsr R17 
    !or R16, R17 
    !Out Wyswietlacz2, R16
    


    Zawsz trochę mniej miejsca zajmuje.


    Zmieniłem lekko układ i podłączenie wyświetlacza. Poniżej schemat urządzenia.

    Zmieniłem też kod przy wyświetlaniu (wróciłem do starszej wersji). Aktualnie mam tak:

    
    
    '-- pomysl i realizacja atom1477 (forum elektroda)
    Symbol = Lookup(cyfra1 , Dta)
    Wyswietlacz1_2 = Symbol * 16
    
    Symbol = Lookup(cyfra1 , Dta)
    Wyswietlacz2_2 = Symbol / 8
    
    In R16, Wyswietlacz1
    andi R16, &B00001111
    Lds R17, {Wyswietlacz1_2}
    !or R16, R17
    !Out Wyswietlacz1, R16
    
    In R16, Wyswietlacz2
    andi R16, &B11100001
    Lds R17, {Wyswietlacz2_2}
    !or R16, R17
    !Out Wyswietlacz2, R16
    


    Ale mam problem z obsługą buzzera. Porty ustawione są następująco:

    
    '-- Wejscia przycisków
    Config Portd.2 = Input
    Config Portd.3 = Input
    Config Portb.0 = Input
    Config Portb.1 = Input
    
    ' -- podciągnięcie
    Set Portd.2
    Set Portd.3
    Set Portb.0
    Set Portb.1
    
    ' -- porty sterowania segmentami LED
    Config Portd.4 = Output
    Config Portd.5 = Output
    Config Portd.6 = Output
    Config Portd.7 = Output
    
    Config Portc.4 = Output
    Config Portc.3 = Output
    Config Portc.2 = Output
    Config Portc.1 = Output
    
    Krop Alias Portc.4                                          '-- kropka
    
    ' -- tranzystory
    Config Portb.2 = Output
    Config Portb.3 = Output
    Config Portb.4 = Output
    Config Portb.5 = Output
    
    '-- buzzer
    Config Portc.0 = Output
    
    T4 Alias Portb.5
    T3 Alias Portb.4
    T2 Alias Portb.3
    T1 Alias Portb.2
    
    S1 Alias Pind.2
    S2 Alias Pind.3
    S3 Alias Pinb.0
    S4 Alias Pinb.1
    
    Buzzer Alias Portc.0
    
    Wyswietlacz1 Alias Portd
    Wyswietlacz2 Alias Portc
    
    '-- 1wire
    Config 1wire = Portc.5
    
    
    '-- pomysl i realizacja atom1477 (forum elektroda)
    Dim Wyswietlacz1_2 As Byte
    Dim Wyswietlacz2_2 As Byte
    


    W obsłudze TIMER1 mam coś takiego:

    
    
    Tajmer1:
    
      If S3 = 0 And S4 = 0 Then
          Incr Opcjax
          Call Rozloz
      End If
    
      If S1 = 0 And S2 = 0 Then
          Decr Opcjax
          Call Rozloz
      End If
    
      If Opcja = 5 Then
    
       Opcjas = _hour
       Opcjam = _min
       If S1 = 0 Then Incr Opcjas
       If S2 = 0 Then Decr Opcjas
       If S3 = 0 Then Incr Opcjam
       If S4 = 0 Then Decr Opcjam
    
       If Opcjas > 23 And Opcjas < 250 Then Opcjas = 0
       If Opcjas > 250 Then Opcjas = 23
       If Opcjam > 59 And Opcjam < 250 Then Opcjam = 0
       If Opcjam > 250 Then Opcjam = 59
    
       _hour = Opcjas
       _min = Opcjam
    
      Elseif Opcja = 6 Then
    
       Opcjas = _month
       Opcjam = _day
       If S1 = 0 Then Incr Opcjas
       If S2 = 0 Then Decr Opcjas
       If S3 = 0 Then Incr Opcjam
       If S4 = 0 Then Decr Opcjam
    
       If Opcjas > 12 And Opcjas < 250 Then Opcjas = 0
       If Opcjas > 250 Then Opcjas = 12
       If Opcjam > 31 And Opcjam < 250 Then Opcjam = 0
       If Opcjam > 250 Then Opcjam = 31
    
       _month = Opcjas
       _day = Opcjam
    
      Else
    
     
      If S1 = 0 Then Toggle Buzzer
    
       If S2 = 0 Then Decr Opcjas
       If S3 = 0 Then Incr Opcjam
       If S4 = 0 Then Decr Opcjam
    
      End If
    Return
    
    


    Kiedy zmieniam zmienną opcjax to na wyświetlaczu pojawia się w kolejności od lewej:
    T1 : "[" Symbol podobny do litery C lub [.
    T2 : dziesiątki liczby Opcjax
    T3 : jedności liczby Opcjax
    T4: "]" Symbol podobny do odbicia litery C lub identyczny z ]

    Problem jest następujący, kiedy wyświetlam różne liczby, buzzer wydaje krótki dzięk po czym coś go przestawia na "1" lub działa normalnie. Oto kilka przykładów:

    "[40]" buzzer włącza się na chwile i wyłącza ( coś ustawia buzzer na 1)
    "[39]" buzzer reaguje na naciśnięcie S1 prawidłowo (stan 0 lub 1 zależnie od S1)
    "[38]" buzzer reaguje na naciśnięcie S1 prawidłowo (stan 0 lub 1 zależnie od S1)
    "[37]" buzzer włącza się na chwile i wyłącza ( coś ustawia buzzer na 1)
    "[36]" buzzer reaguje na naciśnięcie S1 prawidłowo (stan 0 lub 1 zależnie od S1)
    "[35]" buzzer reaguje na naciśnięcie S1 prawidłowo (stan 0 lub 1 zależnie od S1)
    "[34]" buzzer włącza się na chwile i wyłącza ( coś ustawia buzzer na 1)
    "[33]" buzzer reaguje na naciśnięcie S1 prawidłowo (stan 0 lub 1 zależnie od S1)
    "[32]" buzzer reaguje na naciśnięcie S1 prawidłowo (stan 0 lub 1 zależnie od S1)
    "[31]" buzzer włącza się na chwile i wyłącza ( coś ustawia buzzer na 1)
    "[30]" buzzer reaguje na naciśnięcie S1 prawidłowo (stan 0 lub 1 zależnie od S1)

    Wygląda na to ze kiedy wyświetlane są cyfry "1,4,7" to coś przestawia PORTC.0 na 1.
    Ponieważ modyfikowałem kod orginalnie napisany przez atom1477 wydaje mi się że coś tam namodziłem.

    Ta wstawka ASMowa jest dla mnie lekką zagadką :).

    Mam nadzieje że atom1477 znów przyjdzie z pomocą :).

    Załączam również aktualny kod programu. Jest mało czytelny, ale dopiero nad nim pracuje.
  • Pomocny post
    #17 6092142
    zumek
    Poziom 39  
    mozgh napisał:
    ... Jest mało czytelny...

    ... i niepotrzebnie ... "rozwleczony".
    A co do buzera, to wystarczy "wyrzucić" 1 bit.
    Np.
    
    Symbol = Lookup(cyfra1 , Dta)
    Wyswietlacz2_2 = Symbol / 8
    Wyswietlacz2_2 = Wyswietlacz2_2 AND &B00011110   ' dopisać
    

    lub
    
    In R16, Wyswietlacz2
    andi R16, &B11100001
    Lds R17, {Wyswietlacz2_2}
    Andi R17,&H1E                  'dopisać
    !or R16, R17
    !Out Wyswietlacz2, R16
    

    I popracuj nad kodem, bo można go solidnie "przetrzebić" :P
  • #18 6093370
    mozgh
    Poziom 11  
    zumek napisał:
    mozgh napisał:
    ... Jest mało czytelny...

    ... i niepotrzebnie ... "rozwleczony".

    I popracuj nad kodem, bo można go solidnie "przetrzebić" :P


    Czy możesz podać jakieś praktyczne porady odnośnie poprawek w kodzie ?.

    BASCOM podoba mi pod względem obsługi sprzętu peryferyjnego (dostępności bibliotek), ale drażni mnie jako język programowania.

    Nie czuje tego języka, dlatego kod wygląda jak wygląda.

    Z przyjemnością wysłucham i postaram się zaaplikować wszelkie porady od bardziej doświadczonych kolegów.

    Pozdrawiam.
  • Pomocny post
    #19 6093775
    Konto nie istnieje
    Poziom 1  
REKLAMA