Komunikacja UART miedzy procesorami

Proste przykłady do częstych pytań.
ODPOWIEDZ
Pikczu
Posty: 388
Rejestracja: 17 sie 2015, 13:46
Lokalizacja: Dublin, Ireland
Kontakt:

Komunikacja UART miedzy procesorami

Post autor: Pikczu » 04 gru 2017, 23:14

W związku iż kolega pimowo zadał mi pytanie na priv postanowiłem dodać (a raczej wkleić ) moje kiedyś tam wcześniej napisane wypociny na temat komunikacji poprzez UART przy użyciu ASCII

Piszemy rozwiązanie komunikacji przy użyciu ASCII
Standardowo ustawienia konfiguracyjne, zmienne i przerwania:
  1.     '$sim
  2.     'Debug On
  3.     Debug Off
  4.     $regfile = "m2560def.dat"
  5.     $crystal = 16000000
  6.     $hwstack = 40
  7.     $swstack = 16
  8.     $framesize = 32
  9.     $baud = 19200
  10.     $projecttime = 0
  11.     $version 0 , 0 , 0
  12.      
  13.     Config Submode = New
  14.      
  15.     Config Com1 = 19200 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
  16.     Config Com2 = 19200 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
  17.      
  18.      
  19.     Config Serialin0 = Buffered , Size = 100                    'buforowoanie  pierwszy uart
  20.     Config Serialin1 = Buffered , Size = 100                    'buforowoanie  drugi uart
  21.     Config Serialout0 = Buffered , Size = 100                   'buforowoanie  pierwszy uart
  22.     Config Serialout1 = Buffered , Size = 100                   'buforowoanie  drugi uart


Deklarujemy zmienne dla przykładu zmienne dla uart 0 i uart 1


  1.     Dim Ile_elementow As Byte                                   '
  2.     Dim Znak_ As Byte
  3.     Dim Uart_komenda As String * 20                             'musi byc wystarczjaco dlugie
  4.     Dim Getcommands(10) As String * 10                          'tablica na pociete komendy
  5.     '*******************************************************************************
  6.      
  7.     '**********************zmienne dla uart1****************************************
  8.     Dim Ile_elementow_1 As Byte                                 '
  9.     Dim Znak_1 As Byte
  10.     Dim Uart_komenda_1 As String * 20                           'musi byc wystarczjaco dlugie
  11.     Dim Getcommands_1(10) As String * 10                        'tablica na pociete komendy
  12.     '*******************************************************************************
Będziemy używać komendy split która rozbije przychodzące znaki po znaku spacji.

Standardowo zaczynamy od sprawdzania czy znak jest w buforze
przykład dla uart0:

  1.     If Ischarwaiting() > 0 Then                                'calls _gotchar and use URXC
  2.           Znak_ = Waitkey()                                     'pobierz znak z bufora
  3.           If Znak_ = 13 Or Len(uart_komenda) > 20 Then          ' jeslii ENTER lub wiecej niz 20 znaków to call uartrx
  4.              Call Uartrx                                        '
  5.              Print                                              '
  6.              Print Prompt;                                      'slowo zachety jako stala
  7.              Uart_komenda = ""
  8.           Else
  9.              Uart_komenda = Uart_komenda + Chr(znak_)           'kluczowe budowanie bufora
  10.              Print Chr(znak_) ;                                 'to jest echo zeby by³o widac co przychodzi
  11.           End If
  12.        End If
Sprawdzamy czy znak jest w buforze czyli If Ischarwaiting() > 0 Then pobieramy znak z bufora do zmiennej Znak_.
Teraz jeśli nasza zmienna Znak_ zawiera 13 ASCII czyli enter lub Len(uart_komenda) > 20 Then ilość odebranych znaków jest większa niż 20 to Call Uartrx
Ilość znaków musisz dobrać według swoich upodobań nie wiem jak długie będą twoje komendy.

Teraz przechodzimy do uartrx wspomniane na początku split będzie znajdować się właśnie w tym miejscu.
Tniemy nasze komendy żeby można było je rozróżnić
Ile_elementow = Split(uart_komenda , Getcommands(1) , " ")
Zmienna Ile_elementow zawiera jak sama nazwa mówi ilość pociętych elementów.
Zmienna uart_komenda to nasza źródłowy string do którego dodawaliśmy znaki podczas odbioru i pobierania z bufora Uart_komenda = Uart_komenda + Chr(znak_) 'kluczowe budowanie bufora
Zmienna Getcommands(1) to nasza tablica o rozmiarze 10 na 9 znaków, zapewne zauważyłeś po przecinku cudzysłów to właśnie znak spacji miedzy cudzysłowiem będzie naszym punktem w którym będzie następowało cięcie i umieszczanie kolejno w komórkach tablicy Getcommands(1).

