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

BASCOM RS232 i PC - wysyłanie 512bajtów

TomekMus 31 Paź 2009 22:26 5617 20
REKLAMA
  • #1 7200079
    TomekMus
    Poziom 17  
    Witam,

    Chcę zapisać plik wysłany z PC na karcie pamięci MMC.

    Na karte zapisuejemu 512bajtów za jednym zapisem czyli jeden sektor.

    Tak więc aby aplikacja zapisała plik np. 5MB na karcie MMC chcę zrobić tak by uC odbierał 512bajtów z RS'a a nasiępnie je zapisał na MMC i tak aż uzyskamy 5MB.

    Sam zapis na MMC 512 bajtów potrafie napisać lecz jak skutecznie odebrać 512bajtów z PC.

    Na PC mam aplikację napisaną w Delphi i bufor wyjściowy mam 512 tak więc za jednym razem wysyłam 512 bajtów daję mini opóźnienie na zapis przez uC danych do karty MMC i ponawiam wysłanie kolejnych 512bajtów.



    Jak najlepiej odebrać 512 bajtów z PC?
  • REKLAMA
  • Pomocny post
    #2 7200286
    Konto nie istnieje
    Poziom 1  
  • #3 7200357
    TomekMus
    Poziom 17  
    Mogę Cię prosić o przykład takiego przerwania. Będę wdzięczny bo na BASCOM'ie "się znam" ale jak chodzi o o RS'a to kuleję.
  • REKLAMA
  • Pomocny post
    #4 7200426
    mirekk36
    Poziom 42  
    Nic nie musisz (jeśli chodzi o Bascom - sam robić w przerwaniu) Bascom ofruje ci za free - pełną sprzętową obsługę RS232.

    Zapoznaj się tylko z poleceniem Config Serialin oraz z parametrem Bytematch tego polecenia - a wszystko stanie się jasne. Nic nie będziesz musiał sam oprogramowywać w przerwaniu bo to jest bez sensu.

    po prostu będziesz wysyłał paczki danych i zapisywał je do sektora
  • #5 7200584
    TomekMus
    Poziom 17  
    Mirkku - uda się z przykładem?

    Dodano po 1 [godziny] 13 [minuty]:

    $regfile = "m128def.dat"
    $crystal = 14745600
    $baud = 115200
    $hwstack = 150                                              'wartosc stosu
    $swstack = 150                                              'wartosc stosu
    $framesize = 150                                            'wartosc ramki
    
    
    Enable Interrupts
    
    Config Serialin = Buffered , Size = 130 , Bytematch = 13
    
    
    Dim Ar(65) As Byte
    Dim I As Byte
    Dim J As Byte
    
    
    
    Do
    Loop
    
    Serial0charmatch:
         For I = 1 To 65
           Ar(i) = Inkey()
         Next I
    
         J = Crc8(ar(1) , 64)                                   'sprawdzam crc 64bajtow
    
         If J = Ar(65) Then
           'zapisuje 64bajty na karte mmc
         End If
    Return
    
    End


    Czy dobrze zrozumiałem???
    To co napisałem jest poprawne? Mam pytanie czy bytematch to pierwszy odebrany znak czy ostatni?
  • Pomocny post
    #6 7200846
    mirekk36
    Poziom 42  
    Najważniejsze to chociaż troszkę samemu najpierw pokombinować i ew później dopytać co i jak ;) ale po co ten Inkey? toż jak już zajdzie zdarzenie Bytematch - to znaczy, że w twoim buforze jest już co najmniej jedeń łańcuch tekstowy, którzy przyleciał z Rs232 i zakończony znakiem ENTER (13) .... w związku z tym wystarczy dać polecenie Input linia i już w zmiennej linia będziesz miał pierwszy odebrany łańcuch z bufora i to już bez znaku (13) ponieważ Input go ładnie wytnie. (Coś takiego podpowiedział mi kiedyś tu na forum kolega zumek)

    Zobacz co się dzieje:

    1. Ustawiamy parametry RS232 i bufora wg potrzeb (wielkość itp)
    2. definiujemy sobie podstawowe funkcje
    3. definiujemy zmienne, gdzie

    zmienna Event - odpowiada ilości wystąpień znaków 13 w buforze co się równa ilości łańuchów znaków zakończonych enterem, które zdążyły nadlecieć przez RS232 do bufora. Tak więc procedura Serial0charmatch zajmuje się tylko i wyłącznie zwiększaniem licznika tych łańuchów a dalsza obsługa już poprzez funkcję

    Getline - która zwraca ilość znaków łańucha, który czeka spokojnie na ciebie, na obsłużenie w buforze. Tak więc w tej funkcji zerowana jest na początku zmienna Linia, później sprawdzany jest licznik zdarzeń Event i jeśli jest większy od 0 to znaczy, że trzeba szybko pobrać do zmiennej Linia cały ciąg znaków, który czeka w buforze. Robione jest to poleceniem Input, które jest też odpowiednio na początku skonfigurowane (zobacz jak) .... po czym Input pobiera te znaki z bufora do zmiennej Linia i wycina ładnie znak (13). Jednocześnie po odebraniu już jednej porcji danych z bufora (a może ich być więcej w zależności od jego rozmiaru) zmniejszana jest wartość zmiennej Event

    Całość pozwala pięknie i bezkolizyjnie obsługiwać tego typu transmisję w Bascomie przez RS232 .... działa to pięknie


    
    Config Serialin = Buffered , Size = 180 , Bytematch = 13
    
    Declare Function Getline() As Byte   
    Declare Sub Obsluga_rs232  
    
    Dim Event As Byte 
    Dim Linia As String * 120
    Config Input = Cr , Echo = Crlf
    
    ' Pętla główna
    Do
    ...
    ... 'jakieś tam twoje inne działania w pętli
    ...
    
       ' obsługa przychodzących danych przez RS232
       If Getline() > 0 Then
          Call Obsluga_rs232
       End If
    
    ...
    ... 'jakieś tam jeszcze inne działania w pętli
    ...
    Loop
    
    
    
    Serial0charmatch:             'po odebraniu znaku Chr(13) zwiększenie licznika lini(zdarzeń)
    lds r24,{event}
    inc r24
    sts {event},r24
    Return
    
    
    
    Function Getline()as Byte
    Linia = ""
    If Event > 0 Then
    
       If _rs_bufcountr0 > 0 Then Input Linia , Noecho
       Err = 0
       Getline = Len(linia)
    
       Cli
       Decr Event
       sei
    
    End If
    End Function
    
    
    
    
    Sub Obsluga_rs232  
    
    .....'tutaj już spokojnie analizujesz sobie co masz w zmiennej LINIA
    
    Return
    
  • #7 7230083
    TomekMus
    Poziom 17  
    Problem z Bytematch
  • #8 7265120
    TomekMus
    Poziom 17  
    Mam pytanie które mi po testach się ukazało:

    Wysyłana ramka składa się z bajtów i w środku występuje bajt #13 np:

    #100#45#33#13#44#23#12#11#13#88#34#13#56#87#54#66#13#8#38#13

    Ostatni bajt to dopiero Bytematch = 13

    Jak rozwiązać problem? Bo występujące znaki 13 kończą mi ramke zamoczynnie!
  • REKLAMA
  • Pomocny post
    #9 7299011
    Logan
    Poziom 30  
    Zmień 13 na jakiś inny kod, np 3, albo 2.
  • Pomocny post
    #10 7299851
    mirekk36
    Poziom 42  
    Logan napisał:
    Zmień 13 na jakiś inny kod, np 3, albo 2.


    no tak - tylko co to da - skoro pytający może mieć w ramce dowolne dane binarne ??? w związku z czym jeśli da sobie kod np 3, albo 2 - to za chwilę będzie kolejne takie samo pytanie - jeśli trafi się ramka , która wśród danych będzie miała bajty o wartości 0x03 albo 0x02
  • Pomocny post
    #11 7299951
    Konto nie istnieje
    Poziom 1  
  • #12 7303980
    TomekMus
    Poziom 17  
    kombinowałem jak mogłem i z moich testów wynikło że najlepiej sprawuje się zastosowanie komendy INPUTBIN i Watchdoga.

    Jak instrukcja INPUTBIN przekroczy czas 2 x Ramka czyli błąd jakiś w transmisji to reset uC i sprawdza sie na 100% jedyne rozwiązanie
  • REKLAMA
  • Pomocny post
    #13 7304228
    Konto nie istnieje
    Poziom 1  
  • Pomocny post
    #14 7304401
    mirekk36
    Poziom 42  
    No tak , a do obliczania jakiegoś CRC przydałaby się wtedy nawet jakaś mała wstawka asemblerowa o ile kolega chociaż trochę włada tym językiem. Bo wbrew pozorom - zrobienie wstawki do Bascoma nie jest trudne.

    Z drugiej strony oczywiście popieram kolegę powyżej, że lepiej zawsze zobaczyć w helpie czy da radę jakąś instrukcję bascomową skonfigurować dodatkowo za pomocą słówka Config. Wtedy zwykle może doczytać ciekawe dodatki do niej a w tym konkretnym przypadku TimeOut jest o tyle lepszy, że cały czas panujesz nad programem i błędami przesyłu zamiast oddawać się w ręce głębokiego resetu ;)
  • Pomocny post
    #15 7317724
    xury
    Specjalista automatyka domowa
    Widać, że kolega mirekk36 nie pisuje już w Bascomie niestety :(
    Albo to tak specjalnie by dłużej szukać $TimeOut w Helpie :P ?
    No, a tak szczerze to ja też nie wiedziałem o $Timeout.
    Ale nie da się skonfigurować przez Config :) ... i sam się tego naszukałem (pisałem bez dolara w wyszukiwarce)
  • Pomocny post
    #16 7317762
    mirekk36
    Poziom 42  
    xury -> to fakt, że ostatnio już w Bascomie praktycznie nie programuję ;) ale proszę oto fragment helpa Bascomicznego z dokładnym opisem tego polecenia oraz jak i kiedy można z niego korzystać. Więc nie wiem albo może czegoś nie zrozumiałem z tego co napisałeś - że ponoć tego nie możesz znaleźć czy że nie ma

    Cytat:
    $TIMEOUT
    Top Previous Next
    Action

    Enable timeout on the hardware UART 0 and UART1.

    Syntax

    $TIMEOUT = value

    Remarks

    Value
    A constant that fits into a LONG , indicating how much time must be waited before the waiting is terminated.




    All RS-232 serial statements and functions(except INKEY) that use the HW UART, will halt the program until a character is received. Only with buffered serial input you can process your main program while the buffer received data on the background.



    $TIMEOUT is an alternative for normal serial reception. It is not intended to be used with buffered serial reception.



    When you assign a constant to $TIMEOUT, you actual assign a value to the internal created value named ___TIMEOUT.



    This value will be decremented in the routine that waits for serial data. When it reaches zero, it will terminate.



    So the bigger the value, the longer the wait time before the timeout occurs. The timeout is not in seconds or microseconds, it is a relative number. Only the speed of the oscillator has effect on the duration. And the value of the number of course.

    When the time out is reached, a zero/null will be returned to the calling routine. Waitkey() will return 0 when used with a byte. When you use INPUT with a string, the timeout will be set for every character. So when 5 characters are expected, and they arrive just before the timeout value is reached, it may take a long time until the code is executed.

    When the timeout occurs on the first character, it will return much faster.

    When you already sent data, this data will be returned. For example, "123" was sent but a RETURN was never sent, INPUT will return "123". While without the $TIMEOUT, INPUT will not return until a RETURN is received.

    When you activate $TIMEOUT, and your micro has two UARTS(Mega128 for example) it will be active for both UART0 and UART1.


    i przykład:

    Example
    
    '-----------------------------------------------------------------------------------------
    
    'name                     : timeout.bas
    
    'copyright                : (c) 1995-2005, MCS Electronics
    
    'purpose                  : demonstration of the $timeout option
    
    'micro                    : Mega48
    
    'suited for demo          : yes
    
    'commercial addon needed  : no
    
    '-----------------------------------------------------------------------------------------
    
     
    
    $regfile = "m48def.dat"                                     ' specify the used micro
    
    $crystal = 8000000                                         ' used crystal frequency
    
    $baud = 19200                                               ' use baud rate
    
    $hwstack = 32                                               ' default use 32 for the hardware stack
    
    $swstack = 10                                               ' default use 10 for the SW stack
    
    $framesize = 40                                             ' default use 40 for the frame space
    
     
    
    'most serial communication functions and routines wait until a character
    
    'or end of line is received.
    
    'This blocks execution of your program. SOmething you can change by using buffered input
    
    'There is also another option : using a timeout
    
    '$timeout Does Not Work With Buffered Serial Input
    
     
    
     
    
    Dim Sname As String * 10
    
    Dim B As Byte
    
    Do
    
      $timeout = 1000000
    
      Input "Name : " , Sname
    
      Print "Hello " ; Sname
    
      $timeout = 5000000
    
      Input "Name : " , Sname
    
      Print "Hello " ; Sname
    
    Loop
    
    'you can re-configure $timeout
  • Pomocny post
    #18 7317830
    mirekk36
    Poziom 42  
    hmmm tzn dobrze wydedukowałeś , że już dawno nie pisałem w Bascomie bo właśnie nie pamiętałem że do Timeouta nie dojdzie się w helpie szukając poprzez Config jak zasugerowałem ;)

    ale jak widać dla chcącego nie ma nic trudnego i każdy to znajdzie - tylko trza troszkę poszperać w tym helpie
  • Pomocny post
    #19 7317972
    gothye
    Poziom 33  
    Jeśli jest możliwość wykorzystania pinów uC dodałbym kontrole przepływu przez port sterując sygnały RTS/CTS portu COM co znacznie poprawi wysyłanie i odbieranie z portu bez potrzeby stosowania znaku na koncu wysyłanej ramki ;)
  • #20 7328153
    TomekMus
    Poziom 17  
    Ja sprawdzić że został przekroczony TIMEOUT

    przykładowo:

    $Timeout = 10000
    Inputbin B(1), 200
    
    if time out then
      Print "Coś walło :) "
    end if
  • #21 7328228
    mirekk36
    Poziom 42  
    No chyba "Coś walło" jeśli oczekiwana zmienna jest pusta np = 0 o ile nie zakładasz, że może przylecieć jeden bajt o wartości 0 (ale to założenie byłoby troszkę bez sensu) - więc to najprostszy sposób i tak na szybko ;)
REKLAMA