c - HAL_UART_Transmit 发送错误数据
问题描述
当 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 初始化、传输函数和主函数。我应该是软件问题,已经测试了硬件,没关系。单片机 = 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);
}
}
解决方案
看来这毕竟是一个时钟问题。我正在使用内部 16 MHz 振荡器 (HSI) 乘以 32 MHz 和 PLL。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();
推荐阅读
- python - TensorFlow pycharm 中的 GPU 警告
- c# - 当高度绑定到 StackPanel 时,UserControl 中的文本框正在锁定应用程序
- python - 您如何通过 Flask 中的 Stripe Checkout 流程携带像 userID 这样的变量?
- java - 试图从arraylist打印信息,但我认为我正在获取内存
- javascript - JQuery滑块不与用d3垂直绘制的数据交互
- html - 如何在 CSS 中堆叠表格中仅一行的 TD 元素?
- linear-programming - 如何在 GPL 线性规划 (Gusek) 中将变量绑定为负数?
- javascript - 为什么 CSS 过渡不会在 ReactJS 中正确呈现?
- c# - 从存储库中提取时,Visual Studio 2017 丢失了 WPF 的引用
- express - 摩根与 Express 不记录静态文件