Po uzyskaniu już pociętych komend reszta jest już z górki. musimy tylko zdecydować jak reagować na nasze komendy.
  1.     Uartrx:
  2.      
  3.        Ile_elementow = Split(uart_komenda , Getcommands(1) , " ")       'tniemy na komendy
Przejrzystym narzędziem do tego będzie select case, wiec piszemy:
  1.  
  2.     Select Case Getcommands(1)                               'miejsce w tablicy dla komendy pierwszej
  3.      
  4.           Case Komenda1
  5.            'cos do zrobienia  
  6.           Case Komenda2
  7.              'cos do zrobienia  
  8.           Case Komenda3
  9.             'cos do zrobienia  
  10.           Case Komenda4
  11.               'cos do zrobienia  
  12.      
  13.              Select Case Getcommands(2) ' druga komenda po spacji
  14.                 Case Komenda5
  15.                   'cos do zrobienia    
  16.                 Case Komenda6
  17.                    
  18.                    'cos do zrobienia  
  19.                 Case Else
  20.                     Print Prompt ; " " ; Uart_komenda ; " " ; Notincommands  ' nie rozpoznanan komenda  
  21.                    Getcommands(1) = "" 'czyszczenie bufora
  22.                    Getcommands(2) = ""'czyszczenie bufora
  23.                    Getcommands(3) = ""'czyszczenie bufora
  24.              End Select
  25.           Case Help
  26.             'cos do zrobienia  
  27.           Case Reboot
  28.              Print                                              'odstep na ekranie
  29.              Print " Wait rebooting "
  30.              Start Watchdog
  31.           Case Else                                             ' nie rozpoznanan komenda
  32.              Print Prompt ; " " ; Uart_komenda ; " " ; Notincommands
  33.              Print Prompt
  34.      
  35.              Getcommands(1) = ""                                'czysczenie bufora
  36.              Getcommands(2) = ""                                'czysczenie bufora
  37.              Getcommands(3) = ""                                'czysczenie bufora
  38.        End Select
  39.        Getcommands(1) = ""                                      'czysczenie bufora
  40.        Getcommands(2) = ""                                      'czysczenie bufora
  41.        Getcommands(3) = ""                                      'czysczenie bufora
  42.      
  43.     Return
  44.  
  45. GeSHi
W łatwy przejrzysty sposób możemy umieszczać komendy jedna pod druga, używanie stałych jeszcze ułatwi nam zadanie raz napisane select case będziemy mogli edytować w szybki sposób.
Wracamy na początek naszego programu i dodajemy stałe:
  1.     Const Change = "change"
  2.     Const Prompt = "wpisz jakies zwierze "
  3.     Const Komenda1 = "pies"
  4.     Const Komenda2 = "kot"
  5.     Const Komenda3 = "krowa"
  6.     Const Komenda4 = "kon"
  7.     Const Komenda5 = "paszcza"
  8.     Const Komenda6 = "kopyta"
  9.      
  10.     Const Help = "?"
  11.     Const Reboot = "reboot"
  12.     Const Notincommands = "Cos poszlo nie tak spróbuj jeszcze raz "
Dla lepszej zabawy wybieramy w opcjach bascoma emulowanie terminala vt100 i teraz możemy korzystać z własnych kolorów oknie terminala.
  1.  
  2.     '(
  3.     'Set Attribute Mode <ESC>[{attr1};...;{attrn}m
  4.     'Sets multiple display attribute settings. The following lists standard attributes:
  5.     '0 Reset all attributes
  6.     '1 Bright
  7.     '2 Dim
  8.     '4 Underscore
  9.     '5 Blink
  10.     '7 Reverse
  11.     '8 Hidden
  12.     'Foreground Colours
  13.     '30 Black
  14.     '31 Red
  15.     '32 Green
  16.     '33 Yellow
  17.     '34 Blue
  18.     '35 Magenta
  19.     '36 Cyan
  20.     '37 White
  21.     'Background Colours
  22.     '40 Black
  23.     '41 Red
  24.     '42 Green
  25.     '43 Yellow
  26.     '44 Blue
  27.     '45 Magenta
  28.     '46 Cyan
  29.     '47 White
  30.     Print Chr(27) ; "[1;31;47m";                                ' set atributte
  31.     PRINT "Your name ?>";                                       ' text
  32.     Print Chr(27) ; "[0m";                                      ' reset all
  33.     ')
  34.  
  35. GeSHi
