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

1wire i wyświetlacze 7 segmentowe w bascomie

18 Maj 2007 23:46 1266 3
  • Poziom 31  
    Witam. Buduje właśnie termostat z czujnikiem DS1820 i wyświetlaczami 7 segmentowymi, potrzebuje wyświetlić na 3 cyfrach temperaturę nastawioną i na drugich 3 odczytaną z czujnika. Uporałem się z obsługą 6cyfr w multiplexie napisałem odczyt ds-a i pojawił się problem mianowicie odświeżanie wyświetlacza leci w timerze odczyt DS-a w pętli głównej mój problem polega na tym że muszę zatrzymać timer na czas odczytu z 1wire bo inaczej co kilka odczytów pojawiają się błędy (co jest dla mnie zrozumiałe bo jeśli przerwanie od timera wystąpi w momencie generowania sygnałów 1w to powstaną przekłamania) moje pytanie dotyczy sposobów obejścia tego problemu, załączam pełny kod programu.


    Code:
    $regfile = "m8def.dat"
    
    $crystal = 16000000

    Config Portd = Output
    Config Portc = Output
    Config 1wire = Pinb.3

    Config Adc = Single , Prescaler = Auto , Reference = Internal
    Start Adc

    Config Timer2 = Timer , Prescale = 64
    On Timer2 Led
    Enable Timer2
    Enable Interrupts

    Dim A(6) As Byte
    Dim Tab(3) As Byte
    Dim Licz As Byte
    Dim W As Word
    Dim T As Byte
    Dim Odczyt(2) As Byte

    Declare Sub Temp

    Start Timer1

    A(1) = 10
    A(2) = 10
    A(3) = 10
    A(4) = 10
    A(5) = 10
    A(6) = 10

    Do
               'odczyt&wyświetlanie temperatury
    Call Temp
    T = Odczyt(1)
     Tab(1) = T / 100
    Tab(2) = Tab(1) * 100
    T = T - Tab(2)
    Tab(2) = T / 10
    Tab(3) = Tab(2) * 10
    T = T - Tab(3)
    Tab(3) = T

    If Tab(1) = 0 Then
    Tab(1) = 10
    End If
    A(1) = Tab(1)
    A(2) = Tab(2)
    A(3) = Tab(3)

    Loop
    End


    Sub Temp                                                    'odczyt ds1820
    Disable Interrupts
    1wreset
    1wwrite &HCC
    1wwrite &H44
    Enable Interrupts

    Wait 1
    Waitms 500

    Disable Interrupts
    1wreset
    1wwrite &HCC
    1wwrite &HBE
    Odczyt(1) = 1wread(2)
    1wreset
    Enable Interrupts
    Odczyt(1) = Odczyt(1) / 2                                   'obliczanie temperatury
    End Sub

    Led:
    W = Getadc(7)                                               'odczyt wartości nastawionej
    Shift W , Right , 3
    W = W + 20                                                  'konwersja do postaci wyświetlalnej
    Tab(1) = W / 100
    Tab(2) = Tab(1) * 100
    W = W - Tab(2)
    Tab(2) = W / 10
    Tab(3) = Tab(2) * 10
    W = W - Tab(3)
    Tab(3) = W

    If Tab(1) = 0 Then                                          'wygaszenie zer nieznaczących
    Tab(1) = 10
    End If
    A(6) = Tab(1)
    A(5) = Tab(2)
    A(4) = Tab(3)
    Portc = 0
    Waitus 10
    Portd = Lookup(a(licz) , Cyfra)
    Portc = Lookup(licz , Cyfranr)
    Licz = Licz + 1
    If Licz = 7 Then
    Licz = 1
    End If
    Return

    Cyfra:                                                      'tablica z definicjami poszczególnych cyfr (od 0 do 9)
    Data &B11111100 , &B01100000 , &B11011010 , &B11110010 , &B01100110
    Data &B10110110 , &B10111110 , &B11100000 , &B11111110 , &B11110110
    Data &B00000000

    Cyfranr:                                                    'wybór wyświetlacza
    Data &B00000000 , &B00000001 , &B00000010 , &B00000100 , &B00001000 , &B00010000 , &B00100000
  • VIP Zasłużony dla elektroda
    Post był raportowany.
    Przeniosłem z: Programowanie ogólne
  • Poziom 32  
    Licz CRC po cos go w koncu producent zaimplementował w ds-a
  • Poziom 30  
    Kiedyś udało mi się to obejść.

    Dzielisz cała transmisje do ds'a na czynniki pierwsze.
    Steruje tym wszystkim zmienna licznik. Zmienna ma być ustawiona co dwa a nieparzyste ustawiane zaraz po wykonaniu obsługi przerwania wyświetlacza.
    Coś takiego:
    Code:
    dim zmienna_licznik as byte
    
    .....
    petla:
    if zmienna_licznik=1 then: 1wreset:zmienna_licznik=2:endif
    if zmienna_licznik=3 then: 1wwrite xx:zmienna_licznik=4:endif
    if zmienna_licznik=5 then: 1wwrite xx:zmienna_licznik=6:endif
    ....
    przerwanie_do_wyświetlacza:
    ...
    if zmienna_licznik=0 then zmienna_licznik=1
    elseif zmienna_licznik=2 then zmienna_licznik=3
    elseif zmienna_licznik=4 then zmienna_licznik=5
    ...
    endif
    Coś takiego zapewni rozczłonkowanie transmisji na krótsze fragmenty. Teraz musisz dobrać opóźnienie miedzy wyświetlaczami na więcej niż 470us i powinno być ok.

    Dodatkowo trzeba jeszcze uwzględnić jakoś opóźnienie na pomiar - ale to też dodatkowy licznik w odpowiednim miejscu ci załatwi - liczenie ilości przerwań wyświetlacza.