STM32 CubeMX Halk Library의 일부 구멍

10647 단어 stm32

STM32 CubeMX Halk Library의 일부 구멍


stm32f103V1을 사용합니다.40 버전 라이브러리

UART DMA에서 보낸 질문


발송 함수발송이 끝난 후 성공한 리셋 함수도 정상이지만 다시 발송할 때 보낼 수 없습니다.오류가 계속 반환됩니다.이 함수의 코드를 봅시다.
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
  uint32_t *tmp;
  uint32_t tmp_state = 0;

  tmp_state = huart->State;
  if((tmp_state == HAL_UART_STATE_READY) || (tmp_state == HAL_UART_STATE_BUSY_RX))
  {
    if((pData == NULL ) || (Size == 0)) 
    {
      return HAL_ERROR;
    }

    /* Process Locked */
    __HAL_LOCK(huart);

    huart->pTxBuffPtr = pData;
    huart->TxXferSize = Size;
    huart->TxXferCount = Size;

    huart->ErrorCode = HAL_UART_ERROR_NONE;
    /* Check if a receive process is ongoing or not */
    if(huart->State == HAL_UART_STATE_BUSY_RX)
    {
      huart->State = HAL_UART_STATE_BUSY_TX_RX;
    }
    else
    {
      huart->State = HAL_UART_STATE_BUSY_TX;
    }

    /* Set the UART DMA transfer complete callback */
    huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;

    /* Set the UART DMA Half transfer complete callback */
    huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;

    /* Set the DMA error callback */
    huart->hdmatx->XferErrorCallback = UART_DMAError;

    /* Enable the UART transmit DMA channel */
    tmp = (uint32_t*)&pData;
    HAL_DMA_Start_IT(huart->hdmatx, *(uint32_t*)tmp, (uint32_t)&huart->Instance->DR, Size);

    /* Clear the TC flag in the SR register by writing 0 to it */
    __HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);

    /* Enable the DMA transfer for transmit request by setting the DMAT bit
       in the UART CR3 register */
    SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);

    /* Process Unlocked */
    __HAL_UNLOCK(huart);

    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}

코드를 보면 보내기 전에 상태 표시를 먼저 판단하고 발송 상태에서 보내는 것이 아니라는 것도 정상이다.그러나 한 번 발송하면 상태가 발송 상태로 바뀌고 발송 완료도 명확하지 않아 다음에 다시 발송하고 바쁘다고 판단하면 발송이 안 된다.우리는 그가 보낸 성공적인 처리 부분을 보았다.
static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)     
{
  UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  /* DMA Normal mode*/
  if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) )
  {
    huart->TxXferCount = 0;

    /* Disable the DMA transfer for transmit request by setting the DMAT bit
       in the UART CR3 register */
    CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);

    /* Enable the UART Transmit Complete Interrupt */    
    __HAL_UART_ENABLE_IT(huart, UART_IT_TC);
  }
  /* DMA Circular mode */
  else
  {
    HAL_UART_TxCpltCallback(huart);
  }
}

코드에서 볼 수 있듯이 발송 상태를 지우지 않았기 때문에 다음 발송에 성공하지 못할 문제가 생겼다.직접 보내기 전에 상태를 지우는 것은 라이브러리 함수의 본뜻이 아닐 것 같습니다.우리 는 수신 성공 이 어떻게 처리되었는지 비교해 보았다
static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)  
{
  UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  /* DMA Normal mode*/
  if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) )
  {
    huart->RxXferCount = 0;

    /* Disable the DMA transfer for the receiver request by setting the DMAR bit 
       in the UART CR3 register */
    CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);

    /* 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
    {
      huart->State = HAL_UART_STATE_READY;
    }
  }
  HAL_UART_RxCpltCallback(huart);
}

수신 성공 후 상태 표시를 정확하게 지우면 발송 성공도 마찬가지이기 때문에 빠뜨린 것 같습니다.우리는 더하면 된다
static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)     
{
  UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
  /* DMA Normal mode*/
  if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) )
  {
    huart->TxXferCount = 0;

    /* Disable the DMA transfer for transmit request by setting the DMAT bit
       in the UART CR3 register */
    CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);

    /* Enable the UART Transmit Complete Interrupt */    
    __HAL_UART_ENABLE_IT(huart, UART_IT_TC);

      /* Check if a transmit process is ongoing or not */
    if(huart->State == HAL_UART_STATE_BUSY_TX_RX) 
    {
      huart->State = HAL_UART_STATE_BUSY_RX;
    }
    else
    {
      huart->State = HAL_UART_STATE_READY;
    }
  }
  /* DMA Circular mode */
  else
  {
    HAL_UART_TxCpltCallback(huart);
  }
}

테스트, 정상적으로 발송 가능...

Flash 읽기/쓰기 보호


HAL의 라이브러리 flash는 표준 라이브러리에 비해 변화가 매우 커서 이 부분을 보호하기 위해 수동으로 설정해야 한다.부호를 붙이다
FLASH_OBProgramInitTypeDef obProgram;

    __HAL_FLASH_PREFETCH_BUFFER_DISABLE();

    HAL_FLASHEx_OBGetConfig(&obProgram);

    if (obProgram.RDPLevel == OB_RDP_LEVEL_0)
    {
        obProgram.OptionType = OPTIONBYTE_WRP;  //    
        obProgram.WRPState = OB_WRPSTATE_ENABLE;    //  
        obProgram.WRPPage = OB_WRP_ALLPAGES;    //   
        obProgram.Banks = FLASH_BANK_1;         
        obProgram.RDPLevel = OB_RDP_LEVEL_1;

        HAL_FLASH_Unlock();
        HAL_FLASH_OB_Unlock();
        HAL_FLASHEx_OBProgram(&obProgram);
        HAL_FLASH_OB_Lock();
        HAL_FLASH_Lock();
    }
    __HAL_FLASH_PREFETCH_BUFFER_ENABLE();

좋은 웹페이지 즐겨찾기