Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[Atmega8][Bascom] kilka pytań początkującego

luki55 29 Apr 2010 10:12 2307 6
  • #1
    luki55
    Level 20  
    Witam
    Właśnie robie sobie wyświetlacz do samochodu, na razie mam dwie temperatury i napięcie...
    Zamieszczam listing:

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

    Config Lcdpin = Pin , Db4 = Portd.1 , Db5 = Portd.2 , Db6 = Portd.3 , Db7 = Portd.4 , E = Portd.0 , Rs = Portd.5
    Config Lcd = 20 * 4

    Config 1wire = Portd.7

    Config Pinc.0 = Output
    Config Pinb.0 = Output
    Config Pinb.1 = Input
    Set Portc.0
    Set Portb.0
    Reset Portc.1

    D Alias Portc.0
    R Alias Portb.0
    Went Alias Portb.1





    Dim I1 As Integer , Ss As String * 6
    Dim I2 As Integer
    Dim Dsid1(8) As Byte
    Dim Dsid2(8) As Byte


    Dim Wart_ac As Word
    Dim V As Single
    Dim P As String * 3
    Dim X As Single


    Config Adc = Single , Prescaler = Auto , Reference = Avcc


    Deflcdchar 0 , 7 , 5 , 7 , 32 , 32 , 32 , 32 , 32
    Deflcdchar 1 , 28 , 4 , 6 , 12 , 4 , 4 , 14 , 32
    Deflcdchar 2 , 4 , 21 , 10 , 27 , 27 , 10 , 21 , 4
    Deflcdchar 3 , 32 , 32 , 14 , 17 , 30 , 16 , 15 , 2
    Deflcdchar 4 , 32 , 4 , 21 , 14 , 27 , 14 , 21 , 4


    Cls
    Cursor Off

    Dsid1(1) = 1wsearchfirst()
    Dsid2(1) = 1wsearchnext()

    Cursor Off
    Cls







    Do

    1wreset
       1wwrite &H55
       1wverify Dsid1(1)
       1wwrite &HBE
       I1 = 1wread(2)

       1wreset
       1wwrite &H55
       1wverify Dsid2(1)
       1wwrite &HBE
       I2 = 1wread(2)

       1wreset
       1wwrite &HCC
       1wwrite &H44

       Waitms 750




       I1 = I1 / 16

       'If I1 > 0 Then Cls
       Ss = Str(i1)
       Ss = Format(ss , "##")
       Locate 1 , 1
    Lcd "Temp. silnika:"
    Locate 1 , 16
    Lcd Ss ; Chr(0) ; "C";


       I2 = I2 / 16

       'If I2 > 0 Then Cls
       Ss = Str(i2)
       Ss = Format(ss , "##")
       Locate 2 , 1
    Lcd "Temp. zew.:"
    Locate 2 , 16
    Lcd Ss ; Chr(0) ; "C";

    If I1 > 990 Then
    Gosub Temp
    End If


    Start Adc
    Cursor Off



    Wart_ac = Getadc(1)

    V = Wart_ac * 0.0049

    X = V * 4

    P = Fusing(x , "#.&")
    Locate 3 , 1
    Lcd "Napi" ; Chr(3) ; "cie:" ;
    Locate 3 , 16
    Lcd P ; "V"


    If Wart_ac > 750 Then
    Gosub Wysokie
    End If

    If Wart_ac < 560 Then
    Gosub Niskie
    End If

    If Went = 0 Then
    Locate 4 , 1
    Lcd "Wentylator Wl."
    End If


    Loop

    Wysokie:
    Cls
    Lcd "Zbyt wysokie"
    Locate 2 , 1
    Lcd ; Chr(1) ; "adowanie"
    Reset D
    Waitms 500
    Set D
    Cls
    Return


    Niskie:
    Cls
    Lcd "Akumulator"
    Locate 2 , 1
    Lcd "niedo" ; Chr(1) ; "adowany"
    Reset D
    Wait 3
    Set D
    Cls
    Return


    Temp:
    Cls
    Lcd "Silnik si" ; Chr(3);
    Lowerline
    Lcd "przegrzewa"
    Reset D
    Wait 3
    Set D
    Cls
    Return


    End


    Mam to uruchomione na płytce testowej...
    Tak wiem program jest do bani, ale działa i to dla mnie się liczy, ale do rzeczy...
    Chciałbym zrobić coś takiego: podaje napięcie z instalacji samochodu +12V przez dzielnik na port c.1 Atmegi, i chcę zrobić tak, że gdy to napięcie jest to ma się wyświetlić w 4 lini, że wentylator jest włączony...Tylko tu mam problem jak sprawdzać stan na tym wejściu...Ustawiłem go jako input, zresetowałem, przydzieliłem nazwę "Went', niestety nie działa to bo od razu po włączeniu zasilania wyświetla mi się to na wyświetlaczu...
    Jak zrobiłem tak:

    Code:
    If Went = 0 Then
    
    Locate 4 , 1
    Lcd "Wentylator Wl."
    Else
    Lcd "Wentylator Wyl."
    End if


    to jest ok, tylko muszę mieć na porcie albo masę albo +12V bo inaczej wariuje...tzn. na przemian wyświetla się , że jest wł, i wył.

    Jak się z tym uporać?

    Mam jeszcze drugi problem: napisałem sterownik lampki do samochodu, który w momencie zwarcia wyłącznika w drzwiach czyli podaniu "0" płynnie zaświeca i świeci się do momentu gdy wyłącznik zostanie przerwany zostaje wygaszana z opóźnieniem ok 5s , w końcowej fazie płynnie przez pwm, problem w tym, że jak w momencie np. tego płynnego wygaszania zostanie ponownie podana masa (zwarty wyłącznik) to lampka ma się zaświecić od razu, a nie tak tak jest teraz czyli musi zgasnąć i dopiero po tym zaświeca się płynnie...jak to zrobić?
    Jak dodać funkcję wyłączania lampki w momencie gdy podawana jest masa dłużej niż np. 30s ??

    Listing:

    Code:
    $regfile = "m8def.dat"                                     
    
    $crystal = 8000000                                       
    Config Pinb.1 = Output                               
    Config Pinb.5 = Input     ' wylacznik
    Set Portb.5
    S Alias Pinb.5                                             

    Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Down , Compare B Pwm = Disconnect , Prescale = 8

    Dim I As Byte
    Pwm1a = 255
    Do

    If S = 0 Then
    For I = 255 To 0 Step -1
    Pwm1a = I
    Waitms 15
    Next I


    Incr I
    Bitwait S , Set


    If S = 1 Then


    Pwm1a = 0
    Wait 2

    For I = 0 To 255

    Pwm1a = I

    Waitms 25

    If S = 0 Then
    Pwm1a = 0
    End If

    Next I
    Decr I
    End If
    End If
    Loop


    Przepraszam, że programy bez komentarzy...

    Pozdrawiam z góry dzięki za odpowiedzi...
  • Helpful post
    #2
    Mimitron
    Level 20  
    Nie wiem czy dobrze zrozumiałem twój pierwszy problem ale spróbuj zastosować bramkę schmitta między portem a dzielnikiem

    Lub zerknąć jak ja rozwiązałem problem wykrywanie pojawienia się napięcia w instalacji auta, dokładnie po przekręceniu stacyjki lub pojawienia się włączenia świateł :
    Link
  • Helpful post
    #3
    sp3ots
    Level 38  
    Witam !
    Problem 1:
    Code:

    $regfile = "attiny2313.dat"
    Config Lcdpin = Pin , Db7 = Pb.2 , Db6 = Pb.3 , Db5 = Pb.4 , Db4 = Pb.5 , E = Pb.6 , Rs = Pb.7
    Config Lcd = 16 * 2
    $crystal = 10000000
    Cursor Off
    Cls
    Config Pinb.1 = Input
    Portb.1 = 1
    Went Alias Pinb.1
    Do
    If Went = 0 Then
    Locate 1 , 1
    Lcd "Wentylator Wl. "
    Else
    Locate 1 , 1
    Lcd "Wentylator Wyl."
    End If
    Loop
    End

    Przetestowałem na ATtiny2313, działa PORTB.1
    Dostosuj do swoich potrzeb.
    Pozdrawiam. Stefan
  • #4
    luki55
    Level 20  
    Dziękuje za podpowiedzi, będę sprawdzał czy działa...

    Mimitron, świetny projekt i skarbnica wiedzy- dzięki

    A odnośnie pwm wie ktoś jak to rozwiązać?

    Pozdrawiam

    Łukasz
  • Helpful post
    #5
    Mimitron
    Level 20  
    Co do wyłączenie światła po 30 sek. Dodaj dodatkową zmienną bit która będzie ustawiana np: na 1 po wyłączenia światła przez timer po 30 sekundach a dzięki niej nie będzie ponownie włączane światło przez wciąż otwarte drzwi (stan niski na wejściu uC). Dopiero zamkniecie drzwi ( stan wysoki na wejściu uC) spowoduje zmianę tej zmiennej na 0
    Code:

    dim 30SEK as byte
    dim zmienna_ kontrolna as bit
    '****timer0********
    Config Timer0 = Timer , Prescale = 256
    On Timer0 przerwanie_timera_po30s     
    Load Timer0 , 250
    Enable Timer0
    Stop Timer0

    do     'pętla  główna programu

    if otwarte_drzwi = 0 and zmienna_ kontrolna = 0 then

    ZAPAL śWIATłO        'procedura PWM włączenia światła
    start timer0             'włączenie timera0 który odlicza 30 sek.

    end if


    If zamkniete_drzwi = 1 then

    ZGAś śWIATłO           'procedura PWM gasząca światło
    zmienna_kontrolna = 0
    stop timer0
    end if

    loop     'koniec głównej pętli programu
    end

    przerwanie_timera_po30s

    Load Timer0 , 250

    Incr 30SEK

    If 30SEK = 62 Then
    30SEK  = 0
    ZGAś śWIATłO                      ''procedura PWM gasząca światło
    zmienna_kontrolna = 1
    stop timer0
    end if

    return


    Kierując się moimi doświadczeniami dam ci rade abyś zmienił uC na większy , szybko okaże się że w miarę rozwoju projektu i nowych pomysłów zacznie ci brakować pamięci. Będziesz chciał dodać nowe funkcje lub animacje ikon np: ładowania. W moim przypadku miałem prawie gotowy projekt i nagle okazało się że muszę jeszcze raz wykonać płytkę i przeprojektować cały układ bo brakło mi pamięci, poza tym też jestem początkującym i moje procedury nie były zbyt pamięcio oszczędne ;). Zdecydowałem się na atmege32 bo jest nie wiele droższy od atmegi16 a ma 2 razy większą pamięć :)
  • Helpful post
    #6
    kots
    Level 12  
    Po wykryciu naciśnięcia klawisza musisz ustawić poziom świecenia i przerwać pętlę for next, bo wykonuje ci się jej resztka i zmniejsza jasność świecenia.

    Co do W1, nie wiem czy to jest komplet źródeł, ale jeśli używasz Bascomowe procedury obsługi W1, to musisz mieć zablokowane przerwania. Albo nie używasz przerwań wcale w programie, a jak nie to musisz je blokować przed każdą instrukcją obsługującą W1 i po niej włączać je.

    KotS
  • #7
    luki55
    Level 20  
    Mimitron, dziękuje za fragment kodu, teraz chyba wiem jak to będzie wyglądać...Doszedłem do takich samych wniosków, i nawet mam już Atmeg`e 32 także zaprojektuje sobie jeszcze raz płytkę, miałem wcześniej przygotowaną pod m8 ale jest nieprzemyślana, brakuje paru rzeczy, teraz muszę dorzucić jeszcze te układy dopasowujące..

    Code:
    Po wykryciu naciśnięcia klawisza musisz ustawić poziom świecenia i przerwać pętlę for next, bo wykonuje ci się jej resztka i zmniejsza jasność świecenia. 

    Ok, będę też coś kombinował w tym kierunku...

    Dziękuje