单片机:STM32F407
开发板:DMF407电机开发板
平台:keil V5.31
HSE 为8MHZ
HSI为16MHZ
原理图:

串口工具:

主函数:
uint8_t g_usart_tx_buf[8];
int main(void)
{
uint8_t len;
uint16_t times = 0;
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */
delay_init(168); /* 延时初始化 */
usart_init(115200); /* 串口初始化为115200 */
led_init(); /* 初始化LED */
while(1)
{
g_usart_tx_buf[0]=1;
g_usart_tx_buf[1]=2;
g_usart_tx_buf[2]=3;
g_usart_tx_buf[3]=4;
g_usart_tx_buf[4]=5;
g_usart_tx_buf[5]=6;
g_usart_tx_buf[6]=7;
g_usart_tx_buf[7]=8;
HAL_UART_Transmit(&g_uart1_handle, (uint8_t*)g_usart_tx_buf, 8, 1000); /*发送接收到的数据*/
while(__HAL_UART_GET_FLAG(&g_uart1_handle, UART_FLAG_TC) != SET); /*等待发送结束*/
delay_ms(500);
}
}
串口配置:
#define USART_TX_GPIO_PORT GPIOD
#define USART_TX_GPIO_PIN GPIO_PIN_2
#define USART_TX_GPIO_AF GPIO_AF8_UART5
#define USART_TX_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOD_CLK_ENABLE(); }while(0) /* 发送引脚时钟使能 */
#define USART_RX_GPIO_PORT GPIOC
#define USART_RX_GPIO_PIN GPIO_PIN_12
#define USART_RX_GPIO_AF GPIO_AF8_UART5
#define USART_RX_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOC_CLK_ENABLE(); }while(0) /* 接收引脚时钟使能 */
#define USART_UX UART5
#define USART_UX_IRQn UART5_IRQn
#define USART_UX_IRQHandler UART5_IRQHandler
#define USART_UX_CLK_ENABLE() do{ __HAL_RCC_UART5_CLK_ENABLE(); }while(0) /* USART1 时钟使能 */
void usart_init(uint32_t baudrate)
{
g_uart1_handle.Instance = USART_UX; /* USART1 */
g_uart1_handle.Init.BaudRate = baudrate; /* 波特率 */
g_uart1_handle.Init.WordLength = UART_WORDLENGTH_8B; /* 字长为8位数据格式 */
g_uart1_handle.Init.StopBits = UART_STOPBITS_1; /* 一个停止位 */
g_uart1_handle.Init.Parity = UART_PARITY_NONE; /* 无奇偶校验位 */
g_uart1_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE; /* 无硬件流控 */
g_uart1_handle.Init.Mode = UART_MODE_TX_RX; /* 收发模式 */
HAL_UART_Init(&g_uart1_handle); /* HAL_UART_Init()会使能UART1 */
/* 该函数会开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量 */
HAL_UART_Receive_IT(&g_uart1_handle, (uint8_t *)g_rx_buffer, RXBUFFERSIZE);
}
HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
{
/* Check the UART handle allocation */
if (huart == NULL)
{
return HAL_ERROR;
}
/* Check the parameters */
if (huart->Init.HwFlowCtl != UART_HWCONTROL_NONE)
{
/* The hardware flow control is available only for USART1, USART2, USART3 and USART6.
Except for STM32F446xx devices, that is available for USART1, USART2, USART3, USART6, UART4 and UART5.
*/
assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance));
assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
}
else
{
assert_param(IS_UART_INSTANCE(huart->Instance));
}
assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
if (huart->gState == HAL_UART_STATE_RESET)
{
/* Allocate lock resource and initialize it */
huart->Lock = HAL_UNLOCKED;
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
UART_InitCallbacksToDefault(huart);
if (huart->MspInitCallback == NULL)
{
huart->MspInitCallback = HAL_UART_MspInit;
}
/* Init the low level hardware */
huart->MspInitCallback(huart);
#else
/* Init the low level hardware : GPIO, CLOCK */
HAL_UART_MspInit(huart);
#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
}
huart->gState = HAL_UART_STATE_BUSY;
/* Disable the peripheral */
__HAL_UART_DISABLE(huart);
/* Set the UART Communication parameters */
UART_SetConfig(huart);
/* In asynchronous mode, the following bits must be kept cleared:
- LINEN and CLKEN bits in the USART_CR2 register,
- SCEN, HDSEL and IREN bits in the USART_CR3 register.*/
CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
/* Enable the peripheral */
__HAL_UART_ENABLE(huart);
/* Initialize the UART state */
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->gState = HAL_UART_STATE_READY;
huart->RxState = HAL_UART_STATE_READY;
return HAL_OK;
}
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
GPIO_InitTypeDef gpio_init_struct;
if(huart->Instance == USART_UX) /* 如果是串口1,进行串口1 MSP初始化 */
{
USART_UX_CLK_ENABLE(); /* USART1 时钟使能 */
USART_TX_GPIO_CLK_ENABLE(); /* 发送引脚时钟使能 */
USART_RX_GPIO_CLK_ENABLE(); /* 接收引脚时钟使能 */
gpio_init_struct.Pin = USART_TX_GPIO_PIN; /* TX引脚 */
gpio_init_struct.Mode = GPIO_MODE_AF_PP; /* 复用推挽输出 */
gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */
gpio_init_struct.Alternate = USART_TX_GPIO_AF; /* 复用为USART1 */
HAL_GPIO_Init(USART_TX_GPIO_PORT, &gpio_init_struct); /* 初始化发送引脚 */
gpio_init_struct.Pin = USART_RX_GPIO_PIN; /* RX引脚 */
gpio_init_struct.Alternate = USART_RX_GPIO_AF; /* 复用为USART1 */
HAL_GPIO_Init(USART_RX_GPIO_PORT, &gpio_init_struct); /* 初始化接收引脚 */
#if USART_EN_RX
HAL_NVIC_EnableIRQ(USART_UX_IRQn); /* 使能USART1中断通道 */
HAL_NVIC_SetPriority(USART_UX_IRQn, 3, 3); /* 抢占优先级3,子优先级3 */
#endif
}
}
测试结果:

貌似数据移位了。
用另外一个串口工具测试:

测试结果:

两个串口工具的测试结果是一样的。
将串口工具接收脚接到TPT3232E的pin11,接收到的数据正常:
