2016-08-22 2 views
0

Controller: STM32F411RESTM32F411RE serielle Schnittstelle arbeitet nicht im Interrupt-Modus

I USART2 als serielle Schnittstelle mit Interrupt-Basis verwenden. Ich aktiviere NVIC in stmcubemx, den generierten Code, wenn Daten vom Terminal-Interrupt kommen, aber der HART-Status HAL_UART_STATE_READY ist. Aus diesem Grund wird es Funktion UART_Receive_IT Funktion erhalten und kam heraus. Bitte helfen Sie, dieses Problem zu lösen, und ich brauche Anleitung, wie man uart als Unterbrechungsmodus machen kann.

Code:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) 
{ 
    if(__HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE)) 
    { 
     HAL_UART_Transmit(huart, str, 7, 0xFF); 
     memset(str, '\0', sizeof(str)); 
    } 

}        /********* IRQ code*******/ 
    void HAL_UART_IRQHandler(UART_HandleTypeDef *huart) 
{ 


    tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_PE); 
    tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_PE); 
    /* UART parity error interrupt occurred ------------------------------------*/ 
    if((tmp1 != RESET) && (tmp2 != RESET)) 
    { 
    __HAL_UART_CLEAR_PEFLAG(huart); 

    huart->ErrorCode |= HAL_UART_ERROR_PE; 
    } 

    tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_FE); 
    tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR); 
    /* UART frame error interrupt occurred -------------------------------------*/ 
    if((tmp1 != RESET) && (tmp2 != RESET)) 
    { 
    __HAL_UART_CLEAR_FEFLAG(huart); 

    huart->ErrorCode |= HAL_UART_ERROR_FE; 
    } 

    tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_NE); 
    tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR); 
    /* UART noise error interrupt occurred -------------------------------------*/ 
    if((tmp1 != RESET) && (tmp2 != RESET)) 
    { 
    __HAL_UART_CLEAR_NEFLAG(huart); 

    huart->ErrorCode |= HAL_UART_ERROR_NE; 
    } 

    tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_ORE); 
    tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR); 
    /* UART Over-Run interrupt occurred ----------------------------------------*/ 
    if((tmp1 != RESET) && (tmp2 != RESET)) 
    { 
    __HAL_UART_CLEAR_OREFLAG(huart); 

    huart->ErrorCode |= HAL_UART_ERROR_ORE; 
    } 

    tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE); 
    tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE); 
    if(tmp2 == 0x32) 
    tmp2=0x32; 
    /* UART in mode Receiver ---------------------------------------------------*/ 
    if((tmp1 != RESET) && (tmp2 != RESET)) 
    {   
    UART_Receive_IT(huart); 
    } 

    tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_TXE); 
    tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_TXE); 
    /* UART in mode Transmitter ------------------------------------------------*/ 
    if((tmp1 != RESET) && (tmp2 != RESET)) 
    { 
    UART_Transmit_IT(huart); 
    } 

    tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_TC); 
    tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC); 
    /* UART in mode Transmitter end --------------------------------------------*/ 
    if((tmp1 != RESET) && (tmp2 != RESET)) 
    { 
    UART_EndTransmit_IT(huart); 
    } 

    if(huart->ErrorCode != HAL_UART_ERROR_NONE) 
    { 
    /* Set the UART state ready to be able to start again the process */ 
    huart->State = HAL_UART_STATE_READY; 

    HAL_UART_ErrorCallback(huart); 
    } 
}      
/************receive code *********/ 
static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart) 
{ 
    uint16_t* tmp; 
    uint32_t tmp1 = 0; 

    tmp1 = huart->State; 
    if((tmp1 == HAL_UART_STATE_BUSY_RX) || (tmp1 == HAL_UART_STATE_BUSY_TX_RX)) 
    { 
    if(huart->Init.WordLength == UART_WORDLENGTH_9B) 
    { 
     tmp = (uint16_t*) huart->pRxBuffPtr; 
     if(huart->Init.Parity == UART_PARITY_NONE) 
     { 
     *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF); 
     huart->pRxBuffPtr += 2; 
     } 
     else 
     { 
     *tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF); 
     huart->pRxBuffPtr += 1; 
     } 
    } 
    else 
    { 
     if(huart->Init.Parity == UART_PARITY_NONE) 
     { 
     *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF); 
     } 
     else 
     { 
     *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F); 
     } 
    } 

    if(--huart->RxXferCount == 0) 
    { 
     __HAL_UART_DISABLE_IT(huart, UART_IT_RXNE); 

     /* Check if a transmit process is ongoing or not */ 
     if(huart->State == HAL_UART_STATE_BUSY_TX_RX) 
     { 
     huart->State = HAL_UART_STATE_BUSY_TX; 
     } 
     else 
     { 
     /* Disable the UART Parity Error Interrupt */ 
     __HAL_UART_DISABLE_IT(huart, UART_IT_PE); 

     /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ 
     __HAL_UART_DISABLE_IT(huart, UART_IT_ERR); 

     huart->State = HAL_UART_STATE_READY; 
     } 
     HAL_UART_RxCpltCallback(huart); 

     return HAL_OK; 
    } 
    return HAL_OK; 
    } 
    else 
    { 
    return HAL_BUSY; 
    } 
} 
+0

