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

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

mozgh 16 Sty 2009 23:43 6204 18
  • #1 16 Sty 2009 23:43
    mozgh
    Poziom 10  

    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:

    Code:

    $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

    0 18
  • Pomocny post
    #2 16 Sty 2009 23:57
    atom1477
    Poziom 43  

    Code:
    Disable Interrupts 
    
       1wreset
    Enable Interrupts
    Disable Interrupts
       1wwrite &HCC
    Enable Interrupts
    Disable Interrupts
       1wwrite &H44
    Enable Interrupts

       Waitms 750                                               'czas konwersji 750 ms

    Disable Interrupts
       1wreset
    Enable Interrupts
    Disable Interrupts
       1wwrite &HCC
    Enable Interrupts
    Disable Interrupts
       1wwrite &HBE
    Enable Interrupts



    Najgorzej to z tym:
    Code:
    T(1) = 1wread(9)

    Błędy odczytu są spowodowane tym że nie wyłączasz przerwań przed tym. Co najmniej zrób tak:
    Code:
    Disable Interrupts
    
    T(1) = 1wread(9)
    Enable Interrupts


    To powinno już działać. Przynajmniej u mnie coś podobnego działa.

    Ja bym jednak poszedł dalej i rozbił to na osobne odczyty pojedynczych bajtów i je także poprzedzielał tym:
    Code:

    Enable Interrupts
    Disable Interrupts

    0
  • #3 17 Sty 2009 09:39
    mozgh
    Poziom 10  

    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.

    0
  • #4 17 Sty 2009 19:30
    mozgh
    Poziom 10  

    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.

    Code:

    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

    0
  • Pomocny post
    #5 17 Sty 2009 20:19
    atom1477
    Poziom 43  

    Code:
    $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 = 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 Pind.2
    S2 Alias Pind.3

    Dim Wyswietlacz1_2 As Byte                                  '<----------------------------------------------------
    Dim Wyswietlacz2_2 As Byte                                  '<----------------------------------------------------

    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 Byte

    '-- przerwania
    Enable Interrupts

    Config Timer0 = Timer , Prescale = 64
    Enable Timer0
    On Timer0 Tajmer0

    Config Timer1 = Timer , Prescale = 256
    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$ = "19:10:20"

    Print "start programu"

    Cls

    I = 0

    Do

       Debounce S1 , 0 , Switch1 , Sub
       Debounce S2 , 0 , Switch2 , Sub


       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$

       Debounce S1 , 0 , Switch1 , Sub
       Debounce S2 , 0 , Switch2 , Sub

    Loop

    Switch1:

       Incr Opcja

    Return

    Switch2:

       Decr Opcja

    Return

    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

    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

    'Else
    '   Jakitimer0 = Timer0
    '   Incr I
    '   'Timer0 = 10
    '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

    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:

    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_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                                      '<----------------------------------------------------


    Reset T1

    Case 1:

    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                                      '<----------------------------------------------------


    'If Cyfra2 <> 0 Then Wyswietlacz = Lookup(cyfra2 , Dta)
    'Wyswietlacz = Lookup(cyfra2 , Dta)


    Reset T2

    Case 2:

    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:

    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
    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

    0
  • #6 17 Sty 2009 23:35
    mozgh
    Poziom 10  

    Atom mogłbyś wyjaśnić ten kawałek kodu:

    Code:

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


    Wygląda intrygująco... to jakaś ASMowa wstawka ?

    0
  • Pomocny post
    #7 17 Sty 2009 23:54
    atom1477
    Poziom 43  

    Tak.
    Może być i w wysokim poziomie, ale takie będzie o wiele szybsze a w dodatku zajmie mniej miejsca a nie chciałem Ci zajmować swoimi poprawkami całego FLASHa w procku.

    Code:

    In R16, Wyswietlacz1                                        '<-- R16 = PortD
    andi R16, &B00001111                                        '<-- R16 = R16 And &B00001111
    Lds R17, {Wyswietlacz1_2}                                   '<-- R17 = Wyswietlacz1_2
    !or R16, R17                                                '<-- R16 = R16 Or R17
    !Out Wyswietlacz1, R16                                      '<-- PortD = R16



    Inaczej mówiąc, pobiera wartość PortD, zeruje bity 5, 6, 7, 8, potem do tych bitów wklepuje potrzebne wartości i zwraca wartość do PortD.
    Czyli bity 0, 1, 2, 3 pozostaną niezmienione.



    Jeszcze wyjasnienie, dlaczego raz jest In, raz lds a raz ldi.
    To są rozkazy przypisania.
    Na przykład w procesorach ’51 wszystko załatwia jeden rozkaz: mov.
    A w AVR producent wymyślił sobie osobne mnemoniki (producent oprogramowania, choć nim też jest ATMEL). Na początku zabawy z AVRami miałem z tym dużo problemow.
    In - pobranie wartości z rejestru IO do rejestru uniwersalnego
    lds - pobranie wartości z pamięci RAM do rejestru uniwersalnego
    ldi - „pobranie” wartości stałej do rejestru uniwersalnego. Pobranie w cudzysłowiu, bo to w zasadzie jest jedyny rozkaz naprawdę godny nazwy „przypisanie”.
    Pozostałe to raczej rozkazy skopiowania.

    Acha. Ldi to nie w tym przypadku. Ale niech już będzie.

    0
  • #8 18 Sty 2009 14:46
    mozgh
    Poziom 10  

    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. :)

    Code:

    $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

    0
  • Pomocny post
    #9 18 Sty 2009 16:56
    atom1477
    Poziom 43  

    Może zamiast tego:

    Code:

    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:
    Code:

    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.

    0
  • #10 18 Sty 2009 18:20
    mozgh
    Poziom 10  

    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ć :).

    0
  • #11 18 Sty 2009 19:43
    atom1477
    Poziom 43  

    Może jeszcze włącz optymalizację kodu. U mnie nigdy to nie działało aż nie trafiłem na jakiegoś nowego BASCOMa.
    Jest zysk jakieś 10%. Oczywiście jeszcze zależy od programu ale u mnie było dużo w assebmlerze a tego się nie da zoptymalizować a mimo to BASCOM to co mógł to pokompresował i wyszło z 10%.
    U Ciebie może będzie nawet więcej.

    A obsługę przycisków to ja bym zrobił w przerwaniu od Timera.

    0
  • #12 19 Sty 2009 22:04
    mozgh
    Poziom 10  

    mogłbyś pokazać jakiś przykład obsługi przycisku w przerwaniu timera ? Nawet jakiś URL do innego projektu.

    0
  • Pomocny post
    #13 19 Sty 2009 22:54
    atom1477
    Poziom 43  

    Code:

    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

    0
  • #14 19 Sty 2009 23:07
    dawid512
    Poziom 32  

    atom1477 napisał:
    Code:

    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...

    0
  • Pomocny post
    #15 20 Sty 2009 13:33
    atom1477
    Poziom 43  

    dawid512 napisał:

    Jakoś nie widzę żebyś tu korzystał z przerwania od Timera...


    Bo nie musisz ;p

    mozgh napisał:
    mogłbyś pokazać jakiś przykład obsługi przycisku w przerwaniu timera ? Nawet jakiś URL do innego projektu.

    Więc chyba oczywistym jest że ten fragment kodu należy umieścić w przerwaniu od Timera.

    0
  • #16 02 Lut 2009 15:50
    mozgh
    Poziom 10  

    atom1477 napisał:
    Może zamiast tego:
    Code:

    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:
    Code:

    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:

    Code:


    '-- 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:

    Code:

    '-- 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:

    Code:


    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.

    0
  • Pomocny post
    #17 02 Lut 2009 16:32
    zumek
    Poziom 39  

    mozgh napisał:
    ... Jest mało czytelny...

    ... i niepotrzebnie ... "rozwleczony".
    A co do buzera, to wystarczy "wyrzucić" 1 bit.
    Np.
    Code:

    Symbol = Lookup(cyfra1 , Dta)
    Wyswietlacz2_2 = Symbol / 8
    Wyswietlacz2_2 = Wyswietlacz2_2 AND &B00011110   ' dopisać

    lub
    Code:

    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

    0
  • #18 02 Lut 2009 20:28
    mozgh
    Poziom 10  

    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.

    0
  • Pomocny post
    #19 02 Lut 2009 21:18
    atom1477
    Poziom 43  

    No właśnie.
    Nie zwróciłem na to uwagi.
    Pasowało by pododawać jeszcze po jednej linii (tak jak napisał Zumek):

    Code:

    In R16, Wyswietlacz2
    andi R16, &B11100001
    Lds R17, {Wyswietlacz2_2}
    andi R17, &B00011110      '<-- To trzeba dodać.
    !or R16, R17
    !Out Wyswietlacz2, R16


    Oczywiście w Twojej nowszej wersji programu to będzie wyglądało inaczej zależnie od tego czy to Wyświetlacz1 czy Wyświetlacz2.

    0