关于模式的选择
| 模式 | 数据形式 | 你发什么 | 用途 |
|---|---|---|---|
| RawData | 原始字节 | 任意文本/十六进制 | 调试、日志、自己写协议 |
| FireWater | 文本协议 | 名字:数值\n | 人类可读、低速率绘图 |
| JustFloat | 二进制协议 | float 数组 + 帧尾 | 高速、多通道、省带宽 |
| 场景 | 选择 |
|---|---|
| 打印调试信息、回显 | RawData |
| 少量通道、要看数值 | FireWater |
| 高速采样(ADC/波形) | JustFloat |
| 自己定义协议 | RawData + 自己解析 |
关于中文编码
printf回显
int fputc(int ch,FILE * f) { HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,1000); return ch; }发送字符串
char msg[] = "helloworld"; HAL_UART_Transmit(&huart1,(uint8_t *)msg,strlen(msg),HAL_MAX_DELAY); HAL_Delay(1000);空闲中断接收不定长数据
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart,uint16_t Size) { if(huart->Instance == USART1) { HAL_UART_Transmit_IT(&huart1,rxBuf,Size); HAL_UARTEx_ReceiveToIdle_IT(&huart1,rxBuf,LENGTH); } }DMA串口传输
dma适合传输高速,大量的数据。串口,adc的连续采样,spi的屏幕刷图都适用
其本质是为了绕开cpu。快速进行数据传输
HAL_UARTEx_ReceiveToIdle_DMA(&huart1,rxBuf,LENGTH); printf("已开启接收中断,等待数据发送\r\n"); void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart,uint16_t Size) { if(huart->Instance == USART1) { printf("\r\n已接收到不定长数据,数据长度为:%d字节,数据如下: ",Size); HAL_UART_Transmit_DMA(&huart1,rxBuf,Size); HAL_UARTEx_ReceiveToIdle_DMA(&huart1,rxBuf,LENGTH); } }关于uart的结构体
UART_HandleTypeDef是 HAL 给每个串口配的**“控制块”**,里面记录:用哪个硬件、怎么配、当前在干什么。
| 成员 | 类型 | 作用 |
|---|---|---|
Instance | USART_TypeDef * | 硬件寄存器基址(USART1) |
Init | UART_InitTypeDef | 通信参数(波特率/数据位/停止位/校验…) |
pTxBuffPtr | const uint8_t * | 当前发送缓冲区指针 |
TxXferSize | uint16_t | 本次要发多少字节 |
TxXferCount | __IO uint16_t | 还剩多少字节没发 |
pRxBuffPtr | uint8_t * | 当前接收缓冲区指针 |
RxXferSize | uint16_t | 本次要收多少字节 |
RxXferCount | __IO uint16_t | 还剩多少字节没收 |
ReceptionType | 枚举 | 标准接收 / 空闲接收(TOIDLE) |
RxEventType | 枚举 | 这次回调是 IDLE、半传输还是完成 |
hdmatx | DMA_HandleTypeDef * | 发送用的 DMA 句柄 |
hdmarx | DMA_HandleTypeDef * | 接收用的 DMA 句柄 |
Lock | HAL_LockTypeDef | 互斥锁(防止重入) |
gState | 枚举 | 全局/发送状态(READY/BUSY_TX…) |
RxState | 枚举 | 接收状态(READY/BUSY_RX…) |
ErrorCode | uint32_t | 错误码(PE/FE/NE/ORE…) |