Zeigen Sie uns bitte einen Code. –

+0

In der UART_Receive_IT Funktion huart-> State wird immer HAL_UART_STATE_READY sein, also kam es aus der Schleife heraus. –

+0

Werfen Sie einen Blick auf [https://stackoverflow.com/questions/37297318/cannot-transmit-every-characters-through-uart](https://stackoverflow.com/questions/37297318/cannot-transmit-every-characters (durch-uart), sieht es nach der gleichen Frage aus. –

Antwort

0

Ich denke, es gibt ein paar Probleme in Ihrem Code sind. Die Funktionsweise der HAL besteht darin, Ihnen die Arbeit zu erleichtern, damit Sie die Interrupt-Flags nicht überprüfen müssen. In Ihrem Interrupt-Handler überprüfen Sie tatsächlich das UART_IT_RXNE-Bit, aber dieses Bit wurde bereits automatisch gelöscht, wenn die HAL die Bytes aus dem USART-RX-Register gelesen hat. So entfernen Sie die Zeile:

if(__HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE) 

str scheint eine Reihe von Zeichen zu sein, ich glaube, Sie nicht die Memset verwenden, wie es sollte, ist der richtige Weg:

#define LEN 7 
char str[LEN]; 
memset(str, '\0', LEN); 

Ich verstehe, dass Sie möchten, um eine Zeichenfolge zu senden, wenn Sie den RX-Interrupt-Handler erreichen, aber ich bin mir nicht sicher, wie Sie die HAL_UART_Receive_IT Funktion in erster Linie aufgerufen haben. So wie ich es bin mit ist wie folgt:

volatile bool char_received = false; 
volatile char rx_char; 

int main(void) 
{ 
    //All your hardware init here 

    //Receive 1 character in interrupt mode 
    HAL_UART_Receive_IT(&huart, &rx_char, 1); 

    while(1) 
    { 
     if (rx_char == true) 
     { 
      rx_char = false; 

      if (rx_char == 's') 
      { 
       HAL_UART_Transmit(&huart, "Hello", 5, 100); 
      } 

      HAL_UART_Receive_IT(&huart, &rx_char, 1); 
     } 
    } 
} 

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) 
{ 
    rx_char = true; 
} 

In dem obigen Code, ich „Hallo“ string schicken, wenn ich ‚s‘ im Interrupt-Modus erhalten. Beachten Sie, dass ich im Interrupt-Handler nicht viel mache, setzen Sie einfach ein Flag. Beachten Sie auch, dass Sie den Anruf erneut HAL_UART_Receive_IT benötigen.

+0

