HAL_UART_Transmit发送错误的数据

时间:2018-08-15 09:18:47

标签: c embedded stm32 uart

当ch = 0x80时,在PC上我收到0x00,
当ch = 0x40时,在PC上我收到0x80,
当ch = 0x20时,在PC上我收到0x60,
当ch = 0x10时,在PC上我收到0x10,
当ch = 0x08时,在PC上我收到0x08,
当ch = 0x04时,在PC上我收到0x04,
当ch = 0x02时,在PC上我收到0x02,
当ch = 0x01时,在PC上我收到0x01,

我想不通这是怎么回事...我要附加USART初始化,发送功能和主要功能。我应该是软件问题,已经测试过硬件,还可以。 MCU = STM32L011

void InitUSART(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;

    USARTx_CLK_ENABLE();

    UartHandle.Instance = USARTx;
    UartHandle.Init.BaudRate = 9600;
    UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
    UartHandle.Init.StopBits = UART_STOPBITS_1;
    UartHandle.Init.Parity = UART_PARITY_NONE;
    UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    UartHandle.Init.Mode = UART_MODE_TX_RX;
    //UartHandle.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_ENABLE;
    HAL_UART_Init(&UartHandle);

    /* Transmit Configuration */
    USARTx_TX_GPIO_CLK_ENABLE();
    GPIO_InitStruct.Pin = USARTx_TX_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = USARTx_TX_AF;
    HAL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct);

    /* Receive Configuration */
    USARTx_RX_GPIO_CLK_ENABLE();
    GPIO_InitStruct.Pin = USARTx_RX_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = USARTx_TX_AF;
    HAL_GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStruct);

    HAL_NVIC_SetPriority(USARTx_IRQn, 0, 1);
    HAL_NVIC_EnableIRQ(USARTx_IRQn);
}

HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
  uint16_t* tmp;
  uint32_t tickstart = 0;

  /* Check that a Tx process is not already ongoing */
  if(huart->gState == HAL_UART_STATE_READY)
  {
    if((pData == NULL ) || (Size == 0U))
    {
      return  HAL_ERROR;
    }

    /* In case of 9bits/No Parity transfer, pData buffer provided as input paramter 
       should be aligned on a u16 frontier, as data to be filled into TDR will be 
       handled through a u16 cast. */
    if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
    {
      if((((uint32_t)pData)&1) != 0)
      {
        return  HAL_ERROR;
      }
    }

    /* Process Locked */
    __HAL_LOCK(huart);

    huart->ErrorCode = HAL_UART_ERROR_NONE;
    huart->gState = HAL_UART_STATE_BUSY_TX;

    /* Init tickstart for timeout managment*/
    tickstart = HAL_GetTick();

    huart->TxXferSize = Size;
    huart->TxXferCount = Size;
    while(huart->TxXferCount > 0U)
    {
      huart->TxXferCount--;
      if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
      {
        return HAL_TIMEOUT;
      }
      if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
      {
        tmp = (uint16_t*) pData;
        huart->Instance->TDR = (*tmp & (uint16_t)0x01FFU);
        pData += 2U;
      }
      else
      {
        huart->Instance->TDR = (*pData++ & (uint8_t)0xFFU);
      }
    }
    if(UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
    {
      return HAL_TIMEOUT;
    }

    /* At end of Tx process, restore huart->gState to Ready */
    huart->gState = HAL_UART_STATE_READY;

    /* Process Unlocked */
    __HAL_UNLOCK(huart);

    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}

int main(void)
{
  /* STM32L0xx HAL library initialization:
       - Configure the Flash prefetch, Flash preread and Buffer caches
       - Systick timer is configured by default as source of time base, but user
             can eventually implement his proper time base source (a general purpose
             timer for example or other time source), keeping in mind that Time base
             duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
             handled in milliseconds basis.
       - Low Level Initialization
     */
    HAL_Init();

    /* Configure the system clock to 32 MHz */
    SystemClock_Config();

    InitUSART();
    //Transmit(txBuffer, 2);

    extern UART_HandleTypeDef UartHandle;
    uint16_t ch = 0x80;
    TransmitEnable();
    while(1){
        HAL_UART_Transmit(&UartHandle, &ch, 1, 0xFF);
        HAL_Delay(5);
    }
}

2 个答案:

答案 0 :(得分:0)

看起来毕竟是时钟问题。我使用的内部16 MHz振荡器(HSI)与PLL相乘可达32 MHz。 9600波特率的单波特率宽度为110us。现在,我切换到4 MHz(内部MSI),每个波特得到104us。现在的沟通是完美的。

RCC_ClkInitTypeDef RCC_ClkInitStruct ={0};
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0)!= HAL_OK)
{
  while(1);
}

__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
__HAL_RCC_PWR_CLK_DISABLE();

答案 1 :(得分:-1)

根据发送的源文件,将usart编程为“ 8位”,但是此STM HAL例程计算data_bits + parity_bit = 8bits(您的选择)。对于标准文本传输,此STM HAL应为:9位(8_data_bits + one_parity_bit)。