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.

[LPC1769][C] - obsługa UART w przerwaniu

11 Cze 2014 11:36 1599 8
  • Poziom 13  
    Mam problem z obsługą odbioru danych przez UART w przerwaniu. Dotąd korzystałem z funkcji SPL niewykorzystujące przerwania do transmisji danych przez UART.
    Mój kod poniżej, wpisując przez terminal (putty) na klawiaturze cyfry od 1 do 8 mikrokontroler wysyła na terminal m,gp�, a przecież powinien wypluć właśnie przesłane znaki. W czym jest problem ?
    Kod: c
    Zaloguj się, aby zobaczyć kod
    Darmowe szkolenie: Ethernet w przemyśle dziś i jutro. Zarejestruj się za darmo.
  • Pomocny post
    Specjalista - Mikrokontrolery
    Wysyłasz znaki z bufora innego, niż ten, do którego odbierałeś - przyjrzyj się operacjom na zmiennej nr_buf.

    Ile masz ostrzeżeń kompilatora?
  • Poziom 13  
    Dzieki BlueDraco. Ależ przeoczenie wystarczyło wykonać xor na nr bufora w wysyłaniu:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Fakt jest sporo ostrzeżeń:
    Code:

    ../src/main.c: In function 'UART0_IRQHandler':
    ../src/main.c:69:2: warning: passing argument 1 of 'UART_GetIntId' from incompatible pointer type [enabled by default]
      tmp = UART_GetIntId( LPC_UART0 );
      ^
    In file included from ../src/main.c:18:0:
    /Programowanie/LPC1769/lpc175x_6x_driver_library/inc/lpc17xx_uart.h:607:10: note: expected 'struct LPC_UART_TypeDef *' but argument is of type 'struct LPC_UART0_TypeDef *'
     uint32_t UART_GetIntId(LPC_UART_TypeDef* UARTx);

    ../src/main.c: In function 'main':
    ../src/main.c:146:2: warning: passing argument 1 of 'UART_Init' from incompatible pointer type [enabled by default]
      UART_Init( LPC_UART0, &uart_configstruct ); // konfiguracja UART0
      ^
    In file included from ../src/main.c:18:0:
    /Programowanie/LPC1769/lpc175x_6x_driver_library/inc/lpc17xx_uart.h:590:6: note: expected 'struct LPC_UART_TypeDef *' but argument is of type 'struct LPC_UART0_TypeDef *'
     void UART_Init(LPC_UART_TypeDef *UARTx, UART_CFG_Type *UART_ConfigStruct);
          ^
    ../src/main.c:153:2: warning: passing argument 1 of 'UART_FIFOConfig' from incompatible pointer type [enabled by default]
      UART_FIFOConfig( LPC_UART0, &uart_fifiostruct ); // konfiguracja bufora FIFO
      ^
    In file included from ../src/main.c:18:0:
    /Programowanie/LPC1769/lpc175x_6x_driver_library/inc/lpc17xx_uart.h:603:6: note: expected 'struct LPC_UART_TypeDef *' but argument is of type 'struct LPC_UART0_TypeDef *'
     void UART_FIFOConfig(LPC_UART_TypeDef *UARTx, UART_FIFO_CFG_Type *FIFOCfg);

    ../src/main.c:218:7: warning: passing argument 1 of 'UART_Send' from incompatible pointer type [enabled by default]
           UART_Send( LPC_UART0, &bufor[nr_buf ^ 1], BUF_SIZE, NONE_BLOCKING ); // wyslanie przez UART zawrtosc bufora - funcja z SPL
           ^
    In file included from ../src/main.c:18:0:
    /Programowanie/LPC1769/lpc175x_6x_driver_library/inc/lpc17xx_uart.h:597:10: note: expected 'struct LPC_UART_TypeDef *' but argument is of type 'struct LPC_UART0_TypeDef *'
     uint32_t UART_Send(LPC_UART_TypeDef *UARTx, uint8_t *txbuf,
              ^
    ../src/main.c:218:7: warning: passing argument 2 of 'UART_Send' from incompatible pointer type [enabled by default]
           UART_Send( LPC_UART0, &bufor[nr_buf ^ 1], BUF_SIZE, NONE_BLOCKING ); // wyslanie przez UART zawrtosc bufora - funcja z SPL
           ^
    In file included from ../src/main.c:18:0:
    //Programowanie/LPC1769/lpc175x_6x_driver_library/inc/lpc17xx_uart.h:597:10: note: expected 'uint8_t *' but argument is of type 'volatile uint8_t (*)[8]'
     uint32_t UART_Send(LPC_UART_TypeDef *UARTx, uint8_t *txbuf,
              ^
  • Specjalista - Mikrokontrolery
    Jeden błąd zastąpiłeś innym - można łatwo pokazać, że takie coś ma szanse spowodować błąd, bo przerwanie odbioru może pakować dane do starego bufora (nie wiem zresztą, po co te dwa bufory).

    Doprowadź kod do takiej postaci, żeby nie było żadnych ostrzeżeń.
    Możesz np. zrzutować jawnie wskaźnik na UART0 na wskaźnik na UART.

    UART_Send( LPC_UART0, &bufor[nr_buf], BUF_SIZE, NONE_BLOCKING );
    - tu też & jest w zasadzie błędem, ale szczęśliwie kompilator zinterpretuje to poprawnie.
  • Poziom 13  
    BlueDraco napisał:
    Jeden błąd zastąpiłeś innym - można łatwo pokazać, że takie coś ma szanse spowodować błąd, bo przerwanie odbioru może pakować dane do starego bufora (nie wiem zresztą, po co te dwa bufory)..

    2 bufory są potrzebne ponieważ zapis będzie nie na terminal, lecz do pmięci flash która jest stosunkowo wolna i część danych ginęła. Dlatego rozgryzam przerwania. Możesz podać / opisać przykład kiedy będzie błąd.

    Cytat:

    Doprowadź kod do takiej postaci, żeby nie było żadnych ostrzeżeń.
    Możesz np. zrzutować jawnie wskaźnik na UART0 na wskaźnik na UART.

    Zrobione:
    Code:
    UART_Init( (LPC_UART_TypeDef *)LPC_UART0, &uart_configstruct );

    Cytat:

    UART_Send( LPC_UART0, &bufor[nr_buf], BUF_SIZE, NONE_BLOCKING );
    - tu też & jest w zasadzie błędem, ale szczęśliwie kompilator zinterpretuje to poprawnie.

    Wiem, że nazwa tablicy jest zarazem adresem jej początku.
  • Poziom 13  
    Wstawiam kod obsługi odbioru danych w przerwaniu, gdzie odebrane dane są zapisywane do bufora a po zapełnieniu bufora do zewnętrznej pamięci, w tym przypadku na karte SD, docelowo do pamięci Flash - może komuś się przyda.

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Należałoby dopisać obsługę błędów związanych z odbieraniem danych jednak po dłuższym zastanowieniu nie ma sensu ponieważ założeniem było napisanie programu odbierającego surowe dane, które można wysłać dowolnym programem jako ciąg danych.
    Na pewno można dopisać obsługę DMA, lecz na moim etapie zaawansowania i braku styczności z programowaniem DMA odkładam to na później.
  • Poziom 13  
    No i jest problem okazało się, że zastosowanie kodu który wcześniej namłodziłem dla zapisu danych w pamięci NOR FLASH nie zdaje egzaminu. Za każdym razem pierwszy zapis bufora o rozmiarze opisanym w BUF_SIZE jest prawidłowy, następne zapisy tracą cześć danych. Wnioskuję, że zapis do pamięci flash trwa zbyt długo i dane są nadpisywane. Zwiększanie rozmiaru bufora też nie daje oczekiwanego efektu.
    Ktoś ma pomysł w jaki sposób rozwiązać nieprzerwane odbieranie po UART i zapis tych danych do "wolnej" pamięci flash ?
  • Specjalista - Mikrokontrolery
    Zacznij od zwiększenia rozmiaru bufora tak, żeby był nie mniejszy niż 512 B i nie mniejszy niż rozmiar sektora Flash. Jaka to pamięć?
  • Poziom 13  
    Wieczorem spróbuję zwiększyć rozmiar bufora. Jest to pamięć S29GL128P.