Teraz cały kod:
  1.  
  2.     '$sim
  3.     Debug On
  4.     Debug Off
  5.     $regfile = "m2560def.dat"
  6.     $crystal = 16000000
  7.     $hwstack = 40
  8.     $swstack = 16
  9.     $framesize = 32
  10.     $baud = 19200
  11.     $projecttime = 65
  12.     $version 0 , 0 , 41
  13.      
  14.     Config Submode = New
  15.      
  16.     Config Com1 = 19200 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
  17.     Config Com2 = 19200 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
  18.      
  19.      
  20.     Config Serialin0 = Buffered , Size = 100                    'buforowoanie  pierwszy uart
  21.     Config Serialin1 = Buffered , Size = 100                    'buforowoanie  drugi uart
  22.     Config Serialout0 = Buffered , Size = 100                   'buforowoanie  pierwszy uart
  23.     Config Serialout1 = Buffered , Size = 100                   'buforowoanie  drugi uart
  24.      
  25.      
  26.     '**********************zmienne dla uart0****************************************
  27.     Dim Ile_elementow As Byte                                   '
  28.     Dim Znak_ As Byte
  29.     Dim Uart_komenda As String * 20                             'musi byc wystarczjaco dlugie
  30.     Dim Getcommands(10) As String * 10                          'tablica na pociete komendy
  31.     '*******************************************************************************
  32.      
  33.     '**********************zmienne dla uart1****************************************
  34.     Dim Ile_elementow_1 As Byte                                 '
  35.     Dim Znak_1 As Byte
  36.     Dim Uart_komenda_1 As String * 20                           'musi byc wystarczjaco dlugie
  37.     Dim Getcommands_1(10) As String * 10                        'tablica na pociete komendy
  38.     '*******************************************************************************
  39.     '(
  40.     'Set Attribute Mode <ESC>[{attr1};...;{attrn}m
  41.     'Sets multiple display attribute settings. The following lists standard attributes:
  42.     '0 Reset all attributes
  43.     '1 Bright
  44.     '2 Dim
  45.     '4 Underscore
  46.     '5 Blink
  47.     '7 Reverse
  48.     '8 Hidden
  49.     'Foreground Colours
  50.     '30 Black
  51.     '31 Red
  52.     '32 Green
  53.     '33 Yellow
  54.     '34 Blue
  55.     '35 Magenta
  56.     '36 Cyan
  57.     '37 White
  58.     'Background Colours
  59.     '40 Black
  60.     '41 Red
  61.     '42 Green
  62.     '43 Yellow
  63.     '44 Blue
  64.     '45 Magenta
  65.     '46 Cyan
  66.     '47 White
  67.     Print Chr(27) ; "[1;31;47m";                                ' set atributte
  68.     PRINT "Your name ?>";                                       ' text
  69.     Print Chr(27) ; "[0m";                                      ' reset all
  70.     ')
  71.      
  72.     '*******************************************************************************
  73.     '*******************************************************************************
  74.      
  75.      
  76.     Const On = 1
  77.     Const Off = 0
  78.     Const Change = "change"
  79.     Const Prompt = "wpisz jakies zwierze "
  80.     Const Komenda1 = "pies"
  81.     Const Komenda2 = "kot"
  82.     Const Komenda3 = "krowa"
  83.     Const Komenda4 = "kon"
  84.     Const Komenda5 = "paszcza"
  85.     Const Komenda6 = "kopyta"
  86.      
  87.     Const Help = "?"
  88.     Const Reboot = "reboot"
  89.     Const Notincommands = "Cos poszlo nie tak spróbuj jeszcze raz "
  90.      
  91.      
  92.      
  93.      
  94.     Declare Sub Uartrx()
  95.     Declare Sub Uartrx_1()
  96.      
  97.     Enable Interrupts
  98.     Config Watchdog = 4096
  99.     Enable Serial
  100.     Enable Serial1
  101.     Enable Serial2
  102.     Print Version(2)
  103.     Print Chr(27) ; "[1;31;47m";                                ' set atributte
  104.     Print "BY PIKCZU";                                          ' text
  105.     Print Chr(27) ; "[0m";                                      ' reset all
  106.     Print
  107.     Print Prompt
  108.     Print                                                       'nowa linia
  109.     Wait 1
  110.     '*******************************************************************************
  111.     Open "com2:" For Binary As #1
  112.      
  113.     Do
  114.     '*****************************Uart0*********************************************
  115.        If Ischarwaiting() > 0 Then                                'calls _gotchar and use URXC
  116.           Znak_ = Waitkey()                                     'pobierz znka z bufora
  117.           If Znak_ = 13 Or Len(uart_komenda) > 20 Then          ' jelsi ENTER lub wiecej niz 20 znaków to call uartrx
  118.              Call Uartrx                                        '
  119.              Print                                              'puste linia zeby ³adniej wyglada³o na ekranie                                             '
  120.              Print Prompt;                                      'slowo zachety jako stala
  121.              Uart_komenda = ""
  122.           Else
  123.              Uart_komenda = Uart_komenda + Chr(znak_)           'kluczowe budowanie bufora
  124.              Print Chr(znak_) ;                                 'to jest echo zeby by³o widac co przychodzi
  125.           End If
  126.        End If
  127.     '*****************************Uart1*********************************************
  128.        While Ischarwaiting(#1) > 0                              'calls _gotchar and use URXC
  129.           Znak_1 = Waitkey(#1)                                  'get char from buffer
  130.           If Znak_1 = 13 Or Len(uart_komenda_1) > 10 Then       ' check for ENTER of more then 4 characters
  131.              Call Uartrx_1                                      '
  132.              'Print                                              '
  133.              'Print Prompt;                                      'Using a constant will let us change the prompt
  134.              Uart_komenda_1 = ""
  135.           Else
  136.              Uart_komenda_1 = Uart_komenda_1 + Chr(znak_1)      'buffor building
  137.              'Print Chr(Znak_1);                                  'this is echo
  138.           End If
  139.        Wend
  140.     '*******************************************************************************
  141.     Loop
  142.      
  143.     Close #1
  144.     End
  145.      
  146.     Uartrx:
  147.      
  148.        Ile_elementow_1 = Split(uart_komenda , Getcommands(1) , " ")       'This choping coomand after space
  149.        Debug Chr(13)
  150.        Debug "lcount= " ; Lcount
  151.        Debug "uart_command= " ; Uart_komenda
  152.        Debug "Getcommands(1)= " ; Getcommands(1)
  153.        Debug "Getcommands(2)= " ; Getcommands(2)
  154.        Debug "Getcommands(3)= " ; Getcommands(3)
  155.      
  156.        Print                                                    'to dla wyœwietlania poprawnych odstepow
  157.        Select Case Getcommands(1)                               'miesce w tablicy dla komendy pierwszej
  158.      
  159.           Case Komenda1
  160.              Print                                                 ' "pies"
  161.              Print "hal hal hal"
  162.           Case Komenda2
  163.              Print                                                 '"kot"
  164.              Print "mial mial"
  165.           Case Komenda3
  166.              Print                                                 '"krowa"
  167.              Print "muuu"
  168.           Case Komenda4
  169.              Print                                                 '"kon"
  170.      
  171.              Select Case Getcommands(2)
  172.                 Case Komenda5
  173.                    Print                                           '"paszcza"
  174.                    Print "ihhhaaa"
  175.                 Case Komenda6
  176.                    Print                                        '"kopyta"
  177.                    Print "patataj pataj pataj"
  178.      
  179.                 Case Else
  180.                    Print "jestes pewien?" ; " " ; Uart_komenda ; "  " ; "Popelniles jakis blad sprobuj jeszcze raz"
  181.      
  182.                    Getcommands(1) = ""
  183.                    Getcommands(2) = ""
  184.                    Getcommands(3) = ""
  185.              End Select
  186.           Case Help
  187.              Print                                              '?
  188.              Print "pies"
  189.              Print "kot"
  190.              Print "krowa"
  191.              Print "kon"
  192.              Print "paszcza"
  193.              Print "kopyta"
  194.              Print "?"
  195.              Print "reboot"
  196.           Case Reboot
  197.              Print                                              'odstep na ekranie
  198.              Print " Wait rebooting "
  199.              Start Watchdog
  200.           Case Else                                             ' nie rozpoznanan komenda
  201.              Print Prompt ; " " ; Uart_komenda ; " " ; Notincommands
  202.              Print Prompt
  203.      
  204.              Getcommands(1) = ""                                'czysczenie bufora
  205.              Getcommands(2) = ""                                'czysczenie bufora
  206.              Getcommands(3) = ""                                'czysczenie bufora
  207.        End Select
  208.        Getcommands(1) = ""                                      'czysczenie bufora
  209.        Getcommands(2) = ""                                      'czysczenie bufora
  210.        Getcommands(3) = ""                                      'czysczenie bufora
  211.      
  212.     Return
  213.      
  214.      
  215.     Uartrx_1:
  216.        Ile_elementow_1 = Split(uart_komenda_1 , Getcommands_1(1) , " ")       'This choping coomand after space
  217.        Debug Chr(13)
  218.        Debug "lcount#1= " ; Lcount_1
  219.        Debug "Uart_komenda#1= " ; Uart_komenda_1
  220.        Debug "Getcommands#1(1)= " ; Getcommands_1(1)
  221.        Debug "Getcommands#1(2)= " ; Getcommands_1(2)
  222.        Debug "Getcommands#1(3)= " ; Getcommands_1(3)
  223.      
  224.        Print " ";                                               'to dla wyœwietlania poprawnych odstepow
  225.        Select Case Getcommands(1)                               'miesce w tablicy dla komendy pierwszej
  226.           Case Komenda1
  227.              Print                                                 ' "pies"
  228.              Print "hal hal hal"
  229.           Case Komenda2
  230.              Print                                                 '"kot"
  231.              Print "mial mial"
  232.           Case Komenda3
  233.              Print                                                 '"krowa"
  234.              Print "muuu"
  235.           Case Komenda4
  236.              Print                                                 '"kon"
  237.              Select Case Getcommands(2)
  238.                 Case Komenda5
  239.                    Print                                           '"paszcza"
  240.                    Print "ihhhaaa"
  241.                 Case Komenda6
  242.                    Print                                           '"kopyta"
  243.                    Print "patataj pataj pataj"
  244.                 Case Else
  245.                    Print "jestes pewien?" ; " " ; Uart_komenda ; "  " ; "Popelniles jakis blad sprobuj jescze raz"
  246.                    Getcommands(1) = ""
  247.                    Getcommands(2) = ""
  248.                    Getcommands(3) = ""
  249.              End Select
  250.           Case Help
  251.              Print                                                 '?
  252.              Print "pies"
  253.              Print "kot"
  254.              Print "krowa"
  255.              Print "kon"
  256.              Print "paszcza"
  257.              Print "kopyta"
  258.              Print "?"
  259.              Print "reboot"
  260.           Case Reboot
  261.              Print                                              'odstep na ekranie
  262.              Print " Wait rebooting "
  263.              Start Watchdog
  264.           Case Else                                             ' nie rozpoznanan komenda
  265.              Print Prompt ; " " ; Uart_komenda ; " " ; Notincommands
  266.              Print Prompt
  267.              Getcommands(1) = ""                                'czysczenie bufora
  268.              Getcommands(2) = ""                                'czysczenie bufora
  269.              Getcommands(3) = ""                                'czysczenie bufora
  270.        End Select
  271.        Getcommands(1) = ""                                      'czysczenie bufora
  272.        Getcommands(2) = ""                                      'czysczenie bufora
  273.        Getcommands(3) = ""                                      'czysczenie bufora
  274.     Return
  275.  
  276. GeSHi
To by było na tyle nie będe omawiał select case i zawartych komend zaprogramuj układ sparwdź sam jak to działa.
Obsługa drugiego uarta jest zrobiona podobnie ale nie identycznie porównaj sam.
dla testu wpisz w terminalu "kot" sprawdź tez co robi "kon paszcza"
Pozdrawiam
Pikczu
Ostatnio zmieniony 12 sty 2018, 21:46 przez Pikczu, łącznie zmieniany 1 raz.
Awatar użytkownika
pimowo
Posty: 392
Rejestracja: 28 maja 2016, 10:07

Re: Komunikacja UART miedzy procesorami

Post autor: pimowo » 05 gru 2017, 14:06

Bardzo dziękuję za tak obszerny opis-myślę, że nie tylko mi się przyda ;)
Przerobiłem Twoje zwierzaki na swoje potrzeby i teraz przeprowadzam (w końcu) burzliwe dyskusje ze swoim urządzeniem po UART :D

Założę nowy temat aby tu nie śmiecić i pokażę co mi wyszło, jeszcze końca nie widać ale projekt już nabiera rumieńców ;)
ODPOWIEDZ