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

STM32f103rb - Brak odpowiedzi na RX przy komunikacji Modbus RTU po RS232

ienecode 10 Maj 2016 14:35 8118 150
Najlepsze odpowiedzi

Dlaczego STM32F103RB nie odbiera odpowiedzi Modbus RTU po RS485 przez MAX485 i jak poprawnie przełączyć się z nadawania na odbiór?

MAX485 trzeba przełączać na odbiór natychmiast po zakończeniu nadawania, a nie po stałym opóźnieniu; zamiast czekać na TXE należy czekać na bit TC w USART i dopiero wtedy ściągnąć DE/RE w stan odbioru [#15670454][#15673836] Nie warto też blokować przerwania odbioru ani wykonywać w nim długich operacji — w IRQ najlepiej tylko ustawić flagę, a wysyłanie/analizę zrobić w `main()` albo z timera/SysTick [#15667601][#15677505][#15677603] W Twoim przypadku był jeszcze drugi błąd: `ramkaodbierz` była tylko wskaźnikiem, który nie wskazywał na zaalokowaną pamięć, więc zapis do niej powodował problemy; trzeba zrobić z niej tablicę o odpowiednim rozmiarze [#15676888][#15677014] Po tych poprawkach urządzenie zaczęło poprawnie widzieć ramki odpowiedzi [#15671402]
Wygenerowane przez model językowy.
REKLAMA
  • #1 15663308
    ienecode
    Poziom 21  
    Posty: 2097
    Ocena: 96
    Witam,

    Pytanie odnośnie komunikacji modbus RTU po RS232.

    Z Stm32f103 wysyłam zapytania na MAX485. Do urządzenia dochodzi pytanie bo sygnalizuje to diodą, oraz urządzenie sygnalizuje odpowiedź. Sprawdzałem po stronie TX (przed MAX485) za pomocą "SimpleTerm Gold" i ramka się zgadza, natomiast na RX jest cisza. Co może być przyczyną ?

    Tak wygląda mój main:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #2 15663324
    kornik280
    Poziom 18  
    Posty: 466
    Pomógł: 36
    Ocena: 14
    Cisza w sensie że Slave nie odpowiada czy nic nie odbierasz w armie?
    W pierwszym przypadku może sie adres slava nie zgadzać, suma crc błędna, nie kompatybilne ustawienia magistrali, w drugim coś mnie widze obsługi odbioru w armie (przerwanie, DMA).
    Ponadto te opóźnienia nie wyglądają dobrze, szczególnie odczekiwanie 1 sekundy i dopiero potem przestawianie się na odbiór
  • #3 15663334
    ienecode
    Poziom 21  
    Posty: 2097
    Ocena: 96
    Do slave napewno pytanie dochodzi bo to sygnalizuje.
    Sygnalizuje również odpowiedź .

    Teraz sprawdzam tak:
    1) Przed RS485 na MAX485 podglądam co jest na DI i rzeczywiście zgadza się wysłana ramka.
    2) Przed RS485 na MAX485 podglądam co jest na RO i tam jest cisza.

    Narazie w ogsługę w STM nie ma co wnikać bo dane muszą się dopiero pojawić z RS485 na pinie RO układu MAX485. Między masą a RO jest 5.1V ....
  • #4 15663343
    kornik280
    Poziom 18  
    Posty: 466
    Pomógł: 36
    Ocena: 14
    Masz opóźnienie zanim się przełączysz na odbiór, może poprostu przegapiasz ramkę?
  • #5 15663515
    ienecode
    Poziom 21  
    Posty: 2097
    Ocena: 96
    @kornik280 Tak jak w pierwszym poście opóźnienia.
    Po GPIO_ResetBits(GPIOA, GPIO_Pin_8); niby ma być odbiór.
  • #6 15663631
    kornik280
    Poziom 18  
    Posty: 466
    Pomógł: 36
    Ocena: 14
    Chodzi o to że wysyłasz dajesz opóźnienie przełączasz się na odbiór i podczas tego opóźnienia może przyjść odpowiedź
  • #7 15663716
    ienecode
    Poziom 21  
    Posty: 2097
    Ocena: 96
    kornik280 napisał:
    Chodzi o to że wysyłasz dajesz opóźnienie przełączasz się na odbiór i podczas tego opóźnienia może przyjść odpowiedź


    to tak robie - co wynika z kodu w pierwszym poście...
  • REKLAMA
  • #8 15663765
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    i robisz źle, co wynika z odpowiedzi i z tego że masz problem. Slave nie będzie czekał aż mu pozwolisz na odpowiedź, tylko odpowiada najszybciej jak to możliwe. A że Ty wtedy nie odbierasz...
  • #9 15663805
    ienecode
    Poziom 21  
    Posty: 2097
    Ocena: 96
    @Freddie Chopin po pierwsze odbieranie po rs232 mam zrobione w przerwaniu więc odbieram.

    A po drugie czy to takie istotne ma moim etapie? Tak jak wcześniej wspomniałem wpinam się i podglądam co pojawia się na linii za pomoca przejściówki usb/rs232 którą wpinam do układu tak jak poniżej:
    STM32f103rb - Brak odpowiedzi na RX przy komunikacji Modbus RTU po RS232
  • #10 15663823
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    Niczego nie odbierasz - nieważne czy przez polling czy w przerwaniu czy przez DMA czy jakkolwiek sobie życzysz - układ MAX-485 masz przestawiony na nadawanie. Odpowiedź przychodzi w czasie Twojego delaya. Jeśli wiesz lepiej gdzie jest problem niż kilka osób (mówiących o tym samym problemie), to w sumie po co pytać na forum?
  • #11 15663828
    kornik280
    Poziom 18  
    Posty: 466
    Pomógł: 36
    Ocena: 14
    Jak nie dasz strobowania w stan niski to max485 nic nie odbierze , W Twoim przypadku odpowiedź prawdopodobnie przychodzi w czasie twojego opóźnienia
  • #12 15663842
    ienecode
    Poziom 21  
    Posty: 2097
    Ocena: 96
    Freddie Chopin napisał:
    Niczego nie odbierasz - nieważne czy przez polling czy w przerwaniu czy przez DMA czy jakkolwiek sobie życzysz - układ MAX-485 masz przestawiony na nadawanie. Odpowiedź przychodzi w czasie Twojego delaya. Jeśli wiesz lepiej gdzie jest problem niż kilka osób (mówiących o tym samym problemie), to w sumie po co pytać na forum?


    Nie wiem gdzie jest problem, staram się zrozumieć gdzie leży.
    To w takim razie co mogę zrobić z moją pętlą żeby był czas na odebranie informacji ?

    Dodano po 1 [minuty]:

    W ten sposób:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #13 15663857
    kornik280
    Poziom 18  
    Posty: 466
    Pomógł: 36
    Ocena: 14
    Teraz masz szanse zobaczyć coś bo max zaraz po wysłaniu ramki przechodzi w tryb odbioru
  • #15 15663947
    ienecode
    Poziom 21  
    Posty: 2097
    Ocena: 96
    Freddie Chopin napisał:
    Dalej jest źle, bo na początku pętli znów przestawiasz MAXa w tryb nadawania (natychmiast po tym jak przestawiłeś go w tryb odbioru).


    To jak to zrealizować, Żeby dać czas procesorowi na odebranie danych z MAX485? Bo ja nie mam pomysłu...

    Dodano po 8 [minuty]:

    Bez Delay'ów tylko w obsłudze przerwania od odebrania napisać ifa który czeka aż przyjdzie cała ramka ?
  • #16 15663988
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Posty: 13336
    Pomógł: 1712
    Ocena: 870
    Ależ możesz dać delaye, tylko w odpowiednim miejscu... Niemniej jednak te delaye nadają się tylko do testowania czy transmisja działa, bo w "normalnym" programie to będzie już musiało być zrobione inaczej.
  • #17 15663996
    ienecode
    Poziom 21  
    Posty: 2097
    Ocena: 96
    Freddie Chopin napisał:
    bo w "normalnym" programie to będzie już musiało być zrobione inaczej.


    Tz jak ? :)
    Narazie przychodzi mi do głowy tylko takie rozwiązanie:
    Załóżmy że bez Delay'ów w mainie. W pętli jest tylko wysyłana ramka i zmiana pinu sterującego.
    Natomiast w przerwaniu sprawdzam: jeśli odebrano pierwszy bajt (tj. adres urządzenia ) to odbieram kolejne aż do otrzymania sumy CRC ?
    Wtedy by to miało sens ?

    Dodano po 1 [godziny] 38 [minuty]:

    To tak,
    Wyskrobałem obsługę przerwania odebrania z RS która na razie wygląda następująco:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Póki co to mam problem bo nie wiem kiedy stwierdzić że to koniec ramki, zaraz pod komentarzem "//warunek konca ramki??????????????????"

    Jaki tam warunek powinien być ?
  • #19 15664994
    ienecode
    Poziom 21  
    Posty: 2097
    Ocena: 96
    To wychodzi na to że w warunku muszę dodać odliczanie czasu 3,5 znaku ? jeśli przekroczy ten czas to wchodzi mi do tego ifa , tak ?
    Tylko w jaki sposób to zrealizować ?
  • REKLAMA
  • #21 15665017
    ienecode
    Poziom 21  
    Posty: 2097
    Ocena: 96
    Nie będzie to takie łatwe :/
  • #22 15665048
    kornik280
    Poziom 18  
    Posty: 466
    Pomógł: 36
    Ocena: 14
    Na początek możesz mieć ramke na sztywno wiesz co posyłasz do slava i wiesz jak długa będzie odpowiedź,w przerwaniu inkrementujesz tablice.
    Gdy doliczysz się całej ramki wtedy ją sprawdzasz.
    Nie jest to rozwiązanie idealne. Preferowane jest z mierzeniem 3,5T
  • #23 15665655
    ienecode
    Poziom 21  
    Posty: 2097
    Ocena: 96
    To zrobiłem tak jak mówisz:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Jeśli mam tyle bytów o ile pytam to ramkę uważam za całą i sprawdzam czy suma CRC się zgadza. Myślę że to mi spokojnie wystarczy na funkcjonalność jaką potrzebuje.

    Teraz pytanie odnośnie przerobienia maina.
    Bo rozumie że w mainie w pętli głównej nie mogę mieć ciągle wysyłania ramki bo nie będzie czasu na to żeby mikroporcesor przechwycił przerwanie z RXNE ?
    W takim razie mam zrobić jakieś przerwanie zegarowe które będzie wywoływać co jakiś czas wysłanie rami ? To rozwiąże problem ciągłego wysyłania ?
  • #24 15665760
    kornik280
    Poziom 18  
    Posty: 466
    Pomógł: 36
    Ocena: 14
    Najprościej użyć przerwanie od SystTick i tam wysyłać zapytanie
  • #25 15665989
    ienecode
    Poziom 21  
    Posty: 2097
    Ocena: 96
    Nie wiem czy dobrze jeszcze zrozumiałem przerwanie od licznika zliczającego w dół SysTick.
    Procesor skonfigurowałem na zewnętrznym oscylatorze 8MHz i przez PLL ostatecznie jest teraz 72MHz.

    Główna funkcja ma teraz taką postać:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    czyli teraz co 1ms jest wywoływana funkcja SystTick_Handler ?
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Tak to zrozumiałem z jakiegoś tutoriala...
    gdybym w funkcji SysTick_Config(CLK_FREQ/1000); nie dzielił przez 1000 tylko zostawił moją częstotliwośc 72MHz to przerwanie było by co 1s ? dlaczego tak niby ?
  • #26 15666012
    Konto nie istnieje
    Konto nie istnieje  
  • #27 15666040
    ienecode
    Poziom 21  
    Posty: 2097
    Ocena: 96
    No wiem że to układ który zlicza impulsy z zegara z którego jest taktowany mikroprocesor.

    http://echiny.pl/piotr/arm/konfiguracja-rcc-i-nvic-obsluga-systick-oraz-timera-tim2

    Tutaj gośc pisze że jak częstotliwość taktowania podzieli przez 1000 to wywołanie będzie miał co 1ms ....
    @Piotrus_999 Ty napisałeś odwrotnie :
    Piotrus_999 napisał:
    72e3/ 72e6 = 1e-3s
  • #28 15666053
    Konto nie istnieje
    Konto nie istnieje  
  • #29 15666066
    ienecode
    Poziom 21  
    Posty: 2097
    Ocena: 96
    Piotrus_999 napisał:
    Naprawde?

    wiesz co znaczy 1e-3s 0.001s?

    a jeszcze chcą żeby matematyka na maturze była nieobowiązkowa


    nie o zapis mi chodziło tylko myślałem że w argumencie funkcji SysTim_Config chciałeś wstawić 72e3/ 72e6.
    Ale już rozumie:
    1/72e6 = czas jednego taktu
    więc:
    czas jednego taktu *72000 = 0.001s.
  • #30 15666071
    grko
    Poziom 33  
    Posty: 1386
    Pomógł: 247
    Ocena: 141
    Cytat:

    72e6 razy sie zmieni to wywoła UEV co spowoduje wywołanie (w tym przypadku) tego handlera. poniewaz 1 zmiana licznika to 1 takt zegara to 72e6 / 72e6 = 1s

    Jak wartość bedze 72e3 to 72e3/ 72e6 = 1e-3s

    Takie pytanko: czy wiesz w ogóle jak działa licznik?


    Tyle że systick jest 24 bitowym timerem. Wypadałoby zajrzeć do implementacji zanim zaczniesz wprowadzać w błąd autora.

Podsumowanie tematu

✨ Użytkownik zadał pytanie dotyczące problemu z komunikacją Modbus RTU po RS232 z użyciem mikrokontrolera STM32F103RB i układu MAX485. Mimo że zapytania są wysyłane poprawnie, odpowiedzi nie są odbierane. W dyskusji poruszono kwestie związane z opóźnieniami w przełączaniu trybów nadawania i odbioru, co może prowadzić do utraty odpowiedzi. Użytkownicy sugerowali poprawki w kodzie, takie jak zmiana kolejności operacji oraz użycie przerwań do obsługi odbioru. Wskazano również na konieczność poprawnej konfiguracji zegara oraz na problemy sprzętowe, takie jak niewłaściwe połączenia w układzie. Ostatecznie, po wprowadzeniu poprawek, użytkownik uzyskał poprawną komunikację, jednak nadal występowały sporadyczne problemy z odbiorem danych.
Wygenerowane przez model językowy.
REKLAMA