STM32F429I-DISCO obsługa USART w przerwaniu

Wszystko co dotyczy płytek z rodziny Discovery firmy STM
ODPOWIEDZ
Awatar użytkownika
stachu
Użytkownik
Posty: 58
Rejestracja: 18 paź 2017, 19:29
Lokalizacja: Kornatka

STM32F429I-DISCO obsługa USART w przerwaniu

Post autor: stachu »

Witam mam problem z kodem.

Napisałem sobie bufor kołowy i w przerwaniu go obsługuję.

Podczas drukowania znaku czyli wywoływania funkcji

Podczas wysyłania znaku wszytko jest w porzadku program drukuje na uart komunikat i dlaej radosnie mruga diodą, niestety po odczycie danych otrzymuję poprawnie echo ale program nie wraca do pętli głównej z przerwania :( dioda nie mryga zamraza się :(

Cały czas drukuje printfa na terminal podczas debuugowania po odebraniu znaku.
  1. // USART Interrupt Service Routine (ISR)
  2. void USARTx_IRQHandler(void){
  3.    
  4.  
  5.     if (__HAL_USART_GET_FLAG(&UartHandle, USART_FLAG_RXNE)) {
  6.         // the RXNE interrupt has occurred
  7.         if (__HAL_USART_GET_IT_SOURCE(&UartHandle, USART_IT_RXNE)) {
  8.             // the RXNE interrupt is enabled           
  9.             // TODO: read the received character and place it in the receive ring buffer
  10.  
  11.              char c;
  12.              while(RingBuffer_PutChar(&USART_RingBuffer_Rx, c));
  13.        
  14.         // tutaj wisi program i nie wychodzi z przerwania
  15.         //   printf("USART_READ_DATA\n\r");
  16.            
  17.         }
  18.     }
  19.    
  20.     if (__HAL_USART_GET_FLAG(&UartHandle, USART_FLAG_TXE)) {
  21.       // the TXE interrupt has occurred
  22.     if (__HAL_USART_GET_IT_SOURCE(&UartHandle, USART_IT_TXE)) {
  23.         // the TXE interrupt is enabled
  24.          
  25.             // TODO: get a character from the transmit ring buffer and send it via UART
  26.            
  27.             char znak;
  28.            
  29.        
  30.             if (RingBuffer_GetChar(&USART_RingBuffer_Tx, &znak)) // jesli pobrano znak poprawnie  
  31.             {
  32.                 __USART_ENABLE_IT(&UartHandle, USART_IT_TXE);
  33.                 USARTx->DR = znak; // wyslij znak
  34.             }
  35.                 else
  36.             {
  37.                 __USART_DISABLE_IT(&UartHandle, USART_IT_TXE); // disable interrupt // wylacz przerwanie
  38.             }
  39.                
  40.            
  41.            
  42.            
  43.       }
  44.   }
  45. }
dodaje jeszcze funkcję RingBuffer_PutChar
  1. bool RingBuffer_PutChar(RingBuffer *ringBuffer, char c)
  2. {
  3.    
  4.     assert(ringBuffer);
  5.    
  6.     if (ringBuffer) {
  7.        
  8.        
  9.         if(ringBuffer->len == ringBuffer->size)
  10.         {
  11.             return false;
  12.         }
  13.       unsigned int Index = (ringBuffer->tail + ringBuffer->len) % ringBuffer->size;
  14.         ringBuffer->buf[Index] = c;
  15.         ringBuffer->len++;
  16.         return true;    
  17.     }
  18.     return false;
  19. }
poprawiono, Nef.
Awatar użytkownika
squeez
GRafik
Posty: 158
Rejestracja: 16 paź 2017, 23:52

Re: STM32F429I-DISCO obsługa USART w przerwaniu

Post autor: squeez »

No a nie "czyścisz" flagi przerwania?

Ja na HAL-u nie pisałem, ale jak piszę czy to na rejestrach czy LL to pierwsze co robię po sprawdzeniu czy flaga jest ustawiona to ją czyszczę i dopiero potem dalej reszta kodu.

A z innej beczki nie wiem jak masz ten bufor zaimplementowany ale w RingBuffer_PutChar zwiększasz (ringBuffer->len++;) ale nie sprawdzasz czy nie przekraczasz rozmiaru (nadpisujesz dane), chyba że masz to gdzie indziej zaimplementowane.
Awatar użytkownika
elvis
Użytkownik
Posty: 71
Rejestracja: 30 lis 2018, 17:50

Re: STM32F429I-DISCO obsługa USART w przerwaniu

Post autor: elvis »

Używanie while w obsłudze przerwania to przeważnie zły pomysł - co prawda biblioteki ST tak robią, ale nie należy brać przykładu ze złego kodu.
Awatar użytkownika
stachu
Użytkownik
Posty: 58
Rejestracja: 18 paź 2017, 19:29
Lokalizacja: Kornatka

Re: STM32F429I-DISCO obsługa USART w przerwaniu

Post autor: stachu »

Diękuję za odpowiedź :)

Problemem okazało się że podczas odbioru nie ładowałem znaku do rejestru mikrokontrolera czyli zabrakło po

while(RingBuffer_PutChar(&USART_RingBuffer_Rx, c));
lini
USARTx->DR = znak; // wyslij znak

wtedy flaga jest zerowana i wychodzi program z przerwania.

Dziękuję za zainteresowanie :)
ODPOWIEDZ

Wróć do „STM32-Discovery”