嵌入式:Uart模块
1.UART参数设置
基本参数
-Baud Rate (波特率): 配置 UART 的通信速率,以⽐特每秒(bps)为单位。常⻅值有9600、115200等。
-Word Length (字⻓): 设置每个数据帧的位数。常⻅设置包括 8 位和 9 位。
-Parity (奇偶校验): 配置奇偶校验。选项包括 None(⽆)、Even(偶校验)和 Odd(奇校验)。
-Stop Bits (停⽌位): 设置每个数据帧的停⽌位数。选项包括 1 位、1.5位和 2 位。
-Mode (模式): 配置 UART 的⼯作模式,包括 Tx(发送)、Rx(接收)或 Tx Rx(收发)。
-Hardware Flow Control (硬件流控制): 配置硬件流控制选项。选项包括 None(⽆)、RTS、CTS 和 RTS/CTS。
高级参数
-Over Sampling (过采样): 配置过采样⽐例,常⻅值有 16 和 8。
-One Bit Sampling (单⽐特采样): 启⽤或禁⽤单⽐特采样模式。
-Auto BaudRate (⾃动波特率): 启⽤或禁⽤⾃动波特率检测。
-Receiver Time Out (接收超时): 配置接收超时功能,防⽌⻓时间等待数据。
-Lin Mode (LIN 模式): 启⽤或禁⽤ LIN(本地互联⽹络)模式。
2.GPIO设置
在 GPIO 设置选项卡中,可以为 UART 配置相应的引脚:
-Pin Configuration (引脚配置): 选择⽤于 UART Tx 和 Rx 的引脚,并配置其模式(如复⽤功能)。
-Pin Type (引脚类型): 配置引脚的输⼊类型(如浮空输⼊、上拉输⼊等)。
3.NVIC设置
NVIC(嵌套向量中断控制器)设置⽤于配置 UART 中断优先级:
-Preemption Priority (抢占优先级): 设置 UART 中断的抢占优先级。
-Sub Priority (⼦优先级): 设置 UART 中断的⼦优先级。
4.DMA设置
DMA(直接内存访问)设置⽤于配置 UART 的 DMA 功能:
-DMA Requests (DMA 请 求 ): 选 择 对 应 的 UART DMA 请 求 ( 如 UART_TX 、UART_RX)。
-DMA Channel (DMA 通道): 分配 DMA 通道⽤于 UART 数据传输。
-DMA Mode (DMA 模式): 配置 DMA 的⼯作模式,如正常模式、循环模式等。
CUBEMX配置
打开cubemx,我们使用的是usart1,点进USART1进行配置,先把模式设为Asynchronous,波特率改为9600
然后把串口接收中断打开
接着配置DMA,点击DMA Settings,点击Add,在选择USART_RX
把这里改成High高速
Keil配置
CubeMX生成代码后,点击魔术棒,将Micro勾选(一定要勾选,出现的大部分问题都是因为没有勾选这个)
底层代码
#include "string.h"
typedef struct _ FILE FILE;
#include "bsp_system.h"
打开usart.c底层代码,在里面添加这两行,因为串口发送使用的是重定向的发送,所以我们要引用第一行格式化的底层库,而第二行不引用则会报错
int fputc(int ch, FILE * str)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 10);//这个是串口发送HAL库的api
return ch;
}
将这段重定向的代码复制进去,以后无论在哪个工程都可以直接复制进去用,要改的只有huart1,改为自己使用的句柄
uint16_t uart_rx_index = 0;//接收缓存索引
uint32_t uart_rx_ticks = 0;//接收缓存时间戳,用于超时解析
uint8_t uart_rx_buffer[128] = {0};//接收缓存
定义三个后面会使用的变量
HAL_UART_Receive_IT(&huart1,uart_rx_buffer,1);
在初始化函数MX_USART1_UART_Init中添加这行代码,串口的接收中断,传入的第一个是串口的句柄,第二个是放入哪个数组,第三个是每次放入多少个。接收到1个字符就触发一次中断,然后把字符放入数组里
逻辑层代码
extern uint16_t uart_rx_index;//接收缓存索引
extern uint32_t uart_rx_ticks;//接收缓存时间戳
extern uint8_t uart_rx_buffer[128];//接收缓存
在编写逻辑层代码之前,先在bsp_system.h中声明之前定义的变量,以便在逻辑层使用它们
#include "uart_app.h"
#include "usart.h"
#include "string.h"
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//接收到一次数据就会调用这个回调函数
{
if (huart->Instance == USART1)//判断句柄,即通过哪个串口传进来的
{
uart_rx_ticks = uwTick;//进来后更新时间
uart_rx_index++;
HAL_UART_Receive_IT(&huart1, &uart_rx_buffer[uart_rx_index], 1);
}
}
//超时解析部分
/**
* @brief 处理UART接收缓冲区中的数据。
* 如果在100ms内没有接收到新的数据,将清空缓冲区。
* @param None
* @retval None
*/
// 处理UART接收缓冲区中的数据
void uart_proc(void)
{
// 如果接收索引为0,说明没有数据需要处理,直接返回
if(uart_rx_index == 0) return;
// // 如果从最后一次接收到数据到现在已经超过100ms
if(uwTick - uart_rx_ticks > 100) // 100ms内没有收到新的数据
{
printf("uart data: %s\n", uart_rx_buffer);
// 清空接收缓冲区,将接收索引置零
memset(uart_rx_buffer, 0, uart_rx_index);
uart_rx_index = 0;
// 将UART接收缓冲区指针重置为接收缓冲区的起始位置
huart1.pRxBuffPtr = uart_rx_buffer;
}
}
rt_rx_buffer, 0, uart_rx_index);
uart_rx_index = 0;
// 将UART接收缓冲区指针重置为接收缓冲区的起始位置
huart1.pRxBuffPtr = uart_rx_buffer;
}
}