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

[bascom] programowanie zewnetrznego eerpom za pomoca uart

wader_669 26 Lis 2008 19:15 1713 21
  • #1 5786704
    wader_669
    Poziom 28  
    mam taki problem chcialem poprzez przejsciowke usb-uart zrobic programowanie zewnetrznej pamieci 24c64. Komunikacja z nia odbywa sie po i2c.
    Udalo mi sie napisac program ktory zapisuje do pamieci dane wklepywane z terminalu do tej pamieci. Problem jest taki ze za kazdym razym po podaniu znaku musze wciskac eneter, tego chcialem sie pozbyc. A w procku nie chce zwiekszyc miejsca na zmienna.

    znalazl moze ktos rozwiazanie?

    kod:
    
    $baud = 9600
    
    Dim Address As Word
    Dim Address1 As Byte At Address + 1 Overlay
    Dim Address2 As Byte At Address Overlay
    Address = 0
    
    Dim Znak_eeprom As String * 1
    Echo On
    
    do
    cls
    locate 1, 1
    Do
    If Ischarwaiting() = 1 Then
    Do
    Input Znak_eeprom
    lcd Znak_eeprom
    
    I2cstart
    I2cwbyte 160
    I2cwbyte Address1
    I2cwbyte Address2
    I2cwbyte Znak_eeprom
    I2cstop
    Incr Address
    Loop Until Znak_eeprom = "x"
    End If
    
    Loop
    end
    
  • Pomocny post
    #2 5787207
    K_o_n_r_a_d
    Poziom 23  
    Zamiast INPUT użyj do odczytu danych polecenie WAITKEY().
  • #3 5787824
    wader_669
    Poziom 28  
    dzieki wszystko dziala
    teraz kod wyglada tak:
    
    
    Err = 0
    Address = 0
    cls
    locate 1 , 1
    Do
    Znak_eeprom = Waitkey()
    Print Znak_eeprom ;
    lcdZnak_eeprom
    
    I2cstart
    I2cwbyte 160
    If Err = 1 Then Call Brak
    I2cwbyte Address1
    I2cwbyte Address2
    I2cwbyte Znak_eeprom
    I2cstop
    Incr Address
    
    Loop Until Znak_eeprom = "X"
    


    A jak bym chcial zrobic powrot do normalnego programu, np. za pomoca przyciskow, wie ktos moze jak cos takiego zrobic?
  • #4 5787929
    K_o_n_r_a_d
    Poziom 23  
    wader_669 napisał:
    A jak bym chcial zrobic powrot do normalnego programu, np. za pomoca przyciskow, wie ktos moze jak cos takiego zrobic?
    Dokładnie w ten sam sposób co masz w tej chwili, tylko zamiast obracać pętlę do czasu otrzymania znaku 'X' to obracasz do czasu naciśnięcia przycisku. Np.
    ...
    Loop Until PinB.0 = 0 
    lub też rozbudowując ten warunek możesz zrobić jednocześnie kilka możliwości powrotu wykorzystując operatory AND, OR itp.
  • #5 5787960
    wader_669
    Poziom 28  
    :D hehe wiem o tym ze tak sie da, ale nie w tym przypadku (testowalem)
  • Pomocny post
    #6 5787983
    K_o_n_r_a_d
    Poziom 23  
    Acha no tak, za szybko napisałem. Wszystko przez to, że WAITKEY() czeka na znak - zatrzymuje program. W takiej sytuacji trzeba użyć INKEY(), ale wcześniej sprawdzać, czy jest odebrany jakikolwiek znak. Dodatkowo zastosowałbym buforowanie transmisji.
    CONFIG  SERIALIN = BUFFERED , SIZE = rozmiar 
    
    (c) Zbigniew Gibek, 2002-2005   (c) MCS Electronics, 1999-2005
    aby sprawdzić czy w buforze jest jakiś odebrany znak nalezy porównać wskaźniki:
    _RS_HEAD_PTR0	bajt – wskaźnik, określający gdzie znajduje się pierwszy jeszcze nie przetworzony a odebrany bajt,
    _RS_TAIL_PTR0	bajt – wskaźnik określający gdzie znajduje się ostatni jeszcze nie przetworzony a odebrany bajt,
    
    (c) Zbigniew Gibek, 2002-2005   (c) MCS Electronics, 1999-2005

    INKEY() nie zatrzymuje programu.
  • #7 5815133
    wader_669
    Poziom 28  
    Dopiero teraz doszlo do tego ze znowu sie tym zajalem. Probowalem samym inkey i wywala mi niezle bledy.
    Pytanie czy jak zrobie waitkey i bede mial zewnetrzne przerwanie to przestanie czekac na znak z uart'u ?

    __________________________________________

    juz wiem gdzie mam bledy czyli jednak musze zrobic tak jak ty piszesz :/ wuchta roboty, zaraz postaram sie cos wklepac w kompilator :D
  • #8 5815157
    K_o_n_r_a_d
    Poziom 23  
    Zewnętrzne przerwanie nie ma nic wspólnego z WAITKEY. WAITKEY czeka do czasu aż coś odbierze.
    Jakie błędy przy INKEY? Coś źle zrobiłeś.
  • #9 5815179
    wader_669
    Poziom 28  
    nie, jak mam waitkey to zatrzymuje caly program i czeka na znak. Czy jak bede mial zewnetrzne przerwanie to przerwie to czekanie na znak?
  • Pomocny post
    #10 5815208
    K_o_n_r_a_d
    Poziom 23  
    Taj jak napisałem wyżej.
    WAITKEY będzie czekało do czasu, aż coś odbierze. Jeśli w tym czasie wystąpi jakieś przerwanie to się ono wykona i wróci do programu wykonywanego wcześniej, czyli do WAITKEY (chyba, że WAITKEY będzie w jakimś podprogramie przerwania - wtedy kolejne przerwanie się nie wykona (wykona się po skończeniu aktualnego), chyba że na to zezwolimy - ale tak nie należy robić).
    ----
    WAITKEY to to samo co:
    DO LOOP UNTIL ISCHARWAITING()=1
    zmienna = INKEY()
  • #11 5815246
    wader_669
    Poziom 28  
    hehe ale bajer wszystko dziala dzieki za pomoc, sprawe rozwiazalem tak:
    (kod byl jeszcze pisany tak by wszystko pokazywalo na wyswietlaczy od noki 3310 z tad te tprintf, tlocate, tcls)
    
    Sub Program
    Address = 0
    Tcls
    Tlocate 0 , 0
    Do
    Czekanie = Ischarwaiting()
    
    If S4 = 0 Then
    Waitms 25
    Bitwait S4 , Set
    Call Main
    End If
    
    If Czekanie = 1 Then
    
    Znak_eeprom = inkey()
    Print Znak_eeprom ;
    Tprintf Znak_eeprom
    
    
    I2cstart
    I2cwbyte 160
    I2cwbyte Address1
    I2cwbyte Address2
    I2cwbyte Znak_eeprom
    I2cstop
    Incr Address
    End If
    
    Loop
    End Sub
    


    (myslalem ze bedzie trudniejsze)
    jak bedzie ktos zainteresowany calym kode prosze pisac umieszcze.
    Wydaje mi sie, ze jest to fajny projekt. Niezly zamiennik jdm i podobnych programatorow zew. eeprom
  • Pomocny post
    #12 5815327
    K_o_n_r_a_d
    Poziom 23  
    Hmm... w końcu używasz WAITKEY, więc zmienna Czekanie nie ma sensu. Dodatkowo:
    Czekanie = Ischarwaiting()
    wykonujesz przed obsługą przycisku i jakąś procedurą MAIN. Teraz jeśli w trakcie obsługi przycisku i wykonywania procedury MAIN wyślesz dane to nie zostaną one zapisane w EEPROMie
    Ja jednak przerobiłbym program i użyłbym INKEY.
    Sama obsługa przycisku też nie do końca mi się podoba :) Zastosuj lepiej DEBOUNCE.
    -----------------------------------------
    A... to chyba w ogóle tym przyciskiem chcesz wyjść z tej procedury - to tak być nie może! W ten sposób stos przepełnisz. Gdy chcesz wyjść z tej procedury musisz wykonać ją do końca a nie wywoływać procedurę z której wywołałeś aktualnie wykonywaną.
  • #13 5815498
    wader_669
    Poziom 28  
    no tak mi sie wydawalo najprosciej. Wlasnie chce zeby zapisywal tylko wtedy gdy jestem w sub'ie program. zmienilem na inkey

    A co z wyjsciem z tego sub'a to mam uzyc return?
    dojsc do konca nie moze bo wyladuje w krzakach, nie?
    (wiem ze musze w tych sprawach sie doksztalcic, tylko z tego tematu: https://www.elektroda.pl/rtvforum/topic1152738.html link wygasl )
  • Pomocny post
    #14 5815585
    K_o_n_r_a_d
    Poziom 23  
    RETURN służy do zakończenia podprogramu a nie procedury. Nie pamiętam czy jest jakieś polecenie do wyjścia z procedury, ponieważ nigdy na pewno nie używałem nawet jeśli istnieje. Zawsze tak tworzę procedury aby program dochodził do końca i sama się kończyła.
    Ja całą procedurę przerobiłbym tak:
    Dim Koniec As Byte
    Sub Program
       Address = 0
       Tcls
       Tlocate 0 , 0
       Koniec = 0
       Do
          Debounce S4 , 0 , P_s4 , Sub
          If Ischarwaiting() = 1 Then
             Znak_eeprom = Inkey()
             Print Znak_eeprom
             Tprintf Znak_eeprom
    
             I2cstart
             I2cwbyte 160
             I2cwbyte Address1
             I2cwbyte Address2
             I2cwbyte Znak_eeprom
             I2cstop
             Incr Address
          End If
       Loop Until Koniec = 1
    End Sub
    
    P_s4:
       Koniec = 1
    Return

    albo nawet zlikwidować DEBOUNCE i zrobić coś takiego (o ile taka redukcja drgań styków wystarczy):
    Sub Program
       Address = 0
       Tcls
       Tlocate 0 , 0
       Do
          If Ischarwaiting() = 1 Then
             Znak_eeprom = Inkey()
             Print Znak_eeprom
             Tprintf Znak_eeprom
    
             I2cstart
             I2cwbyte 160
             I2cwbyte Address1
             I2cwbyte Address2
             I2cwbyte Znak_eeprom
             I2cstop
             Incr Address
          End If
       Loop Until S4 = 0
       Waitms 20
       Bitwait S4 , Set
    End Sub
  • #15 5815634
    Andy74
    Poziom 25  
    K_o_n_r_a_d napisał:
    Nie pamiętam czy jest jakieś polecenie do wyjścia z procedury, ponieważ nigdy na pewno nie używałem nawet jeśli istnieje.

    Exit Sub - przydaje się :)
  • #16 5815669
    wader_669
    Poziom 28  
    no dobra a czy z jednej procedury mozna wywolac druga procedure ? bo tutaj wyglada to tak ze to jest menu wielopoziomowe i z tej drugiej wrocic jakos do pierwszej
  • Pomocny post
    #17 5815672
    K_o_n_r_a_d
    Poziom 23  
    Cytat:
    no dobra a czy z jednej procedury mozna wywolac druga procedure ?
    Oczywiście, że można wywoływać - można wywoływać dowolnie dopóki pamięci na stos wystarczy.
    Cytat:
    bo tutaj wyglada to tak ze to jest menu wielopoziomowe i z tej drugiej wrocic jakos do pierwszej
    Gdy skończy się wykonywać ta druga to wróci program do pierwszej.
  • #18 5860532
    wader_669
    Poziom 28  
    Dobra to chyba wszystkie moje watpliwosci sa wyjascnione. Nie wiem czy ktorys z kolegow chce cos dodac, jak nie to pojutrze temat zamykam.
    Jeszcze raz dzieki K_o_n_r_a_d za pomoc.
    ______________________________________________________________
    Jeszcze moze dodam, ze nie uzylem debounce, bo chce zeby procesory wykonywal czynnosc po puszczeniu switcha
    _____________________________________________________________
    Dobrz ze nie zamknelem tematu, bo pojawil sie proble:

    po tym jak dodalem opcje czyszczenia pamieci i ja uruchomilem cos sie zrabalo i nie chce czytac odpowiednio.
    Moze pierw umieszcze kod:

    
    Dim Address As Word , Address1 As Byte At Address + 1 Overlay , Address2 As Byte At Address Overlay 
    dim znak as string*1
    
    znak="{255}"
    For Address = 0 To 65535 
             I2cstart
             I2cwbyte 160
             I2cwbyte Address1
             I2cwbyte Address2
             I2cwbyte znak
             I2cstop
    Next
    


    jeszcze czytalem ze mozna to tak zrobic

    
    i2csend 160, znak, 65535
    


    jednak nie mam jak tego przetestowac bo pamiec padla :(
  • #20 5860794
    wader_669
    Poziom 28  
    nie bo do eepromu wpisuje zmienne typu string a "{255}" to jest decymarnie 255
  • #21 5860849
    K_o_n_r_a_d
    Poziom 23  
    No ale jak sama nazwa wskazuje polecenie I2cwbyte wysyła bajta a nie stringa.
    Jak chcesz zapisać stringa to musisz go rozbić na pojedyncze bajty.
  • #22 5893150
    wader_669
    Poziom 28  
    to jest jasne ale tutaj uzywam string*1 czyli jednego bajta.
    Udal mi sie zapis przez przejsciowki usb>com, podobnie to robilem tylko teraz zamiast stringa otrzymanego z uart wpisuje 255 i to 65535 razy

    (poprawilem troche kod)
    ________________________________________________

    Problem sie rozwiazal, kasowanie dziala. Okazalo sie, ze kabel byl luzny :P sorry za problemy
REKLAMA