zsefb123 Napisano Styczeń 4, 2017 Udostępnij Napisano Styczeń 4, 2017 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 More sharing options...
Lukaszm Styczeń 4, 2017 Udostępnij Styczeń 4, 2017 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 More sharing options...
zsefb123 Styczeń 4, 2017 Autor tematu Udostępnij Styczeń 4, 2017 Dodałem __HAL_USART_CLEAR_FLAG(&usart2, USART_IT_RXNE) w handlerze i przed while() ale nadal przerwanie się wykonuje zamiast main(). Link do komentarza Share on other sites More sharing options...
Lukaszm Styczeń 4, 2017 Udostępnij Styczeń 4, 2017 Sprawdź w dokumentacji czy przez przypadek ta flaga nie jest czyszczona poprzez wpisanie jedynki do rejestru. Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. 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
Pomocna odpowiedź
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ę »