Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

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

NewbieMan 11 Jun 2014 11:36 1701 8
  • #1
    NewbieMan
    Level 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 ?
    Code: c
    Log in, to see the code
  • Helpful post
    #2
    BlueDraco
    MCUs specialist
    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?
  • #3
    NewbieMan
    Level 13  
    Dzieki BlueDraco. Ależ przeoczenie wystarczyło wykonać xor na nr bufora w wysyłaniu:
    Code: c
    Log in, to see the code


    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,
              ^
  • #4
    BlueDraco
    MCUs specialist
    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.
  • #5
    NewbieMan
    Level 13  
    BlueDraco wrote:
    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.

    Quote:

    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 );

    Quote:

    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.
  • #6
    NewbieMan
    Level 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.

    Code: c
    Log in, to see the code


    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.
  • #7
    NewbieMan
    Level 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 ?
  • #8
    BlueDraco
    MCUs specialist
    Zacznij od zwiększenia rozmiaru bufora tak, żeby był nie mniejszy niż 512 B i nie mniejszy niż rozmiar sektora Flash. Jaka to pamięć?
  • #9
    NewbieMan
    Level 13  
    Wieczorem spróbuję zwiększyć rozmiar bufora. Jest to pamięć S29GL128P.