Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[ATMEGA2560][BASCOM]Bufory wejściowe i wyjściowe UART-ów

07 Sty 2010 23:24 4502 27
  • Poziom 24  
    Witam

    Wie ktoś może (no może poza datasheet-em :D ,gdzie nie znalazłem lub przeoczyłem ) w jaki sposób czyścić "ręcznie" bufor wejściowy i wyjściowy danego uarta? Czy instrukcja :

    Code:
    _RS_BUFCOUNTR4=0


    załatwi sprawę? Czy można ręcznie czyścić każdy z buforów wejściowych i wyjściowych dla każdego uarta z osobna? Jak to z tym jest?
  • Pomocny post
    Poziom 42  
    a tak z ciekawości zapytam - po co ci czyszczenie buforów
  • Pomocny post
    Poziom 17  
    W starszych AVR'ach wystarczyło wyłączyć na moment nadajnik/odbiornik UART'u (rejestr UCSRB, lub UCSR0B, UCSR1B, itd.) i włączyć ponownie - może tu też zadziała.
  • Poziom 24  
    Motam się znowu okrutnie z uartami.

    Mam dwa urządzenia i chcę aby w każdym nadawanie i odbieranie chodziło w przerwaniach.

    Urządzenia A odpytuje cyklicznie co kilka sekund urządzenie B.

    Całe odpytywanie polega na tym że:

    Moduł A wysyła poleceniem:

    Code:
    Print #6 , "RED" ; chr(13) ; 


    zapytanie o treści "RED"

    i na to zapytanie urządzenie B ma odpowiedzieć stringiem o rozmiarze 156 znaków taki jak ten:


    Code:
    AT150T223T339T499UP44UW40UK40UB10SP10US1UL0UD1UO0R1088OP0C11C21C31C41C51P10P21P30P40P50P60P70P80KLU1KLD1KLL1KLR1KLM1KLE1R11R22R33R44R510R611R712R813R914QPM1


    Oczywiście wysyła to także poleceniem :
    Code:

    Print #6 , x ; chr(13) ;


    gdzie "x" to zmienna string z danymi jak wyżej.


    Czyli urządzenie B odpowiada zawsze w ten sam sposób czyli stringiem 156znaków. Zmieniają się w nim tylko wartości. Znany jest tylko początek czyli "AT1" i końcówka "PM1".

    Oczywiście urządzenie A wysyła także i inne polecenia ale zawsze 3 znakowe z chr(13) i średnikiem na koncu.

    Urządzenie A mam skonfigurowane tak:

    Code:

    Config Com1 = 19200 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
    Config Com2 = 19200 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
    Config Com3 = 19200 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
    Config Com4 = 19200 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0


    Config Serialin = Buffered , Size = 20 , Bytematch = All
    Config Serialin1 = Buffered , Size = 20 , Bytematch = All
    Config Serialin2 = Buffered , Size = 20 , Bytematch = All
    Config Serialin3 = Buffered , Size = 156 , Bytematch = All

    'Config Serialout3 = Buffered , Size = 30


    i otwieram com4 do transmisji tak:

    Code:

    Open "COM4:" For Binary As #6



    Przerwanie od tego uarta realizuję tak:

    Code:

    Serial3bytereceived:


    Urt4_2 = Inkey(#6)
    Urt4_1 = Urt4_1 + Chr(urt4_2)

    If Len(urt4_1) = 157 Then
    Rs4_odebrane = Urt4_1
    Urt4_1 = ""
    Rs4_flaga = 1
    End If

    Return


    Problem jest taki że to czasem nie działa. Jak w buforze pojawi się przypadkiem coś więcej niż te moje 156znaków to wszystko przestaje działać.

    Chciałbym aby jakaś flaga poinformowała mnie że czekają w jakiejś zmiennej (w moim przypadku w Urt4_1) gotowe dane o długości 156B.
    Albo aby przed każdym zapytaniem wysłanym z A do B wyczyścić bufor wejściowy aby mieć pewność że odbierze tylko to co powinno.

    Dodatkowo w urządzeniu B odbiór zrealizowany jest w pętli głównej (niestety jeszcze nie w przerwaniu) w taki sposób:

    Code:


    $regfile = "m32def.dat"
    $crystal = 8000000
    $baud = 19200                                               ' use baud rate



    Config Serialin = Buffered , Size = 3
    Config Serialout = Buffered , Size = 156                   
    Enable Interrupts


    Do

    'procedura odczytu rs232
    Bufor_flaga = Ischarwaiting() : If Bufor_flaga = 1 Then Gosub Odbierz_uart

    Loop



    Odbierz_uart:

             Bufor = ""
          Do
             Bufor_znak = Inkey()
             Bufor = Bufor + Chr(bufor_znak)
             Bufor_flaga = Ischarwaiting()
          Loop Until Bufor_znak = Chr(13) Or Bufor_flaga = 0
             Rsdata(1) = Bufor
    Return




    Nie wiem jak to zgrać do kupy aby działało. Niby to działa ale jakoś kulawo. No i brak mi pomysłu na obsługę tego w przerwaniu w urządzeniu B.
    Oddam 100pkt. za fachową pomoc. Może to nie dużo ale przy mojej ilości pkt. to :D

    Dodano po 3 [godziny] 48 [minuty]:

    Nie rozumiem dlaczego urządzenie A wiesza się jeśli nie stosuję bufora wyjściowego:

    Code:
    Config Serialout3 = Buffered , Size = 30 
  • Pomocny post
    Poziom 42  
    Bufor nadawczy nie jest zwykle tak potrzebny jak odbiorczy szczególnie jeśli korzystamy z prędkości większych niż 9600 i nie mamy zbyt dużo do nadawania.

    Jeśli jednak już się stosuje bufor wyjściowy to zapewne przyśpieszy i usprawni proces nadawania - bo często to co mamy do nadania wrzucone jest tylko procedurą PRINT do tegoż bufora , program leci sobie dalej a resztę za naszymi plecami tzw czarną robotę - załatwiają przerwania.

    Piszesz, że wiesza ci się urządzenie .... to bardzo dziwne. Bo spodziewać się tego można prędzej przy odbiorze i zastosowaniu polecenia INPUT. A skoro przy wysyłaniu - to znaczy, że gdzieś w całym programie jakiś "misz-masz" się robi
  • Poziom 24  
    Ale dziwne że jeśli pominę przerwania i config serialin to działa bezbłędnie (w sumie 99/100 bo jadę na zewnętrznym kwarcu 16Mhz i jakieś błędy są możliwe) ale nie tak jak chciałem bo musiałem wpiąć to w pętlę główną:

    To lata w pętli głównej:

    Code:
    'RS232 UART4 - ODCZYT DANYCH ZE STEROWNIKA KOMINKA
    
    Rs4_flaga = Ischarwaiting(#6) : If Rs4_flaga > 0 Then Gosub Odbierz_uart


    Jeśli flaga zmieni wartość to skok do Odbierz_uart czyli:

    Code:
    Odbierz_uart:
    


    Urt4_1 = ""
    Do
    Urt4_2 = Inkey(#6)
    Urt4_1 = Urt4_1 + Chr(urt4_2)
    Rs4_flaga = Ischarwaiting(#6)
    Loop Until Urt4_2 = Chr(13)
    Rs4_flaga = 0
    Rs4_odebrane = Urt4_1
    If Len(rs4_odebrane) = 157 Then Gosub Dekoder_uart4

    Return



    Jak dostosować to do serialin i przerwań? Próbowałem już chyba wszystkiego ale się coś sypie. W programie głównym nie ma żadnych innych miejsc które są odpowiedzialne za nadawanie lub odbieranie czegokolwiek. W tej chwili zostawiłem tylko te kawałeczki kodu co powyżej. Jak mówiłem odbierany string ma zawsze 157znaków. Więc teoretycznie powinno być to proste , ale dla mnie w tej chwili jakoś nie jest. Bo jeśli powyższy schemat będę musiał zastosować dla wszystkich czterech uartów to spowoduje to zamieszanie w pętli głównej ....
  • Pomocny post
    Poziom 42  
    Ciężko tak analizować program na wyrywki a jeszcze gorzej duży program gdzie na dodatek "coś się wiesza"

    ja tylko tak na gorąco dopytam czy założenia do całości nie pozwalały zrobić tej całej komunikacji pomiędzy kilkoma urządzeniami na RS485 ???

    Po drugie to kto wie jak ty w ogóle całą pętlę główną masz zorganizowaną. Może ci się bufor odbiorczy przepełnia? samą flagą dosyć "dziwnie" się bawisz a już sama ta pętla w "Odbierz_uart" ma prawo się zawiesić na śmierć jeśli nie nadleci nigdy ENTER. Jednym słowem bardzo to pokręcone jakby - no ale wiadomo tobie może się inaczej na to patrzy.
  • Poziom 24  
    W tym urządzeniu pętla główna jest praktycznie pusta. Obsługuje tylko wyświetlanie na LCD na którym na razie wyświetlam tylko to co odbiorę z Uart-a.

    Jeśli chodzi o tą pętlę Do Loop to wiem że to chore. Ale działa. Wiem że tak być nie może i muszę uruchomić "Config Serialin". Ale mam spore problemy. W tej chwili nic się nie wiesza i wszystko funkcjonuje prawidłowo jeśli korzystam z tej "lipnej" obsługi odbioru. Generalnie w programie nawet w tej chwili nie ma co się zawiesić bo dla celów testowych mam usunięte obsługę większości peryferiów.


    Co do RS485 to mam wszystko co trzeba na "pokładzie" tego mojego urządzenia A , i będzie się ono komunikowało jeszcze z 2-3 innymi modułami.
    Problem jest tego typu że komunikację z tym urządzeniem B muszę oprzeć na RS232 gdyż takie właśnie posiada mój poprzedni moduł z którym muszę się komunikować.

    Jeśli chodzi o przepełnienia bufora to nie może mieć to miejsca ponieważ dokładnie wiem kiedy nadlecą dane. I działa to tak:

    1.Urządzenie A wysyła
    Code:
    Print #6 , "RED" ; Chr(13); 

    2.Urządzenie B odpowiada
    Code:
     Print #1 , DANE ;chr(13) ; 


    gdzie DANE to:
    Code:
    AT150T223T339T499UP44UW40UK40UB10SP10US1UL0UD1UO0R1088OP0C11C21C31C41C51P10P21P30P40P50P60P70P80KLU1KLD1KLL1KLR1KLM1KLE1R11R22R33R44R510R611R712R813R914QPM1


    3.Po odebraniu danych następuje skok do podprogramu gdzie dekoduję odebrany ciąg za pomocą instrukcji
    Code:
    Mid(dane,x,x)
    i przepisuje otrzymane wartości do zmiennych.

    i to wszystko. Powtarzam to co jakieś 10-20 sekund i tak bez przerwy. I to na prawdę koniec obecnego programu.
    To powinno być proste , bo takie jest. Ale nie działa mi to poprawnie w przerwaniu jak to opisałem na początku tematu. Dlaczego ? Co prawda brak mi doświadczenia i robię to jak bym się zabierał za "jeża" , ale co zrobić :|
  • Pomocny post
    Specjalista automatyka domowa
    adambehnke napisał:
    Witam

    Wie ktoś może (no może poza datasheet-em :D ,gdzie nie znalazłem lub przeoczyłem ) w jaki sposób czyścić "ręcznie" bufor wejściowy i wyjściowy danego uarta? Czy instrukcja :

    Code:
    _RS_BUFCOUNTR4=0


    załatwi sprawę? Czy można ręcznie czyścić każdy z buforów wejściowych i wyjściowych dla każdego uarta z osobna? Jak to z tym jest?

    Na pytanie z pierwszego postu:

    np. Clear serialin

    p.s Polecam też zainteresować się nową wersją Bascom'a 1.11.9.8 ma kilka fajnych uaktualnień.
  • Poziom 35  
    Zastanawiam się ile jeszcze założysz tematów w kształcie [atmega2560][BASCOM]..... Zanim siądzeisz do książek i nauczysz się pisać programy w asemblerze lub C . Piszesz komercyjne aplikacje w bascomie bierzesz za to kasę. Cała sytuacja jest o tyle nie smaczna ,że zarabiasz kasę jadąc na wiedzy użytkowników tego forum.
  • Poziom 24  
    kamyczek napisał:
    Zastanawiam się ile jeszcze założysz tematów w kształcie [atmega2560][BASCOM]..... Zanim siądzeisz do książek i nauczysz się pisać programy w asemblerze lub C . Piszesz komercyjne aplikacje w bascomie bierzesz za to kasę. Cała sytuacja jest o tyle nie smaczna ,że zarabiasz kasę jadąc na wiedzy użytkowników tego forum.


    O panie kolego teraz to wypaliłeś!

    Nie skomentuję bo to śmieszne.

    Albo nie , właśnie odpiszę , i to w punktach aby było jaśniej , gdyż już drugi raz próbujesz mnie obrazić i zmieszać z błotem:

    1.Co do mojego pisania w Bascomie to może i rzeczywiście jest to albo przykładem mojej głupoty albo brakiem czasu lub umiejętności w nauczeniu się C lub asemblera.A tak naprawdę powodem jest fakt że dawno temu pisałem aplikacje w Visual Basic (były to naprawdę poważne jak na tamte czasu wyczyny). Pewnego razu trafiłem na pewien przykład z Atmegą8 i programem napisanym w dość znajomy mi sposób. Po przestudiowaniu doszedłem do wniosku że znam to i jest to coś ala Basic. Okazało się Bascomem i spodobało mi się to do tego stopnia że zakupiłem tonę części i rozpoczęły się testy i próby. Raz udane a raz nieudolne. W końcu mogłem przerobić kilka starych sterowników ( sterowały ciśnieniem i dozowaniem utwardzacza do żywic w automatach wtryskowych) na nowe-mniejsze i 100000000razy prostsze. A jeśli chodzi o porównanie Bascoma i innych języków w prostych urządzeniach to powiem tak : Człowieku co za różnica w jakim języku stworzyłem Hexa którego wgrałem do procka. Ważne że urządzenie robi to co ma robić. Owszem dla jakichś szczególnych urządzeń wymagających szybkości działania to mogę przyznać rację że Bascom nie za bardzo się nadaje.Dla mnie liczy się to że udaje mi się jak na razie zrealizować w mniejszym lub większym stopniu to co planuję.
    2.Nigdy nie napisałem że nie mam zamiaru się nauczyć jakiegokolwiek innego języka niż Bascom.
    3.Pojęcia nie masz kim jestem , ile mam lat oraz czym się zajmuję prywatnie i zadowowo ale masz dziś szczęśliwy dzień i Ciebie oświecę:
    Otóż nie jestem dzieciakiem z rocznika 80-90 i nie miałem możliwości doświadczenia super wykształcenia w kierunkach programistycznych. Jestem z zawodu elektronikiem po GZE UNIMOR. Może nie mam się czym szczycić ale sporo się tam nauczyłem. Ja w odróżnieniu od wielu z tu piszących musiałem zdrowo się nagłowić aby stworzyć jakiś bardziej zaawansowany moduł nie używając mikroklocków. W tej chwili to jest jak z LEGO - wszystko jest możliwe i to w mini wymiarach. Dzisiejsze urządzenia jakie tu na forum widzę to w 90% wspomagane mikrokontrolerami i ich firmware-ami "komputerowe" aplikacje. Teraz wszystko można zrealizować w jednym scalaku. A cała elektroniczna wiedza jaką trzeba posiadać to znajomość jak to już pisałeś C i asemblera oraz kilku podstawowych podzespołow jak rezystor i podstawka pod scalak.
    4.To że z zawodu jestem elektronikiem to nie oznacza że pracuję w tym zawodzie.
    Wiele lat przesiedziałem w Norwegii w firmie produkującej wielkie jachty motorowe. Teraz mam przyjemność posiadać samemu taką firmę.Może jest jeszcze niewielka ale jakoś to idzie. Siedzę w pracy do późnych godzin , i raptem czasami w ciągu dnia uda mi się usiąść przy komputerze i coś pogrzebać.
    Mikrokontrolerami zajęłem się przypadku. I ku mojemu zaskoczeniu trafiłem na program napisany na Atmega8 to w basicu. Co po zagłębieniu okazało się Bascomem.
    5.Nigdy nie napisałem że piszę komercyjne aplikacje i biorę za to pieniądze.
    Owszem napisałem z ładnych pare lat tamu aplikację która obsługiwała wymianę danych w jednym z marketów (dawny-GEANT). Było to dla mnie wielkie osiągnięcie i znaczny dochód. To że piszę teraz w Bascomie i robię jak na mnie w tej chwili wielkie urządzenie nie oznacza że jest ono na sprzedaż .Akurat jestem w tej chwili na etapie budowy swojego domu i niemu poświęcam większość wolnego czasu i mam głowę pełną pomysłów na elektronikę jaka w nim się znajdzie. I to co robię trafi właśnie do mojego domu i firmy.
    6.Jeśli chodzi o korzystaniu lub jak to napisałeś na "jechaniu" na wiedzy użytkowników tego forum to przyznaję że bardzo wiele niektórzy z nich mi pomogli i bardzo cenię sobie ich wiedzę i pomoc. Nauczyłem się dzięki nim wiele i zapewne wiele się jeszcze nauczę. I jeśli zechcę założyć nowy temat i admin mi tego nie uniemożliwi to będę pytał bo kto pyta nie błądzi.Nigdy nie pisałem że chcę jakichś gotowców .Sam wyrywam sobie włosy z głowy i rozgryzam co źle robię i jeśli pytam o cośto w ostateczności.
    7.Najlepsze z tego jest to że nie napisałem w temacie " Panie Kamyczek...... jest Pan jedynym obdarzonym wszech-wiedzą forumowiczem i błagam Pana o pomoc.
    Człowieku nie chcesz to nie pisz.I Ty się nie będziesz "niesmaczył" i ja nie będę musiał głupot czytać. A jak nie chcesz pomagać za darmo to napisz , a zapłacę ci. Ale wydawało mi się że to chyba forum a nie dział płatnych ogłoszeń.

    Jeśli admin uzna mój post za obraźliwy lub niezgodny z regulaminem to mówię : Adminie czyń swoją powinność. Przepraszam również wszystkich tych którzy mi pomagali a których może w jakiś mi nieznany sposób obraziłem.


    Co do pytania pana "XURY" to dodaję że problemy mam z tym że jeśli umieszczę moje wypociny w przerwaniach to podczas wysyłania danych z modułu A instrukcją Print to układ lubi mi się zawiesić , lub mam problemy z odebraniem kompletnych danych. W tem przykładzie jaki podałem ostatnio wszystko chodzi idealnie poza tym że mam zaśmieconą i opóźnioną przez to pętlę główną.
  • Poziom 42  
    adambehnke napisał:
    .... dodaję że problemy mam z tym że jeśli umieszczę moje wypociny w przerwaniach to podczas wysyłania danych z modułu A instrukcją Print to układ lubi mi się zawiesić , lub mam problemy z odebraniem kompletnych danych. W tem przykładzie jaki podałem ostatnio wszystko chodzi idealnie poza tym że mam zaśmieconą i opóźnioną przez to pętlę główną.


    Posłuchaj - ja a może i ktoś inny także zapewne chętnie by pomógł w twoich problemach, ale jeśli trzeba analizować jakiś większy że tak powiem kod, który jest niby przykładowy ale jednocześnie obsługujesz aż kilka UARTów a do tego jak widać na razie jeszcze niewiele wiesz o programowaniu z udziałem przerwań niestety, a nie mówię tego żeby broń boże ci dogryźć, bo widać, że się uczysz dopiero tego wszystkiego) ...... to zrozum, że będzie zawsze z tym problem na jakimkolwiek forum. Nie dlatego, że takie są zasady - tylko ciężko jakby wytłumaczyć czy pomóc komuś zrobić dosyć skomplikowaną rzecz w Bascomie, nie mając pod ręką podobnego układu żeby to testować a co gorsze widząc, że jakby od podstaw brniesz troszkę nie tą drogą co trzeba. Dlatego tylko napisałem ci na PW o pewnym rozwiązaniu. Bo czasem warto od podstaw się zająć poznaniem pewnych mechanizmów, żeby potem wykorzystywać je w taki ciut bardziej skomplikowany sposób.

    hmmm jedyne co mogę na tym etapie ja podpowiedzieć to:

    1. totalnie źle podchodzisz do pisania obsługi przerwania UART a szczególnie że w ogóle zabierasz się za to w Bascomie skoro on ma już dosyć dobrą obsługę przerwań.

    2. nie zdajesz sobie troszkę sprawy na razie (ale to też rozumiem bo nie wszystko od razu) jak wygląda hmm że tak powiem prolog i epilog przerwania w Bascomie

    3. nie wiesz na razie co to są bufory cykliczne (taki podstawowy znany od dawien dawna, sposób - obsługi UARTA w przerwaniach. No i oczywiście robiąc obsługę tej transmisji w większości przypadków ta wiedza jest nie istotna jakby bo Bascom robi wiele za ciebie - no ale ty znowu sięgasz do pisania własnej obsługi takiego przerwania i to jak mówię o zgrozo w Bascomie. Żebyś ją sobie w czystym asemblerze napisał (bo w innym języku nie można zrobić wstawki do Bascoma) to jeszcze bym rozumiał

    Ale przecież już kiedyś podpowiadałem ci o mechaniźmie Bytematch, którego niestety jak na mój gust całkiem opatrznie także używasz i stąd twoje pomysły zapewne nad chęcią okiełznania przerwania od UART'a

    No toż nawet jak ktoś by się zaparł żeby wręcz poświęcić czas i gotowca dla ciebie napisać to też nie dałoby rady bez podania dokładnych założeń.

    Dlatego zrozum mnie przynajmniej proszę, że ja tak nie umiem pomóc - bo chcesz zrobić coś dużego ale jakby trochę po macoszemu traktując podstawy i stąd te problemy - a niestety trudno zrobić tu wykład od początku po kolei

    1. o co chodzi z przerwaniami jeśli chodzi o techniki dobrego programowania
    2. jak wyglądają możliwości pisania wstawek asemblerowych do Bascoma - a są one możliwe i dzięki nim na prawdę dużo można z poczciwego Bascoma wycisnąć
    3. na czym w ogóle polega taka typowa standardowa obsługa przerwań UART z użyciem buforów cyklicznych - bo to Bascom robi że tak powiem "pod spodem" i ty nie widzisz sczegółów..... ale gdyby znać dokładnie te zasady to zapewniam cię że inaczej podchodziłbyś już do samego korzystania z obsługi UART w Bascomie a szczególnie przy kilku UART'ach - gdzie już trzeba się nagimnastykować

    dlatego gdy zadajesz pytanie "... czy już nikt nie potrafi podpowiedzieć o co tu chodzi w moim programie?..." - to nie dziw się, że nie ma odpowiedzi za bardzo. Bo to jest tak troszkę jakbym ja np wziął się za budowę jachtu a nigdy z tym nie miałem do czynienia w zyciu - a zacząłbym naukę od razu od budowy dużej jednostki morskiej i zrozpaczony dopytywał się na jakimś forum dlaczego mi nie wychodzi. Pewnie w takim przypadku ty także nie udzieliłbyś mi odpowiedzi ale nie dlatego że nie chcesz - tylko dlatego, że uznałbyś iż powinienem zacząć naukę od budowy najpierw małej łódeczki czy kajaka żeby poznać podstawy. Bo w kilku zdaniach na forum nie będziesz mi w stanie przekazać całej i skomplikowanej wiedzy podstawowej - prawda? sam przyznaj.

    Może i się mylę w tym co piszę i źle oceniam twoją dotychczasową wiedzę bo coś tam już zrobiłeś i ci działa - ale tak to bywa w programowaniu - proste rzeczy dosyć prosto da się zaprogramować a te bardziej skomplikowane już nie - warto byłoby mieć już doświadczenie..... a taka jest też prawda, że nauka programowania tylko w Bascomie - strasznie wydłuża ten czas poznawania podstaw, które działają jak pisałem "pod spodem" i nawet nie wiesz jak w szczegółach. Dlatego tylko uważam, że ja - taką osobę jak ty, która jest także pasjonatem tej elektroniki i tak uparcie dąży do celu - na pewno bym zainteresował pokazując możliwości jakie się otwierają pisząc programy w innych językach

    ------------------------

    ok na zakończenie - bo teraz spojrzałem dopiero dokładnie co robi twoja procedura obsługi przerwania od UART'a. Napisałem że to masakra bo


    Code:
    Serial3bytereceived: 
    


    Urt4_2 = Inkey(#6)
    Urt4_1 = Urt4_1 + Chr(urt4_2)

    If Len(urt4_1) = 157 Then
    Rs4_odebrane = Urt4_1
    Urt4_1 = ""
    Rs4_flaga = 1
    End If

    Return


    jak ty sobie wyobrażasz? z jednej strony włączasz w ogóle przerwania sprzętowe dla UARTa automatycznie za pomocą Config Serialin (chyba że nie wiesz właśnie o tym, że to polecenie je włącza) a jednocześnie jakby je wywłaszczasz - podstawiając swoją niestety hmmm dziwną procedurę jak wyżej - i oczekujesz że to będzie ci dobrze działać??? ..... to że czasem działa dobrze a czasem źle - nie świadczy że idziesz w dobrym kierunku - bo już samo to , że prawdopodobnie nie panujesz świadomie nad stosem - może powodować takie dziwne zachowania. A błędy w pracy stosu bywają na prawdę niedorzeczne i najgorsze do wyłapania - jeśli nie ma się praktyki dłuższej

    eeeeeh - sam widzisz - no chciałbym coś tam napisać i podpowiedzieć ale co? naklepałem w tą klawiaturę, naklepałem i podejrzewam, że i tak niezbyt jasno i precyzyjnie cokolwiek tak pisząc - wytłumaczyłem. Inaczej jest na żywo ;)

    ok pozdrówka i powodzenia
  • Poziom 24  
    Oczywiście w 100% się z tym wszystkim zgadzam.Piszę w tym temacie ostatni raz zanim mnie znienawidzicie. Ale studiowałem polecenie serialin w Helpie i na przykładzie tam podanym mogę że tak powiem odebrać znak wysłany np. z terminala na któryś uart.
    To że mam w procku kilka uartów to prawda. Ale jak uruchomię obsługę na jednym to z resztą sobie poradzę. I nie trzeba tu analizować całego programu.

    Załóżmy że mam tylko jeden aktywny uart w A2560.

    skonfigurowany tak:
    Code:
    Config Com4 = 19200 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
    

    Config Serialin3 = Buffered , Size = 156 , Bytematch = All  ' i tu wiem że włącza to przerwanie od tego uarta.


    I wysyłam z poziomu PC (mam napisane swoją mini aplikację do wysyłania tekstu czy czego tam chcę na dowolny com) takie coś :
    Code:
     ABCDEFGHIJKL 
    i na końcu dodane chr(13) i ";"

    to po zgłoszeniu przerwania wykonuje skok do:

    Code:

    Serial3bytereceived:


    Return


    I jak z tego przerwania podstawić do zmiennej "ODEBRANE" przesłane dane aby otrzymać ODEBRANE=ABCDEFGHIJKL .

    Wg. tej mojej procedurki widzicie jak ja to robiłem.Dodawałem znak do znaku itd.
    Ale jak mam to zrobić korzystając z "Serial3bytereceived" , używać INKEY() ?? To chyba nie o to chodzi.
    Jak mówię piszę ostatni raz w tej sprawie i przy braku odzewu zamknę temat.
  • Pomocny post
    Poziom 42  
    Powiedz mi dlaczego - skoro korzystasz z Bytematch to dajesz parametr ALL ??? a przecież piszesz że odbierasz swoją "ramkę danych" zakończoną znakiem chr(13)...

    I znowu mógłbym się rozpisać za długo jak warto podchodzić do transmisji danych przez RS232, że warto wykorzystać własnie znaki końca linii do wyłapywania zdarzeń, że warto wtedy ustawiać flagę a potem dopiero w oparciu o nią działać dalej, że warto procedurę tego ustawiania flagi zrobić w asemblerze, bo masz napisane nawet w helpie Bascoma że:

    Cytat:
    "While bytematch allows you to trap the incoming bytes, take care that you do not delay the program execution too much. After all the serial input interrupt is used in order not to miss incoming data. When you add delays or code that will delay execution too much you might loose incoming data."


    Później warto skorzystać gdzieś w pętli głównej sprawdzanie czy bufor jest pusty i ew wtedy dopiero pobierać gotowe ramki. No ale też jak widzisz to rysuje się od razu zmiana całej koncepcji pisania programu i sporo do omówienia a tymczasem ty oczekujesz porady - jak coś tam zmienić w tym co napisałeś do tej pory, żeby było dobrze. To jest taka trochę analogiczna sytuacja patrząc tak ogólnie na twój problem jak np w tym temacie:

    https://www.elektroda.pl/rtvforum/topic1536810.html


    poza tym
    adambehnke napisał:

    To że mam w procku kilka uartów to prawda. Ale jak uruchomię obsługę na jednym to z resztą sobie poradzę. I nie trzeba tu analizować całego programu.

    ja myślę, że to nie jest w tym przypadku taka prosta zależność w związku z tym wszystkim co wyżej napisałem. A szczególnie dlatego zwróć uwagę w moim powyższym tekście na cytat z helpa bascoma i sugestię korzystania z flagi ale przy użyciu kilku rozkazów asemblera zamiast bascoma nawet.
  • Pomocny post
    Poziom 35  
    Problem leży w tym ,że to co usiłuje zbudować kolega wymaga sporej wiedzy na temat rozwiązań tego typu zagadnień. Jeśli urządzenie to ma pracować w domu stanowiąc automatykę RS232 nie nadaje sie do tego typu transmisji ze względu na długość przewodów i odporność na zakłócenia . Do tego jest RS485 i CAN. Co do nauki programowania to mało kto napisze że nauczył się go w szkole ,bo nie ma uczelni na której liczba zajęć w tym kierunku jest wystarczająca do poznania zagadnienia w stopniu podstawowym. Jedyna możliwość to zakupienie kilku czy kilkunastu książek czytanie , analizowanie przykładów i pisanie swojego kodu. Do bascoma też są dwie książki z wydawnictwa BTC w których można sie troszkę dowiedzieć , do tego jest help w bascomie ,który przedstawia przykłady opatrzone stosownym komentarzem. Co do mojego wieku to nie jestem z rocznika 80-90, nie nauczyłem się programowania w szkole , i na uczelni tylko swoją pracą siedzeniem po nocach , czytaniem książek i pisaniem programów. Zwróciłem koledze uwagę na fakt , którego nie chce kolega przyjąć do wiadomości . Do pisania takich programów ma kolega zbyt małą wiedzę i trzeba ją uzupełnić . Problem w tym że poznanie pewnych mechanizmów wymaga poznania mikrokontrolerów od podstaw i asemblera. Do póki kolega tego nie zrobi sytuacja będzie się powtarzała . Problemy będą rosły a osób mogących rozwiązać problem będzie mniej.
  • Poziom 24  
    Oczywiście trudno mi się z tym wszystkim nie zgodzić. I przepraszam że na Ciebie naskoczyłem ale nie rozumiem "durnej" rzeczy jak bufor. Ja to rozumiem jako jakąś zmienną w której przechowywane jest to co odbierze Uart. Pewnie znowu błędnie.
    Nie mam już siły do wałkowania tego tematu i pozostaje w moim programie z tym co działa. Może to lipne ale jakoś działa. Cała transmisja danych w domu będzie oparta o RS485 ale z jednym modułem muszę się porozumieć przez RS232. I odległość to około 1,2m (po prostu przez ścianę).

    Jestem toporny (wiem), czyli jeżeli korzystam z Bytematch to powinienem ustawić w module (A) parametr Bytematch = 13 , tak? I podczas kiedy wyślę coś z mojego drugiego modułu (B) to moduł (A) będzie odbierał dane i dodawał je do bufora do czasu napotkania znaku chr(13) , dobrze zrozumiałem? I kiedy go odbierze to wygeneruje przerwanie i tym samym będę wiedział że nastąpił koniec odbioru moich danych bo odebrano ostatni znak (13). Potem tylko sprawdzam dane czy to te które mnie interesują i gotowe? Ale ja jestem "toporny" i nie wiem tylko tego jak przepisać dane z bufora do mojej zmiennej. "DANE" to moja zmienna a bufor(w którym siedzą dane) to? Gdzie Dane=bufor , ale co to za ten bufor jak to zapisać .
    Jak napisałem znowu coś bez sensu to nie odpisujcie :D
  • Pomocny post
    Specjalista automatyka domowa
    No dobra to tak trochę "po chłopsku" to opiszę:
    Jeśli ustawisz Bytematch = 13 to znaczy to tyle, że program przejdzie od podprogramu w którym może być tylko jedna linijka np. jak ja to zrobiłem w moim programie wysylania sms:
    Code:
    Serial0charmatch:
    
     Input Todczyt Noecho
    Return

    Oczywiście trzeba ustawić Input na działanie tylko na znak enter (13). Proste prawda ? Wiekie dzięki tu należą się koledze mirkowi.

    Drugi sposób który ja używam to:
    Code:
    Serial0charmatch:
    
    Enter = 1                     'flaga odebrania CR - do wykorzystanie w pętli gł.
    If Ignoracja = 0 Then     'sprawdzenie flagi ignorowania odczytu
     Input Todczyt Noecho 
    End If
    Return

    Jeśli nie chcę czegoś odbierać to ustawiam flagę Ignoracja na 1 w pętli głównej, a potem odbieram tam sam lub czyszczę bufor.
  • Poziom 24  
    I o to mi właśnie chodziło . Zaraz idę do kościoła odmówić zdrowaśkę w podziękowaniu :D.

    o proszę czy to był może problem wieszania się programu?
    Cytat:
    eśli ustawisz Bytematch = 13 to znaczy to tyle, że program przejdzie od podprogramu w którym może być tylko jedna linijka

    bo ja miałem w tym podprogramie prawdziwą odę do młodości naklepane.

    I jeszcze jedno , jeśli trafi się znak końca w moim przypadku jest nim chr(13) to znaczy że odebrano to co wysłano w urządzenia B , tak? I jeśli pobiorę to tak:

    Code:

    Serial0charmatch:
    Input Dane Noecho
    return
     


    to w zmiennej Dane będę miał to co wysłałem z urządzenia B , tak to rozumiem.
    Ale znając polecenie Input ,to czy czasem nie zawiśnie na tym poleceniu i nie będzie czekał w nieskończoność? Ale z tego co przekopałem w helpie to powinienem mieć w zmiennej Dane to co wysłałem z urządzenia B. Czyli w końcu to co chcę osiągnąć.
    I po pobraniu danych poleceniem Input bufor jest automatycznie czyszczony , czyż tak?

    Ale nudzę prawda? Tu macie coś na zmianę klimatu Link
  • Pomocny post
    Specjalista automatyka domowa
    Input nie zawiśnie jeśli ustawisz poprawnie "Config Input = Cr", bo standardowo Input "czeka" na CRLF.
    A odczytać musi, bo przejście do podprogramu nastąpi tylko w przypadku nadejścia znaku entera (13). Więc z góry wiadomo, że Input je odbierze. Bufor jest czyszczony przez ten Input właśnie.

    Sorry pomyłka - standardowo Input czeka tylko na CR więc jeśli nie wysyłasz CRLF nie musisz ustawiać Config Input
    Jeśli jednak masz mozliwość zmiany odbieranych danych na akończenie ich przez CRLF
    np. nie dając średnika na końcu polecenia Print to polecam tą metodę. Jest to dobre w przypadku spodziewania sie znaku entera (13) w środku odbieranego łańcucha danych. "Przypadkowe" pojawienie się CRLF (13 10) jest mniejsze niż samego CR.
  • Poziom 42  
    Input rzeczywiście nie zawiśnie nigdy w takiej sytuacji ponieważ wołanie takiego przerwania odbywa się po wystąpieniu chr(13) w buforze sprzętowym UART'a - tak więc zawsze będzie miał co odczytać z tego bufora - zakładając oczywiście jego poprawną konfigurację o czym pisał kolega wyżej.

    Ja jednak oczywiście z uporem będę twierdził nadal, że nie opłaca się w tym momencie (czyli w przerwaniu odczytywać dane z bufora za pomocą INPUT bo to może niestety w skrajnych przypadkach zakłócić nie tylko dalszą transmisję przy jednym kanale RS232 a o czterech już nie wspomnę plus innych rzeczy)

    W takim wytaku warto tylko ustawić flagę i na jej podstawie ładnie takiego Inputa robić gdzieś w pętli głównej.

    adambehnke --> przy okazji - to będę musiał "oskarżyć" cię za to co napisałeś wyżej, tzn za link który podałeś wyżej do zmiany klimatu ..... no - normalnie o mało co mi się krzesło nie połamało i bym się przewróciła może nawet okaleczył - ze śmiechu czytając ten tekst.... ;) ..... no masakra - uśmiałem się też do łez... A na poważnie to jak masz jeszcze jakiś taki link - to dawaj ;)
  • Poziom 24  
    A więc tak :

    Konfiguracja( mam 4 uarty i pokażę to na czwartym):



    Code:
    Config Com4 = 19200 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0  
    

    Config Serialin3 = Buffered , Size = 200 , Bytematch = 13        'Enter=13
    Config Serialout3 = Buffered , Size = 50
    Config Input = Cr , Echo = OFF                  'CR= 13

    Open "COM4:" For Binary As #6
     




    Podprogram przerwania od uart-a 4:

    Code:
    Serial3charmatch:
    
    Rs4_flaga = 1                 'flaga informuje mnie że odebrano dane i mogę je dalej "obrabiać"
    Input #6 , Rs4_odebrane Noecho
    Return




    A teraz sprawdzę jak to chodzi przy wykorzystaniu flagi i odbioru w pętli głównej.



    I pomyśleć że wystarczy kilka linijek i wszystko chodzi . I to jak na razie bezbłędnie. :D Musiałem dołożyć bufor wyjściowy gdyż w momencie kiedy akurat wysyłałem dane z A do B i moduł B akurat mi coś nadawał to program wariował lub się wieszał. Ale teraz jak na razie jest ok.
    Jeśli Widzicie jeszcze coś niedobrego w tej procedurce to czekam na uwagi.

    Dodano po 12 [minuty]:

    Odbiór w pętli głównej także działa bez zarzutu , więc zrobię tak jak radzi Mirek i w przerwaniu ustawię tylko flagę a odczytam bufor w pętli głównej.
  • Specjalista automatyka domowa
    Tak lepiej jest odczytywać z bufora w pętli głównej. Może się jednak zdarzyć w niektórych przypadkach (takim jaki był mój), że odbieranie danych było ok tylko że nie tych co akurat powinny być. Sytuacja ma ta miejsce kiedy kilkakrotnie w pętli głównej odpytujemy jakieś urządzenie i za każdym razem oczekujemy innej odpowiedzi (w moim przypadku różne komendy AT). Zanim nadejdzie odpowiedź pętla główna może "przelecieć" kilkaset razy i odebrane dane mogą pojawić się nie w tym miejscu co powinny tzn. nie w tym "Input" co ja bym chciał. Jeśli jednak Ty zawsze oczekujesz na dane tego samego typu wszystko powinno byc ok. Możesz podpatrzeć jak ja to rozwiązałem w moim temacie o module gsm ze sterowaniem sms jeśli byś miał tego typu problemy. A jeśli nie masz takiej potrzeby, to zignoruj to co napisałem.

    btw. Historia o akcji z kotem - rewelacja :)
  • Poziom 42  
    xury napisał:
    Tak lepiej jest odczytywać z bufora w pętli głównej. Może się jednak zdarzyć w niektórych przypadkach (takim jaki był mój), że odbieranie danych było ok tylko że nie tych co akurat powinny być. Sytuacja ma ta miejsce kiedy kilkakrotnie w pętli głównej odpytujemy jakieś urządzenie i za każdym razem oczekujemy innej odpowiedzi (w moim przypadku różne komendy AT). Zanim nadejdzie odpowiedź pętla główna może "przelecieć" kilkaset razy i odebrane dane mogą pojawić się nie w tym miejscu co powinny tzn. nie w tym "Input" co ja bym chciał.


    no ale tu właśnie kłania się stworzenie odpowiedniej konstrukcji pętli głównej. Poza tym nawet jeśli kilkakrotnie wysyłasz do urządzenia polecenie AT i nadejdzie ci nagle do bufora sprzętowego UART kilka odpowiedzi - to ponieważ jest to bufor - zapiszą się one w tymże buforze ładnie po kolei. Tak więc w pętli głównej także dokładnie po kolei można je odczytać i nie ma mowy o żadnej pomyłce o ile ...............

    ....... o ile właśnie odpowiednio się podejdzie. Tak się składa, że właśnie niedawno miałem okazję pobawić się obsługą modemu GSM. Napisałem procdury do odbierania i wysyłania SMSów - przy czym co ISTOTNE dekodowanie oraz kodowanie PDU następuje "w locie" dzięki czemu program prawie nie zużywa pamięci RAM na te operacje. Ale piszę to nie dlatego żeby się pochwalić tylko żeby powiedzieć, że pomimo iż program pisałem w C - to zastosowałem jeśli chodzi o obsługę UART'a dokładnie taką samą technikę jak w Bascomie z Bytematch ;) ... i dokładnie występują takie sytuacje o jakich piszesz xury - że czasem trzeba wysłać kilka poleceń i teoretycznie mogłoby się pomieszać z odpowiedziami. A tymczasem - jak mówię - wszystko jest ładnie realizowane w pętli głównej. Nooo .... oczywiście to już wymagało wprowadzenia mechanizmów do obsługi tzw "zdarzeń" oraz co istotne tzw "programowych timerów" . Brzmi to może groźnie - ale wbrew pozorom jest to pikuś - choć oczywiście ciężko go omówić w 2 zdaniach.
  • Poziom 24  
    xury napisał:
    Może się jednak zdarzyć w niektórych przypadkach (takim jaki był mój), że odbieranie danych było ok tylko że nie tych co akurat powinny być. Sytuacja ma ta miejsce kiedy kilkakrotnie w pętli głównej odpytujemy jakieś urządzenie i za każdym razem oczekujemy innej odpowiedzi (w moim przypadku różne komendy AT). Zanim nadejdzie odpowiedź pętla główna może "przelecieć" kilkaset razy i odebrane dane mogą pojawić się nie w tym miejscu co powinny tzn. nie w tym "Input" co ja bym chciał


    Między innymi dlatego ja odpytuję moje urządzenie o wszystkie możliwe parametry na raz . Wysyłam "RED" (akurat jakoś mi ten wyraz przypasował) i dostaję w odpowiedzi prawie 40 różnych parametrów połączonych w jeden string :) .Potem to "dekoduję" i po kłopocie. Muszę jeszcze tylko w moim starym urządzeniu zrobić to co w nowym i poprawić obsługę Uart.
  • Poziom 10  
    kamyczek napisał:
    Problem leży w tym ,że to co usiłuje zbudować kolega wymaga sporej wiedzy na temat rozwiązań tego typu zagadnień. Jeśli urządzenie to ma pracować w domu stanowiąc automatykę RS232 nie nadaje sie do tego typu transmisji ze względu na długość przewodów i odporność na zakłócenia . Do tego jest RS485 i CAN.


    Orientuje się może ktoś jaka jest maksymalna długość przewodów przy bezpośrednim połączeniu dwóch uC? I czy np. konwertowanie sygnału przez MAX232 coś zmienia odnośnie długości połączenia?