STM32 USART出现乱码

USART使用串口助手调试时出现乱码的情况,一般都是波特率的问题,例如:向串口发送“hello world\r\n”,但是串口助手收到的数据却是这样:
usart

于是我仔细检查代码中设置的波特率的大小,发现没错,也是设置为115200,但是串口助手上显示的还是乱码。我再仔细检查与USART相关的代码,包括UASRT初始化、中断、以及发送数据的类型。。。,很绝望,还是没有找出这个BUG!
以下是我的UASRT相关设置代码:

void Uart1_Init(void)
{
    //GPIO端口设置
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);        //使能GPIOA的时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);       //使能USART1时钟

  
<think>我们正在处理关于STM32 USART配置和使用的问题。根据引用内容,我们有一些关于中断处理、NVIC优先级分组和启动代码的信息。用户可能想知道如何配置USART,特别是中断配置。 步骤: 1. 配置GPIO:USART需要配置TX和RX引脚为复用推挽输出和浮空输入。 2. 配置USART:设置波特率、数据位、停止位、校验位等。 3. 配置中断(如果需要使用中断方式):使能USART中断,配置NVIC。 4. 编写中断服务函数(ISR):在stm32f10x_it.c中编写中断处理函数。 根据引用[1],中断服务函数的名称是固定的,例如USART1的中断服务函数为`void USART1_IRQHandler(void)`。这个函数需要在stm32f10x_it.c中定义,并且不需要事先声明。 根据引用[2],STM32的中断优先级由NVIC管理,有5种优先级分组方式。我们需要根据需求设置优先级分组,然后为USART中断设置抢占优先级和子优先级。 根据引用[3],启动代码中已经定义了弱(weak)的中断服务函数,如果我们在其他地方(如stm32f10x_it.c)定义了同名的函数,编译器会使用我们定义的函数覆盖弱符号。 下面是一个USART1配置的示例(以STM32F10x系列为例):</think>### STM32 USART 配置与使用指南 #### 一、硬件配置 1. **引脚复用** USART 需要配置 GPIO 为复用模式: - TX 引脚:复用推挽输出(GPIO_Mode_AF_PP) - RX 引脚:浮空输入(GPIO_Mode_IN_FLOATING) ```c GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE); // 配置 PA9 (TX) GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStruct); // 配置 PA10 (RX) GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStruct); ``` 2. **USART 参数配置** 通过 `USART_InitTypeDef` 设置通信参数: ```c USART_InitTypeDef USART_InitStruct; USART_InitStruct.USART_BaudRate = 115200; // 波特率 USART_InitStruct.USART_WordLength = USART_WordLength_8b; // 数据位 USART_InitStruct.USART_StopBits = USART_StopBits_1; // 停止位 USART_InitStruct.USART_Parity = USART_Parity_No; // 校验位 USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 收发模式 USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 硬件流控 USART_Init(USART1, &USART_InitStruct); USART_Cmd(USART1, ENABLE); // 使能USART ``` --- #### 二、中断配置(可选) 1. **NVIC 优先级设置** 根据引用[2],需选择优先级分组(如 Group 2): ```c NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 2位抢占优先级,2位响应优先级 NVIC_InitTypeDef NVIC_InitStruct; NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; // 抢占优先级 NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; // 响应优先级 NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct); ``` 2. **使能USART中断** ```c USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // 使能接收中断 ``` 3. **中断服务函数** 根据引用[1]和[3],需在 `stm32f10x_it.c` 定义中断函数: ```c void USART1_IRQHandler(void) { if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { uint8_t data = USART_ReceiveData(USART1); // 读取数据 // 处理接收数据... } } ``` --- #### 三、数据收发 1. **阻塞式发送** ```c void USART_SendByte(USART_TypeDef* USARTx, uint8_t data) { USART_SendData(USARTx, data); while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET); // 等待发送完成 } ``` 2. **DMA传输(高效方式)** 配置 DMA 自动搬运数据,减少 CPU 负载: ```c DMA_InitTypeDef DMA_InitStruct; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR; DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)tx_buffer; DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralDST; // 内存到外设 DMA_InitStruct.DMA_BufferSize = buffer_size; DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStruct.DMA_Mode = DMA_Mode_Normal; DMA_Init(DMA1_Channel4, &DMA_InitStruct); // USART1_TX 对应 DMA1 Ch4 USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); ``` --- #### 四、常见问题解决 1. **波特率误差过大** 使用公式计算波特率寄存器值: $$ \text{USARTDIV} = \frac{f_{\text{PCLK}}}{16 \times \text{BaudRate}} $$ 确保实际误差 < 3%(推荐使用 115200 等标准波特率)。 2. **中断无法触发** - 检查 NVIC 优先级分组是否冲突(引用[2]) - 确认中断服务函数名正确(如 `USART1_IRQHandler`,引用[1]) - 检查 `stm32f10x_it.c` 是否覆盖弱符号定义(引用[3]) 3. **数据乱码** - 核对双方设备的波特率、数据位、停止位 - 检查 GPIO 时钟和 USART 时钟使能状态 - 使用示波器验证信号质量 ---
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值