Ich habe Ihren Code dann gesehen, was Bedeutung von Interrupt-Basis Sie HAL_UART_Receive_IT Funktion in while (1) aufrufen. Ich möchte von UART_Receive_IT Funktion immer aufrufen, wenn Daten in uart Datenregister von Vektortabelle uart IRQ Handle sind. –

+0

'HAL_UART_Receive_IT (& huart, & rx_char, 1)' aktiviert den UART RX-Interrupt (Vektortabelle) und macht sich bereit, 1 Zeichen im Interrupt-Modus zu empfangen. Wenn dann 1 Zeichen empfangen wird, deaktiviert die HAL den UART-RX-Interrupt, ruft "HAL_UART_RxCpltCallback" auf und zu diesem Zeitpunkt enthält "rx_char" das tatsächliche Zeichen. Wenn Sie ein anderes Zeichen erhalten möchten, müssen Sie erneut 'HAL_UART_Receive_IT' aufrufen. Beachten Sie, dass ich in diesem Beispiel nur ein Zeichen erhalten möchte. Wenn Sie wissen, dass Sie N Zeichen erhalten sollen, verwenden Sie 'HAL_UART_Receive_IT (& huart, rx_buff, N)' wobei 'rx_buff' ein Array von N Bytes ist. –

+0

Vielen Dank für Ihre Erklärung. \t Noch habe ich einige Zweifel 1. zur Zeit des Empfangs, wie Sie entscheiden Bytes zählen, Benutzer kann Ihnen nicht sagen, die Nr. von Byte nur Ding ist bis '\ r' oder '\ n' ist Endpunkt. 2.Wenn ich bereits mein UART-Register für die UART-Empfangs-Interrupt-Base konfiguriert habe, sollte die Leitung laut meinem Wissen Interrupt geben. Keine Notwendigkeit, jedes Mal zu unterbrechen, sollte es automatisch von der Vektortabelle kommen. –

-1
void HAL_UART_IRQHandler(UART_HandleTypeDef *huart) 
{ 


    tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_PE); 
    tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_PE); 
    /* UART parity error interrupt occurred ------------------------------------*/ 
    if((tmp1 != RESET) && (tmp2 != RESET)) 
    { 
    __HAL_UART_CLEAR_PEFLAG(huart); 

    huart->ErrorCode |= HAL_UART_ERROR_PE; 
    } 

    tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_FE); 
    tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR); 
    /* UART frame error interrupt occurred -------------------------------------*/ 
    if((tmp1 != RESET) && (tmp2 != RESET)) 
    { 
    __HAL_UART_CLEAR_FEFLAG(huart); 

    huart->ErrorCode |= HAL_UART_ERROR_FE; 
    } 

    tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_NE); 
    tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR); 
    /* UART noise error interrupt occurred -------------------------------------*/ 
    if((tmp1 != RESET) && (tmp2 != RESET)) 
    { 
    __HAL_UART_CLEAR_NEFLAG(huart); 

    huart->ErrorCode |= HAL_UART_ERROR_NE; 
    } 

    tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_ORE); 
    tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR); 
    /* UART Over-Run interrupt occurred ----------------------------------------*/ 
    if((tmp1 != RESET) && (tmp2 != RESET)) 
    { 
    __HAL_UART_CLEAR_OREFLAG(huart); 

    huart->ErrorCode |= HAL_UART_ERROR_ORE; 
    } 

    tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE); 
    tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE); 
    if(tmp2 == 0x32) 
    tmp2=0x32; 
    /* UART in mode Receiver ---------------------------------------------------*/ 
    if((tmp1 != RESET) && (tmp2 != RESET)) 
    {   
    HAL_UART_Receive(huart, buff, 8, 0xFF); // FOR receive data on interrupt base :chandan 
    } 
+0

Diese Funktion HAL_UART_Receive (huart, buff, 8, 0xFF) empfängt alle Daten bis '\ r' oder '\ n' innerhalb der Funktion, für die ich Änderungen vorgenommen habe. Es funktioniert gut. –

Verwandte Themen