STM32-USART HAL 라이브러리 수신 임의의 길이 데이터 상세 분석

5959 단어 STM32STM32 개발
선언:
최근 STM32L152 HAL 라이브러리 직렬 포트에서 임의의 길이 데이터를 받는 프로그램을 디버깅하여 임의의 길이 데이터를 받는 방법을 상세하게 분석하였다.
하드웨어 플랫폼: STM32L152
소프트웨어 플랫폼: keil v5+cubeMX
함수 라이브러리:HAL 라이브러리
STM32L152 —USART
STM32L152 USART의 HAL 라이브러리에서 수신 함수:
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
이 함수의 매개 변수는 Size가 고정되어 있어 사용 시 매우 불편하여 고정된 길이의 데이터만 수신할 수 있다.
본고는 HAL 라이브러리 UASRT 수신 함수를 상세하게 분석하여 수신 임의의 길이로 수정합니다.PS: 수신 데이터의 끝에 줄 바꿈 문자 0x0a만 적용되며, 수신 데이터가 다른 형식이면 데이터의 특징에 따라 수정할 수 있습니다.
1.HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer, 200);
수신 단말기를 시작하여 초기 길이 200을 설정하고 수신하는 임의의 바이트 수가 200보다 크지 않으면 된다.
2. 인터럽트 처리 함수
void USART1_IRQHandler(void)
{
    HAL_UART_IRQHandler(&huart1); 
}

3. HAL에서UART_IRQHandler (&huart1) 의 정의 수신 단말기 함수 찾기: UARTReceive_IT(huart);
void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
{
  uint32_t tmp_flag = 0, tmp_it_source = 0;


  tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_PE);
  tmp_it_source = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_PE);  
  /* UART parity error interrupt occurred ------------------------------------*/
  if((tmp_flag != RESET) && (tmp_it_source != RESET))
  { 
    huart->ErrorCode |= HAL_UART_ERROR_PE;
  }
  
  tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_FE);
  tmp_it_source = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR);
  /* UART frame error interrupt occurred -------------------------------------*/
  if((tmp_flag != RESET) && (tmp_it_source != RESET))
  {
    huart->ErrorCode |= HAL_UART_ERROR_FE;
  }
  
  tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_NE);
  /* UART noise error interrupt occurred -------------------------------------*/
  if((tmp_flag != RESET) && (tmp_it_source != RESET))
  {
    huart->ErrorCode |= HAL_UART_ERROR_NE;
  }
  
  tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_ORE);
  /* UART Over-Run interrupt occurred ----------------------------------------*/
  if((tmp_flag != RESET) && (tmp_it_source != RESET))
  {
    huart->ErrorCode |= HAL_UART_ERROR_ORE;
  }
  
  tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE);
  tmp_it_source = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE);
  /* UART in mode Receiver ---------------------------------------------------*/
  if((tmp_flag != RESET) && (tmp_it_source != RESET))
  { 
    UART_Receive_IT(huart);
  }
  
  tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_TXE);
  tmp_it_source = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_TXE);
  /* UART in mode Transmitter ------------------------------------------------*/
  if((tmp_flag != RESET) && (tmp_it_source != RESET))
  {
    UART_Transmit_IT(huart);
  }


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


  if(huart->ErrorCode != HAL_UART_ERROR_NONE)
  {
    /* Clear all the error flag at once */
    __HAL_UART_CLEAR_PEFLAG(huart);
    
    /* Set the UART state ready to be able to start again the process */
    huart->State = HAL_UART_STATE_READY;
    
    HAL_UART_ErrorCallback(huart);
  }  
}.

4. UART 수정Receive_IT(huart) 함수,
u8 flag,Rx_Size;
static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
{
  uint16_t* tmp;
  uint32_t tmp_state = 0;

  tmp_state = huart->State; 
  if((tmp_state == HAL_UART_STATE_BUSY_RX) || (tmp_state == 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);
if(((uint8_t)(huart->Instance->DR & (uint8_t)0x00FF))==0x0a) flag++;   //   0x0A          。
Rx_Size++;

      }
      else
      {
        *huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
      }
    }





//   if(--huart->RxXferCount == 0)    //              RxXferCount  0       ,   ,   if(flag== 1);

    if(flag== 1)
    {
      flag=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; 
  }
}

5. UART 직렬 리셋 함수를 작성하고 수신 중단을 다시 켜고 로고를 정리한다.
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if(huart->Instance==USART1)
    { 
    HAL_UART_Transmit(&huart3 ,(uint8_t *)aRxBuffer,Rx_Size ,200);//   3             ,   
    HAL_UART_Receive_IT(&huart1,(uint8_t *)aRxBuffer, 200);//     
    for(u8 i=0;i

위의 수정 사항은 0x0a로 끝나는 임의의 길이의 데이터를 수신할 수 있습니다.그러나 HAL 라이브러리를 수정하는 것은 좋은 해결 방법이 아니다.만약 다른 사람이 당신의 프로그램을 이식하려고 한다면, 다른 사람에게 이식 프로그램에 어려움을 가져올 것이다.DMA 방식으로 직렬 수신을 하는 것이 비교적 좋은 방법이다.

좋은 웹페이지 즐겨찾기