Skocz do zawartości

STM32F4 USART odbiór danych w przerwniach


zsefb123

Pomocna odpowiedź

Dzień dobry. Posiadam płytkę STM32f411re Nucleo. Muszę zrobić komunikację po interfejsie USART pomiędzy komputerem a moją płytką. Wysyłanie ciągu znaków do komputera działa, sprawdziłem za pomocą programu RealTerm oraz własnej aplikacji napisanej w c#. Problemem jest odbiór znaków zarówno w przerwaniach jak i normalnie. Poniżej zamieszczam mój kod.



#include "stm32f4xx.h"
#include "stm32f4xx_nucleo.h"
#include "stm32f4xx_hal_gpio.h"
#include "stm32f4xx_hal_usart.h"

void initUsart2(USART_HandleTypeDef* usart);
void initLed(GPIO_InitTypeDef* led);
static GPIO_InitTypeDef led1;
static USART_HandleTypeDef usart2;
static uint8_t receiveChar = 0;
size_t strlen(char const *s);
void delay(int time);


int main(void)
{
   HAL_Init();

    __HAL_RCC_GPIOA_CLK_ENABLE();
    HAL_USART_MspInit(&usart2);
    HAL_NVIC_EnableIRQ(USART2_IRQn);
    HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
    initLed(&led1);
    initUsart2(&usart2);
   __HAL_USART_ENABLE_IT(&usart2, USART_IT_RXNE);

    char *msg0 = "-50,56\n";
    char *msg1 = "-5,77777\n";
    char *msg3 = "hurra\n";
    char* array[2];
    array[0] = msg0;
    array[1] = msg1;

    int i = 0;
    while(1){

       HAL_USART_Transmit(&usart2, (uint8_t*)array[i], strlen(array[i]), 500);
       HAL_Delay(1000);
       if(receiveChar == 96){
          HAL_USART_Transmit(&usart2, (uint8_t*)msg3, strlen(msg3), 5000);
       }
    }
}

void delay(int time){
    while(time--)
       asm("nop");
}

size_t strlen(char const *s){
  size_t i=0;
  while(s[i])
     i+= 1;
  return i;
}

void HAL_USART_RxCpltCallback(USART_HandleTypeDef* usart){


  int i = 5;
  while(i--){
       HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, 1);
       delay(100000UL);
       HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, 0);
       delay(100000UL);
  }
}

void USART2_IRQHandler(void){

  //HAL_USART_IRQHandler(&usart2);
  //HAL_USART_RxCpltCallback(&usart2);
  int i = 5;
  while(i--){
       HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, 1);
       delay(100000UL);
       HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, 0);
       delay(100000UL);
  }
}

void HAL_USART_MspInit(USART_HandleTypeDef* huart)
{
 GPIO_InitTypeDef GPIO_InitStruct;
 if(huart->Instance==USART2)
 {
   __GPIOA_CLK_ENABLE();
   __USART2_CLK_ENABLE();

   /**USART2 GPIO Configuration
   PA2     ------> USART2_TX
   PA3     ------> USART2_RX
   */
   GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
   GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 }
}

void initUsart2(USART_HandleTypeDef* usart){

  usart->Instance = USART2;
  usart->Init.BaudRate = 9600;
  usart->Init.WordLength = USART_WORDLENGTH_8B;
   usart->Init.StopBits = USART_STOPBITS_1;
   usart->Init.Parity = USART_PARITY_NONE;
   usart->Init.Mode = USART_MODE_TX_RX;
   usart->RxXferSize = 240;
   HAL_USART_Init(usart);
}
void initLed(GPIO_InitTypeDef* led){
  led->Pin = GPIO_PIN_5;
  led->Mode = GPIO_MODE_OUTPUT_PP;
  led->Pull = GPIO_NOPULL;
  led->Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOA, led);
}

W powyższym kodzie problemem jest to, że handler obsługujący przerwanie wykonuje się cały czas, powoduje to nie wykonywanie się funkcji main(). W funkcji obsługującej przerwanie musiałem umieścić własne opóźnienie ponieważ HAL_Delay() się zawieszał (myślę, że to konflikt z SysTick). Dodam jeszcze, że z komputerem komunikuję się przez USART2, pzez piny PA2, PA3 za pomocą programatora dołączonego z płytką. Oczywiście w programie wykorzystuję biblioteki HAL. Z góry dziękuję za odpowiedź.

Link do komentarza
Share on other sites

Miałem kiedyś podobny problem (i przy STMach i przy AVRach), problem leży w ustawianiu flag. Jeżeli w obsłudze przerwania nie wyczyścisz flagi od tego właśnie przerwania, to po wyjściu z ISR znowu zostanie wywołany (ISR). I tak w kółko.

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...