Elektroda.pl
Elektroda.pl
X

Wyszukiwarki naszych partnerów

Wyszukaj w ofercie 200 tys. produktów TME
Kategoria: Kamery IP / Alarmy / Automatyka Bram
Montersi
Proszę, dodaj wyjątek elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[mega8][bascom] problemów kilka....

mszkoda 31 Paź 2008 23:09 1892 10
  • #1 31 Paź 2008 23:09
    mszkoda
    Poziom 9  

    witam,

    na początek dodam iż pierwszy raz mam do czynienia z AVR i bascomem,

    sklepałem taki programik który mam nadzieje że z Waszą pomocą uda się dokończyć i pójść dalej :)

    Code:
     $regfile = "m8def.DAT"                                     ' Atmega8
    
     $crystal = 1000000                                         'wew oscylator 1MHz
    'Deklaracja portów od wyświetlacza LCD
     Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portb.4 , Rs = Portb.5
     Config Lcd = 16 * 2
     Config Sda = Portc.4                                       'deklaracja portu sda
     Config Scl = Portc.5
     Config Pinc.3 = Input                                      'power buttor
     Config Pinc.2 = Input                                      'up button
     Config Pinc.1 = Input                                      'down button
     Config Pinc.0 = Input                                      'menu button

     Const T1 = "   Funkcja1 "
     Const T2 = "   Funkcja2 "
     Const T3 = "   Funkcja3 "
     Const T4 = "   Funkcja4 "
     Const T5 = "   Funkcja5 "

     Declare Sub Init                                           ' Inicjalizacja
     Declare Sub Power_off                                      ' "STAND-BY"
     Declare Sub Power_on                                       ' POWER ON
     Declare Sub Normal                                         ' tryb pracy
     Declare Sub Menu
     Declare Sub Greenled                                       ' odpalenie zielonej diody
     Declare Sub Redled                                         ' odpalenie czerw. diody
     Declare Sub 5ms                                            ' czekajka
     Declare Sub 100ms                                          ' czekajka
     Declare Sub 500ms                                          ' czekajka


     Dim Menu_funkcja As Byte

     Sub Init:

         Call Redled
         Call Greenled
         Lcd "Init...."
         Call 500ms
         Cls
         Goto Power_off
     End Sub

     '###########################

     Sub Power_off:

         Call 100ms
         Cls
         Upperline
          Lcd "power off"
         Lowerline
          Lcd "wylaczanie..."
         Call 500ms
         Cls
         Call 500ms
         Call 500ms
         Call Redled
            Do
            Set Portc.3
            Call 5ms
            If Pinc.3 = 1 Then Power_on
            Loop
            End Sub

       '###########################
       Sub Power_on
       Call 100ms
       Lcd "power on"
       Call 500ms
       Call 500ms
       Cls
       Goto Normal
       End Sub
       '###########################

       Sub Normal
       Cls
       Call Greenled
       Do
       Set Portc.3
       Call 5ms
       If Pinc.3 = 1 Then Goto Power_off
       Set Portc.0
       Call 5ms
       If Pinc.0 = 1 Then Menu
       Loop
       End Sub
       '##########################
       Sub Menu
       Incr Menu_funkcja
       Home : Lcd T1

       '....


       Debounce Pinc.0 , 1 , Menu , Sub

       Do
           Set Portc.0
           Call 5ms
           If Pinc.0 = 1 Then Normal
           Loop


     End Sub

    '##################################

     Sub 100ms:

         Waitms 100

     End Sub

    '##################################

     Sub 500ms:

         Waitms 500

     End Sub

    '##################################

     Sub 5ms:

         Waitms 5

     End Sub

    '##################################

     Sub Greenled:

         Set Portd.3

     End Sub
     '##################################

     Sub Redled:

         Set Portd.2

     End Sub


    Urządzenie na tą chwile składa się z
    atmega8
    lcd 2x16
    2x led
    przyciski: power, menu, up, down

    Docelowo jak mi sie uda to miało by wysterować tda7318

    Ogólnie program sie odpala - "init" - w tej chwili nic jeszcze tam nie ma ale w dalszej części będzie sie coś robić :) (wpisywać po i2c ustawienia do tda7138) i przechodzi do standby (którym jest poweroff) i następnie po wciśnięciu klawisza power przechodzi do "power on" i do trybu "normal mode"
    w międzyczasie zapalają sie też diodki ale teraz to nie istotne :)
    W trybie "normal mode" moge albo wywołać "poweroff" albo "menu"

    o i mam problem i kilka pytań z tym związanych:
    1) jak zrobić obsługe menu - chodzi o to aby po wejściu do "menu" klawiszami (down/up button) przeskakiwać po zdefiniowanych pozycjach w menu (Funkcja1 do Funkcja5) oczywiście aby sie wyświetlało na lcd :) a następnie:

    a) ponownie wciskając (krótko) przycisk menu wejść (będąc na wybranej funkcji) do tej funkcji i móc zmienić ew ustawienia
    b) przytrzymując dłużej przycisk menu (np 2sek) wyjść z "menu" do trybu "normal" jednocześnie zapisując gdzieś (chyba do int eeprom?) zmiany


    Szukałem podobnego projektu z obsługą tda7318 ale chyba w żadnym nie było źródeł pod atmege, jedynie co znalazłem pod 89c52 ale jakoś niebardzo rozumiem jak to tam jest zrobione no i chyba troche inaczej niż ja chciałbym


    dziękuje i pozdrawiam

  • #2 01 Lis 2008 09:43
    Maciek4141
    Poziom 22  

    Witam, osobiście bym zrobił to w ten sposób:
    1)Jak masz "normal" i procesor wykona wszystkie zawarte w nim funkcje(procedury), wtedy dajesz Do...Loop...End i tam umieszczasz funkcję np. z if`ów która po naciśnięciu danego przycisku przenosi cię do następnego podprogramu(Sub`y), i tak w kółko.
    a/b) Tutaj możesz zrobić to na zasadzie, że w/w pętli dać coś takiego, że będzie do wcześniej zdeklarowanej zmiennej dodawał wartość. Po puszczeniu przycisku należałoby sprawdzić, czy wartość jest mniejsza np. od 100 czy większa i wtedy przenosić do danego Sub`a.

    Pozdrawiam

  • #3 01 Lis 2008 11:12
    mszkoda
    Poziom 9  

    witam

    nie wiem czy ma to większy sens ale dołożyłem osobne suby dla przycisków

    Code:

    '###########################
       Sub Pwronbtn                                     'włączanie
       Set Portc.3
       Call 5ms
       If Pinc.3 = 1 Then Goto Power_on
       End Sub
       '###########################

       Sub Pwrbtn                                        'wyłączanie
       Set Portc.3
       Call 5ms
       If Pinc.3 = 1 Then Goto Power_off
       End Sub
       '###########################
       Sub Menubtn                                      ' button menu
       Set Portc.0
       Call 5ms
       If Pinc.0 = 1 Then Goto Menu
       End Sub
       '###########################


    i pozmieniałem w kodzie powyżej, tak że

    poweroff wygląda tak:
    Code:
    Sub Power_off:
    

         Call 100ms
         Cls
         Upperline
          Lcd "power off"
         Lowerline
          Lcd "wylaczanie..."
         Call 500ms
         Cls
         Call 500ms
         Call 500ms
         Call Redled
         Do
         Call Pwronbtn
         Loop
         End Sub


    a tryb "normal" tak:
    Code:

    Sub Normal
       Cls
       Lcd "Mode:"
       Lowerline
       Lcd "Normal..."
       Call Greenled
       Do
       Call Pwrbtn
       Call Menubtn
       Loop
       End Sub

    Chyba wyszło tak jak @Maciek4141 podpowiedział, i o ile wyłączanie działa prawidłowo i wejście do menu również :) pomijając poruszanie sie po menu którego jeszcze nie rozumiem, to wyjście z menu do normal zadziałać jeszcze nie chce


    edit:

    udało sie zrobić coś takiego
    Code:
    Sub Menu
    
       Cls
       Lowerline
       Lcd "Menu"
       Call 500ms
       Do
       Locate 1 , 1
       Select Case Menuu
       Case Is = 1
       Lcd T1
       Case Is = 2
       Lcd T2
       Case Is = 3
       Lcd T3
       Case Is = 4
       Lcd T4
       Case Is = 5
       Lcd T5
       End Select

       If Pinc.1 = 1 Then
       Incr Menuu
       Call 500ms
       End If

       If Pinc.2 = 1 Then
       Decr Menuu
       Call 500ms
       End If

       If Pinc.0 = 1 Then
       Cls
       Call 5ms
       Lcd "exit menu"
       Call 500ms
       Call 500ms
       Call Normal
       End If
       Loop
       End Sub


    opóźnienia takie duże bo inaczej w symulatorze nie chce działać poprawnie, ale chyba jest dobrze?


    pozdrawiam

  • #4 01 Lis 2008 20:57
    Maciek4141
    Poziom 22  

    Witam, co do tego wyjścia można zrobić to jeszcze łatwiej. Poniżej zamieszczam przykładowy kod.

    Code:

    $crystal = 1000000

    Declare Sub Normal
    Declare Sub Menu1
    Declare Sub Menu2


    Config Pinb.0 = Input


    Do

    Call Normal

    Loop
    End


    Sub Normal:
       Cls
       Lcd "NORMALNY"
       Do
          If Pinb.0 = 0 Then                                    'JEZELI NA PINIB.0 POJAWI SIE STAN NISKI
             Call Menu1                                         'WTEDY IDZEMY DO MENU 1
          End If

       Loop
       End
    End Sub



    Sub Menu1:
       Cls
       Lcd "MENU 1"
       Lowerline
       Lcd "DOKONAC ZMIAN?"

       Waitms 400                                               'OPÓŹNIENEI PRZED POPRZEDNIM "KLIKNIECIEM" NA PINIEB.0
       Do
         If Pinb.0 = 0 Then                                     'JEZELI NA PINIEB.0 POJAWI SIE STAN NISKIE WTEDY
             Waitms 500                                         'CZEKAMY 500ms
             If Pinb.0 = 0 Then                                 'JEZELI TEN STAN UTRZYMUJE SIE NADAL
                Call Normal                                     'WTEDY WRACAMY DO NORMAL
             Else                                               'JEŻELI NIE
                Call Menu2                                      'IDZEMY DO MENU2 GDZIE MOZNA DOKONYWAC ZMIAN
             End If
          End If

       Loop
       End
    End Sub




    Sub Menu2:
       Cls
       Lcd "DOKONYWANIE ZMIAN"

       Do
       Loop
       End
    End Sub



    Co do GÓRA/DÓŁ to robisz to w taki sposób że w każdym sub`ie musisz dać DO...Loop End i tam dajesz warunek if, jeżeli zostanie on spełniony to przenosi ci do następnego podprogramu (menu x), jeżeli nie to pętla będzie cały czas czekała na spełnienie któregokolwiek warunku.

    Pozdrawiam

  • #5 03 Lis 2008 16:49
    mszkoda
    Poziom 9  

    witam,

    Na tą chwile menu wydaje się już być opanowane :)

    Zmieniłem tytuł tematu gdyż obecne moje pytanie nie dotyczy menu....


    wycinek z kodu:

    Code:

    Dim Write1 As Eram Byte 
    Dim Read1 As Byte

    ...

    Write1 = 44
    Writeeeprom Write1 , &H0A
    Readeeeprom Read1 , &H0A
    Lcd Read1



    Zapisuje sobie wartość 44dec do int eeproma pod adres H0A i tu jest dobrze, gdyż w eepromie wpisuje się 2C hex, natomiast przy odczycie i wyświetleniu tego na lcd (w celu podglądu) nie dostaje ani 44dec ani 2C hex tylko zupełnie inną wartość , pewnie mój ewidentny błąd, tylko gdzie?

    W helpie niestety nie znalazłem rozwiązania :(

    pytanie 2

    eeprom jak wiadomo ma określoną liczbę zapisu, dobrym rozwiązaniem zatem jest aby zmienne w trakcie działania programu zapisywać w sram a dopiero w momencie przejścia do trybu "standby" kopiować sram do eepprom? (oczywiście tylko to co potrzeba) a w momencie "init" kopiować z eepromm do sram?

    a) jak będzie wyglądać funkcja kopiowania bajtów lub określonego obszaru od - do z sram do eeprom i odwrotnie?

    b) atmega używa sram w czasie pracy programu (chyba tak?), w jakim obszarze sram moge swobodnie umieszczać zmienne żeby nie zostały zmienione przez inne funkcje programu, nie wiem czy dobrze opisałem, ale na przykładzie aby zmienna write1 była umieszczana w komórce przykładowo H0A (lub każdej innej, ale żeby był zdefiniowany jej adres)


    dziękuje i pozdrawiam

  • #6 03 Lis 2008 21:30
    dawid512
    Poziom 32  

    Cytat:
    Code:
    Dim Write1 As Eram Byte 
    
    Dim Read1 As Byte

    ...

    Write1 = 44
    Writeeeprom Write1 , &H0A
    Readeeeprom Read1 , &H0A
    Lcd Read1


    Pomijając literówkę w słowie "eeprom" to deklarując zmienną jako eram byte to siłą rzeczy zostaje ona automatycznie zapisywana do eepromu pod adres 0. Masz dwie opcje: pierwsza to deklaracja zmiennej jako eram byte i odczytywanie jej z eepromu z adresu 0 lub zapisanie zmiennej jako byte i wcześniejszy jej zapis do eepromu pod dowolny adres i następnie odczytanie jej z niego. Po za tym &H0A to nie to samo co &HA? Po co komplikujesz?

  • #7 03 Lis 2008 23:33
    mszkoda
    Poziom 9  

    dawid512 napisał:

    Pomijając literówkę w słowie "eeprom" to deklarując zmienną jako eram byte to siłą rzeczy zostaje ona automatycznie zapisywana do eepromu pod adres 0.
    Masz dwie opcje: pierwsza to deklaracja zmiennej jako eram byte i odczytywanie jej z eepromu z adresu 0 lub zapisanie zmiennej jako byte i wcześniejszy jej zapis do eepromu pod dowolny adres i następnie odczytanie jej z niego.


    nie wiem czy dobrze zrozumiałem....
    zadeklarować zmienną aby jej wartość była brana z danego adresu w eeprom a jak będę chciał ją oczytać (wartość tej zmiennej) to zczytać adres 0 ? (ale odczytywać już chyba nie z eeprom, tylko z sram? i wartość będzie odczytywana prawidłowo?

    dawid512 napisał:

    Po za tym &H0A to nie to samo co &HA? Po co komplikujesz?

    a to coś komplikuje?


    Może dodam mały opisik, możliwe że będzie laicko opisany...

    Załóżmy że program będzie korzystał z max 10 zmiennych, które będą zapisywane w pamięci eeprom atmegi, lub jeśli była by taka konieczność to w zewnętrzym eepromie. (pamięci typu 24Cxx się zawsze znajdą)
    Te wartości to będą typowe nastawy tda7318 typu volume, bass, treble, on/off mute i co tam jeszcze potrzeba.

    Założyłem sobie może dobrze a może źle, że w momencie "init'u" (czyli włączeniu po zaniku zasilania) program wykona operacje skopiowania tych nastaw z eeproma do sram? i wyśle przez i2c do tda i przejdzie w tryb standby.

    Czyli albo skopiuje wszystkie nastawy do sram pod znany mi adres i będe później operował na tych zmiennych (w czasie init wysyłał do tda7138) uwzględniając ich adres?
    czy też należy zadeklarować jedną zmienną z eeprom która będzie w sram pod adresem 0 i wysłać ją do tda7318 i następnie tak samo z drugą zmienna ? itd..

    z kolei w czasie przejścia do standby chciał bym aby zmienne (nastawy tda7318) lądowały do eeprom tak aby po zaniku zasilania nie trzeba było ustawiać na nowo, ewentualnie dodać sprawdzenie czy aktualne nastawy tda7318 są zgodne z tymi co w eeprom - jeśli zgodne to nie zapisuj do eeprom, a jeśli nie zgodne to zapisz do eeprom (żeby nadmiernie nie eksploatować eeproma )

    w tekście celowo pogrubiłem, gdyż nie wiem czy adres 0 bedzie sie tyczył eeprom czy sram

    to jest mój pierwszy kontakt z bascomem , avr, tda7318 i można powiedzieć że z programowaniem również, więc licze na uprzejmość i wybaczenie mojej wielkiej niewiedzy :D

  • #8 03 Lis 2008 23:50
    dawid512
    Poziom 32  

    Kolego zmienne zapisane w SRAM to zmienne które znikają z tej pamięci po zaniku napięcia.

    Zmienne zapisane w EEPROM to zmienne które pozostają w pamięci nawet po zaniku napięcia ale uwaga: staraj się nie zapisywać zmiennych pod adresem 0 gdyż mogą one ulec wyczyszczeniu.

    Proponuję zrobić tak:
    Masz tam swoje zmienne w SRAM i w wypadku zaniku napięcia zapisujesz je do EEPROMU. Następnie gdy wróci napięcie odczytujesz je z niego i w tym momencie kopiujesz wartości zmiennych z EEPROMU do pamięci SRAM.

    Możesz także zrobić coś takiego choć wydaje mi się to nadwyrężaniem EEPROMA(niestety nie wiem kiedy zostają wymienione wartości zmiennych pomiędzy SRAM a EEPROMEM):

    Code:
    Dim Write1 As Eram Byte
    
    Dim Write2 As Eram Byte
    Dim Read1 As Byte
    Dim Read2 As Byte
    ....

    Write1 = &H01
    Write2 = &H02

    ....
    Readeeprom Read1 , 0
    Readeeprom Read2 , 1
    ....

  • #9 04 Lis 2008 12:23
    mszkoda
    Poziom 9  

    dawid512 napisał:
    Kolego zmienne zapisane w SRAM to zmienne które znikają z tej pamięci po zaniku napięcia.

    Zmienne zapisane w EEPROM to zmienne które pozostają w pamięci nawet po zaniku napięcia ale uwaga: staraj się nie zapisywać zmiennych pod adresem 0 gdyż mogą one ulec wyczyszczeniu.

    Wiem o tym
    dawid512 napisał:

    Proponuję zrobić tak:
    Masz tam swoje zmienne w SRAM i w wypadku zaniku napięcia zapisujesz je do EEPROMU. Następnie gdy wróci napięcie odczytujesz je z niego i w tym momencie kopiujesz wartości zmiennych z EEPROMU do pamięci SRAM.

    pisałem powyżej że tak właśnie chce zrobić

    dawid512 napisał:

    Możesz także zrobić coś takiego choć wydaje mi się to nadwyrężaniem EEPROMA(niestety nie wiem kiedy zostają wymienione wartości zmiennych pomiędzy SRAM a EEPROMEM):
    Code:
    Dim Write1 As Eram Byte
    
    Dim Write2 As Eram Byte
    Dim Read1 As Byte
    Dim Read2 As Byte
    ....

    Write1 = &H01
    Write2 = &H02

    ....
    Readeeprom Read1 , 0
    Readeeprom Read2 , 1
    ....


    piałem powyżej i pytałem się czy dobre rozwiązanie bedzie skopiowanie zmiennych z eeprom do sram w momencie initu, i wyslanie ich przez i2c do tda, i następnie jeśli będe zmieniał nastawy, to będe działał na zmiennych będących w sram, i następnie przy wyłączaniu programu (przejściu do standby) porówbywał te wartości z istniejącymi w eeprom i jeśli będą inne to wtedy nadpisywał,

    nie wiem jeszcze jak to zrobić :|

  • #10 04 Lis 2008 15:47
    dawid512
    Poziom 32  

    Cytat:
    następnie przy wyłączaniu programu (przejściu do standby) porówbywał te wartości z istniejącymi w eeprom i jeśli będą inne to wtedy nadpisywał,

    nie wiem jeszcze jak to zrobić Neutral


    Zrób tak:
    Jeśli spadek napięcia(przechodzenie w tryb standby) odczytaj wartości ze zmiennych w eeprom i w tym momencie masz je w SRAM. Zrób warunek typu:
    Code:
    if zmienna_sram <> zmienna_eeprom then
    
    wrtiteeeprom zmienna_sram, adres
    end if

  • #11 06 Lis 2008 07:59
    Andy74
    Poziom 24  

    Witam.

    Jeśli deklarujesz zmienną typu eram, to bezcelowe jest korzystanie w dalszej części programu z poleceń readeeprom i writeeeprom. Po to zapewne wprowadzono (w którejś z nowszych wersji Bascoma) możliwość deklaracji takiej zmiennej, by móc uniknąć korzystania z tych mało wygodnych (jak na Bascoma ;)) poleceń.
    Jeśli chcesz, aby Twoja zmienna została umieszczona w pamięci eeprom pod konkretnym adresem, wystarczy ją odpowiednio zadeklarować:

    Code:
    Dim Zmienna_eeprom As Eram Byte At Adres_komorki

    W ten sam sposób można deklarować zwykłe zmienne w pamięci sram, jeśli chcemy by znajdowały się one w komórkach o konkretnym adresie, ale w tym wypadku nie widzę sensu komplikowania sobie życia. Jeśli tylko prawidłowo napiszesz program, to kompilator już sam zadba o rozmieszczenie zmiennych w sram, i nie musisz się martwić że zostaną one nadpisane przez inne (poczytaj o poleceniach kompilatora $hwstack, $swstack, $framesize)
    Wracając do sprawy zapisu do eeprom, jak i odczytu z niego. Dokonuje się tego przez proste działania:
    Code:
    Dim Zmienna_eeprom As Eram Byte At Adres_komorki
    
    Dim Zmienna_ram As Byte
    '...
    Zmienna_eeprom = Zmienna_ram   'zapis do eeprom
    Zmienna_ram = Zmienna_eeprom   'odczyt z eeprom
    '...

    Proste, prawda? Trzeba tylko pamiętać o kilku podstawowych ograniczeniach związanych ze stosowaniem zmiennych typu eram (np. nie wykonuje się na nich operacji matematycznych), o których można się dowiedzieć z pliku pomocy Bascoma, czy chociażby z forum.
    mszkoda napisał:
    pytałem się czy dobre rozwiązanie bedzie skopiowanie zmiennych z eeprom do sram w momencie initu, i wyslanie ich przez i2c do tda, i następnie jeśli będe zmieniał nastawy, to będe działał na zmiennych będących w sram, i następnie przy wyłączaniu programu (przejściu do standby) porówbywał te wartości z istniejącymi w eeprom i jeśli będą inne to wtedy nadpisywał

    Koncepcja jak najbardziej słuszna, z tym, że ja porównywał bym i ewentualnie zapisywał nastawy za każdym razem po wyjściu z menu, które jak widzę planujesz zrobić. Unikniesz w ten sposób ich utraty w razie zaniku zasilania. Eeprom ma gwarantowane 100000 cykli zapisu dla każdej komórki (z doświadczenia wiem, że potrafi wytrzymać dużo więcej), więc jeśli nie zrobisz w programie jakiegoś kardynalnego błędu powodującego np. zapętlenie się jego fragmentu z procedurą zapisu - nic mu nie grozi.

    Pozdrawiam
    Andy

 
Promocja -20%
Zamknij 
Wyszukaj w ofercie 200 tys. produktów TME
tme