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

STM32f103rb - Komunikacja Modbus

Damian7546 13 Maj 2016 13:26 6522 150
  • #91
    BlueDraco
    Specjalista - Mikrokontrolery
    Chodziło o bit TC , a nie TXE.

    Ja bym to zrobił tak:

    if (USART1->SR & USART_STR_TC)
    GPIOA->BRR = 1u << DE_BIT;

    Ale to niepoważnie wygląda, działa za szybko i zajmuje za mało pamięci - same wady w porównaniu z mądrymi wywołaniami SPL.
  • AM TechnologiesAM Technologies
  • #92
    Użytkownik usunął konto
    Użytkownik usunął konto  
  • #93
    Damian7546
    Poziom 21  
    BlueDraco napisał:
    if (USART1->SR & USART_STR_TC)
    GPIOA->BRR = 1u << DE_BIT;


    Podobnie próbowałem ale z użyciem bibliotek i błąd:

    :25: error: 'USART_STR_TC' undeclared (first use in this function)
  • #94
    grko
    Poziom 33  
    No trochę samodzielności... Weź poszukaj w nagłówkach od ST jaką ta flaga ma definicje.
  • #95
    Damian7546
    Poziom 21  
    Mam chyba wszystkie potrzebne includy:
    Kod: c
    Zaloguj się, aby zobaczyć kod
  • #96
    Użytkownik usunął konto
    Użytkownik usunął konto  
  • #97
    Damian7546
    Poziom 21  
    Piotrus_999 napisał:

    U(S)ART w takim trybie to bardzo proste w obsludze urządzenie.

    Ucze sie
  • #98
    Użytkownik usunął konto
    Użytkownik usunął konto  
  • Pomocny post
    #99
    BlueDraco
    Specjalista - Mikrokontrolery
    Tak dokładnie to powinno być:
    if (USART1->ISR & USART_ISR_TC)
    GPIOA->BRR = 1u << DE_BIT;

    Coś mi dzisiaj klawiatura nie służy.
  • AM TechnologiesAM Technologies
  • #100
    Użytkownik usunął konto
    Użytkownik usunął konto  
  • #101
    grko
    Poziom 33  
    Cytat:

    Coś mi dzisiaj klawiatura nie służy.


    Tyle lat na forum i nawet syntax nie udało się opanować...
  • #102
    BlueDraco
    Specjalista - Mikrokontrolery
    No fakt, w F1 to się nazywa SR, w nowszych ISR.
  • #103
    Użytkownik usunął konto
    Użytkownik usunął konto  
  • #104
    grko
    Poziom 33  
    Wybacz, ale używanie syntax nie jest kwestią doskonałości-niedoskonałości tylko kwestią lenistwa. Doświadczony użytkownik forum powinien jednak dawać przykład w tym zakresie.
  • #105
    BlueDraco
    Specjalista - Mikrokontrolery
    Dośwuadczony użytkownik uważa używanie syntax przy dwóch linijkach kodu źródłowego na znaczący przerost formy nad treścią.
  • #106
    Damian7546
    Poziom 21  
    BlueDraco napisał:
    Tak dokładnie to powinno być:
    if (USART1->ISR & USART_ISR_TC)
    GPIOA->BRR = 1u << DE_BIT;


    Pomogło, urządzenie sygnalizuje że otrzymało ramkę - jednak nie do końca działa.
    Po restarcie procesora jest kilka zapytań i nagle cisza.
    Pomaga tylko restart. Debugerem nie jestem w stanie wychwycić gdzie się wysypuje...

    Dodano po 24 [minuty]:

    Byłbym jeszcze wdzięczny za sprawdzenie konfiguracji zegara 36MHz na wewnętrznym oscylatorze , bo może coś tu jest źle:

    Kod: c
    Zaloguj się, aby zobaczyć kod
  • #107
    Użytkownik usunął konto
    Użytkownik usunął konto  
  • #108
    Damian7546
    Poziom 21  
    To nie problem z zegarem... Tylko ostatnio dodanym ifem... Gdy usunę tego ifa to transmisja działa ciągle (podglądając ramki na Relaterm), jednak bez tego warunku ramki nie docierają do urządzenia po RS485
  • #109
    BlueDraco
    Specjalista - Mikrokontrolery
    A my mamy szukać błędu w kodzie, którego nie raczyłeś pokazać?
  • #110
    Damian7546
    Poziom 21  
    No tak:
    Kod: c
    Zaloguj się, aby zobaczyć kod
  • #111
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Kod w postaci którą przedstawiłeś nie przestawia układu nigdy na odbieranie, ponieważ na flagę TC powinieneś w jakiś sposób czekać - w najprostszej wersji zastąp "if" czymś takim:

    if (USART1->SR & USART_SR_TC)
    ->
    while (!(USART1->SR & USART_SR_TC)) {};

    (przestawienie pinu ma _NIE_ być wewnątrz tej pętli)

    W obecnym kodzie warunek ten jest sprawdzany raz, w momencie w którym na pewno nie jest spełniony, a potem już wychodzisz z całego tego warunku.
  • #112
    Damian7546
    Poziom 21  
    Freddie Chopin napisał:
    while (!(USART1->SR & USART_SR_TC)) {};


    Przy takim rozwiązaniu wydaje się być jeszcze gorzej, bo po restarcie jest tylko jedno zapytanie i potem cisza.
  • #113
    Freddie Chopin
    Specjalista - Mikrokontrolery
    No to zobacz debuggerem gdzie wisi i dlaczego (jaka wtedy jest - przykładowo - wartość rejestru SR).
  • #114
    Damian7546
    Poziom 21  
    Jak mogę zobacyzć gdzie wisi ? W czasie kiety sie zawiesi debugując program w opcjach debugera mam możliwośc wyboru tylko "stop" i "reset" ...
  • #115
    Użytkownik usunął konto
    Użytkownik usunął konto  
  • #116
    Damian7546
    Poziom 21  
    Piotrus_999 napisał:
    Co to za środowisko?

    CoIDE.
    Mam takie ikonki. Tylko jak wyżej napisałem , w czasie kiedy wisi aktywny jest tylko stop i pause.

    Dodano po 48 [minuty]:

    Ale jeśli w czasie debugowania zatrzymam debugowanie "pause" to wychodzi na to że program jest w pętli w tym miejscu :

    Kod: c
    Zaloguj się, aby zobaczyć kod


    W pliku startup_stm32f10x_md.c

    Dodano po 3 [minuty]:

    Dodano po 10 [minuty]:

    Wypinając linie RX mikroprocesora z układu MAX485 program działa o wiele dłużej.
    Tylko pytanie dlaczego?

    Myślałem że może coś nie tak jest w obsłudze przerwania USART1_IRQHandler więc zakomentowałem całość kodu znajdujący się w tym przerwaniu ale to nic nie zmieniło - dopiero fizycznym rozpięci linii RX
  • #117
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Zapisujesz dane do nieistniejącej pamięci poprzez wskaźnik "ramkaodbierz", który na nic nie wskazuje. Zamień ten wskaźnik na tablicę o odpowiednim rozmiarze, nie będziesz musiał w kodzie zmieniać niczego innego, a rozwiążesz ten problem.
  • #118
    Damian7546
    Poziom 21  
    Ciężko będzie wybrać odpowiedni rozmiar tablicy. Trzeba będzie zwiększać / zmniejszać ją dynamicznie...
    Tylko to raczej nie problem bo miejsce gdzie używam ramkaodbierz jest właśnie w przerwaniu:
    USART1_IRQHandler(void) a robiłem próbę gdzie ciało tego przerwania za komentowałem, tym bardziej że gdy linia RX jest rozpięta to po jakimś czasie transmisja się znów zawiesi ?
    A może to przez wewnętrzny oscylator ? Wszędzie piszą żeby raczej używać zewnętrznych ..
    Bufor RX w Stm powinno się czyścic ?
  • #119
    grko
    Poziom 33  
    @Damian7546
    To raczej jest problem. Taka definicja:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    NIE rezerwuje pamięci na ramkę. Definiuje ona tylko wskaźnik na typ u8. Jednym z rozwiązań będzie wybranie rozmiaru tablicy równego maksymalnemu rozmiarowi ramki:

    Kod: c
    Zaloguj się, aby zobaczyć kod
  • #120
    Damian7546
    Poziom 21  
    Ewidentnie w tym leżał problem.
    Jeszcze pytanie od strony sprzętu.
    Skoro już pytania docierają do mojego urządzenia to teraz wpiąłem się usb2rs232ttl i podsłuchuje co jest na linii RX mikroprocesora.

    i tu dziwne rzeczy. Jeśli układ jest podłączony w ten sposób że:
    A (max485) do - RS (TxD)
    B (max485) do +RS (RxD)

    To w odpowiedzi mam tylko 0x00,
    I to powyższe połączenie wydaje mi się poprawne .

    Natomiast jeśli zamienię linie A z B to w odpowiedzi mam dane które nijak mają się do danych jakie powinienem otrzymać. I nie są w każdej odpowiedzi te same ramki .
    Jak to w końcu ma być podłączone ?