一、基础时序单位
UART 通信中,1 个 bit 的电平持续时间由通信波特率(通信速率)决定,单帧数据内的起始位、数据位、停止位,均遵循统一的单 bit 时长,以此保证收发双方的时序同步。
二、总线空闲状态
UART 总线无数据传输时,数据线默认保持高电平状态。
三、起始信号(起始位)
- 起始信号的识别标志:数据线由高电平跳转为低电平,该下降沿是接收端识别数据传输启动的核心信号。
- 起始位固定占用 1 个 bit 的时长,持续 1 个 bit 位宽的低电平。(UART 标准协议中,起始位固定为低电平,以此和空闲高电平状态做明确区分)
四、数据位传输规则
- 传输顺序:采用小端序传输,先传低位,后传高位。
- 图中示例传输的二进制数据为
0b10011101,传输时从最低位(最右侧的 bit 0)开始,依次向高位(bit 7)逐位传输。 - 每个数据位的电平持续时间,与起始位、停止位的单 bit 时长完全一致,由设定的波特率统一管控。
五、停止信号与停止位
- 停止信号的电平特征:数据线由低电平跳转为高电平;若数据位的最后一位本身就是高电平,则数据线直接保持高电平不变。
- 停止信号的核心目的:让数据线在数据传输结束后,恢复并保持空闲时的高电平状态,为下一次数据传输的起始位下降沿做好准备。
- 停止位定义:停止信号后,会持续1~2 个 bit 位宽的高电平,作为本次数据帧传输的结束标志。
六、波特率
指单位时间(1 秒)内通信链路可以传输的码元数量,是衡量通信符号传输速率的核心指标。在 UART 串行通信中,单个码元仅能承载 1 个 bit 的二进制数据,因此 UART 的波特率在数值上等同于单位时间内传输的 bit 数。
七、校验位
| 校验类型 | 计算规则 | 适用场景 |
|---|---|---|
| 奇校验(Odd Parity) | 数据位 + 校验位中,1 的总数为奇数 | 简单场景,能检测出奇数个 bit 错误 |
| 偶校验(Even Parity) | 数据位 + 校验位中,1 的总数为偶数 | 与奇校验类似,同样只能检测奇数个 bit 错误 |
| 无校验(No Parity) | 不添加校验位,传输效率更高 | 工业 / 嵌入式最常用,依赖上层协议做错误处理 |

寄存器配置:
URXD:读取收到的数据
UCR1:使能
UCR2: 忽略RTS
校验使能
停止位
数据长度
发送器/接收器 使能
软件复位
UCR3:接收复用选择(置1)
UFCR:时钟分频
USR2:TXDC/RDR 发送完成状态位,用于判断发送链路是否完全空闲 接收数据就绪状态位,用于判断是否有新数据可读
UBIR/UBMR:设置波特率

模块时钟要*16

uart的初始化
cpp
void uart_init(UART_Type * base)
{
if (base == UART1)
{
IOMUXC_SetPinMux(IOMUXC_UART1_RX_DATA_UART1_RX, 0);
IOMUXC_SetPinMux(IOMUXC_UART1_TX_DATA_UART1_TX, 0);
IOMUXC_SetPinConfig(IOMUXC_UART1_RX_DATA_UART1_RX, 0x10b0);
IOMUXC_SetPinConfig(IOMUXC_UART1_TX_DATA_UART1_TX, 0x10b0);
}
else if(base == UART2)
{
IOMUXC_SetPinMux(IOMUXC_UART2_RX_DATA_UART2_RX, 0);
IOMUXC_SetPinMux(IOMUXC_UART2_TX_DATA_UART2_TX, 0);
IOMUXC_SetPinConfig(IOMUXC_UART2_RX_DATA_UART2_RX, 0x10b0);
IOMUXC_SetPinConfig(IOMUXC_UART2_TX_DATA_UART2_TX, 0x10b0);
}
base->UCR2 &= ~(1 << 0);
delay_us(1);
unsigned int tmp = base->UCR2;
tmp |= (1 << 14);
tmp &= ~(1 << 8);
tmp &= ~(1 << 6);
tmp |= (1 << 5);
tmp |= (1 << 2);
tmp |= (1 << 1);
base->UCR2 = tmp;
base->UCR3 |= (1 << 2);
tmp = base->UFCR;
tmp &= ~(0x7 << 7);
tmp |= (0x5 << 7);
base->UFCR = tmp;
base->UBIR = 999;
base->UBMR = 43404;
base->UCR1 |= (1 << 0);
}
发送
cpp
void uart_send_byte(UART_Type * base, unsigned char data)
{
while(!(base->USR2 & (1 << 3)));
base->UTXD = data;
}
接收
cpp
unsigned char uart_recv_byte(UART_Type * base)
{
unsigned char data = 0;
while(!(base->USR2 & (1 << 0)));
data = base->URXD & 0xff;
return data;
}
发送字符串
cpp
void uart_send_str(UART_Type *base,const char * str)
{
while(*str != '\0')
{
uart_send_byte(base, *str);
str++;
}
}
接收字符串
cpp
void uart_recv_str(UART_Type * base,char *str,int max_len)
{
char ch;
int i = 0;
while(1)
{
ch = uart_recv_byte(base);
if(ch == '\n' || ch == '\r')
{
str[i] = '\0';
break;
}
else if (i < max_len)
{
str[i++] = ch;
}
else
{
str[i] = '\0';
break;
}
}
}