3. 通用同步/异步收发器接口USART
3.1 UART简介
3.2 USART结构及寄存器说明
3.3 USART设计实例
3.3.1 USART基本功能程序设计
3.3.2 与计算机通信程序设计
3.3.3 用printf()实现通行程序设计
3.1 UART简介
- 并行/串行:同步/异步:UART(Universal Asynchronous Receiver/Transmitter)
UART TxD RxD GND
SPI MISO MOSI SCLK NSS GND
I2C SDA SCL GND
USB 5V D+ D- GND
- UART的相关标准规定了接口的机械特性、电气特性和功能特性等,UART的电气特性标准包括RS-232C、RS422、RS423和RS485等,其中RS232C是最常用的串行通信标准
- RS-232C的全称是“数据终端设备(DTE)和数据通信设备(DCE)之间串行二进制数据交换接口技术标准”,其中DTE包括微机、微控制器和打印机等,DCE包括调制解调MODEM、GSM模块和 WiFi模块等
- RS-232C机械特性规定RS-232C使用25针D型连接器,后来简化为9针D型连接器
- RS-232C电气特性采用负逻辑:逻辑“1”的电平低于-3V,逻辑“0”的电平高于+3V,这和TTL的正逻辑(逻辑“1”为高电平,逻辑“0”为低电平)不同,因此通过RS-232C和TTL器件通信时必须进行电平转换
- 目前微控制器的UART接口采用的是TTL正逻辑,和TTL器件连接不需要电平转换。和采用负逻辑的计算机相连时需要进行电平转换,或使用UART-USB转换器连接
- RS-232C功能特性规定各引脚功能
引脚 | 名称 | 功能 | DTE方向 | DCE方向 | 引脚 | 名称 | 功能 | DTE方向 | DCE方向 |
1 | DCD | 载波检测 | 输入 | 输出 | 6 | DSR | 数据设备准备好 | 输入 | 输出 |
2 | RXD | 接收数据 | 输入 | 输出 | 7 | RTS | 请求发送 | 输出 | 输入 |
3 | DCD | 发送数据 | 输出 | 输入 | 8 | CTS | 清除发送 | 输入 | 输出 |
4 | DCD | 载波检测 | 输出 | 输入 | 9 | RI | 振铃指示 | 输入 | 输出 |
5 | GND | 地 |
- 其中最常用的引脚只有3个:
RXD(接收数据)、TXD(发送数据 )和GND(地)
- RS-232C连接
- RS-232C指标:数据速率和数据格式
- 数据速率用波特率表示:1200 2400 4800 9600 19200
- 数据格式包括1个起始位、8-8个数据位、0-1个校验位和1-2个停止位
- 通信双方的数据速率和数据格式必须一致,否则无法实现通信
3.2 USART结构及寄存器说明
- USART由收发数据和收发控制两部分组成
- 收发数据使用双重数据缓冲:收发数据寄存器和收发移位寄存器
- 收发控制包括控制状态寄存器、发送器控制、接收器控制、中断控制和波特率控制等
- USART使用的GPIO引脚
注:(1)括号中的引脚为复用功能重映射引脚
- USART通过7个寄存器进行操作
- USART状态寄存器(SR)
位 | 名称 | 类型 | 复位值 | 说明 |
7 | TXE | 读 | 1 | 发送数据寄存器空(写DR清除) |
6 | TC | 读/写0清除 |
1 | 发送完成 |
5 | RXNE | 读/写0清除 |
0 | 接收数据寄存器不空(读DR清除) |
4 | IDLE | 读 | 0 | 线路空闲 |
3 | ORE | 读 | 0 | 过载错误 |
2 | NE | 读 | 0 | 噪声错误 |
1 | FE | 读 | 0 | 帧错误 |
0 | PE | 读 | 0 | 校验错误 |
- USART控制寄存器1(CR1)
位 | 名称 | 类型 | 复位值 | 说明 |
13 | UE | 读/写 | 0 | UART使能 |
12 | M | 读/写 | 0 | 字长:0-8位,1-9位 |
10 | PCE | 读/写 | 0 | 校验控制使能:0-禁止,1-允许 |
9 | PS | 读/写 | 0 | 校验选择:0-偶校验,1-奇校验 |
7 | TXEIE | 读/写 | 0 | TXE中断使能:0-禁止,1-允许 |
6 | TCIE | 读/写 | 0 | TC中断使能:0-禁止,1-允许 |
5 | RXNEIE | 读/写 | 0 | RXNE中断使能:0-禁止,1-允许 |
3 | TE | 读/写 | 0 | 发送使能:0-禁止,1-允许 |
2 | RE | 读/写 | 0 | 接收使能:0-禁止,1-允许 |
- USART控制寄存器2(CR2)
位 | 名称 | 类型 | 复位值 | 说明 |
13:12 | STOP[1:0] | 读/写 | 00 | 停止位数:00-1位,10-2位 |
11 | CLKEN | 读/写 | 0 | 时钟使能(同步模式使用) |
10 | CPOL | 读/写 | 0 | 时钟极性(同步模式使用) |
9 | CPHA | 读/写 | 0 | 时钟相位(同步模式使用) |
8 | LBCL | 读/写 | 0 | 最后一位时钟脉冲(同步模式使用) |
6 | LBDIE | 读/写 | 0 | LIN间断检测中断使能 |
5 | LBDL | 读/写 | 0 | LIN间断检测长度 |
3:0 | ADD[3:0] | 读/写 | 0000 | 地址(多机通信使用) |
3.3 USART设计实例
3.3.1 USART基本功能程序设计
- USART初始化子程序
//USART1初始化子程序
void Usart1_Init(void)
{
RCC->APB2ENR |= 1<<2; //开启GPIOA时钟
RCC->APB2ENR |= 1<<14; //开启USART1时钟
GPIOA->CRH &= 0xfffff00f;
GPIOA->CRH |= 0x000004b0; //PA.09(TX1)复用推挽输出、PA.10(RX1)浮空输入
USART1->BRR = 0x0045; //8000000/115200=69(0x45)
USART1->CR1 |= 1<<2; //USART接收允许
USART1->CR1 |= 1<<3; //USART发送
USART1->CR1 |= 1<<13; //USART允许
}
- USART发送/接收子程序
//USART1发送子程序
//入口参数:data-发送数据
//出口参数:返回发送数据
char Usart1_Txd(char data)
{
USART1->DR =data; //发送数据
while(!(USART1->SR & 1<<7)); //等待TXE=1(发送数据寄存器空)
return data; //返回发送数据
}
//USART1接收子程序
//出口参数:接收数据(接收成功)/0(接收不成功)
char Usart1_Rxd(void)
{
if(USART1->SR & 1<<8) //RXNE=1(接受数据寄存器不空)
return USART1->DR; //返回接收数据
else
return 0; //返回0
}
3.3.2 与计算机通信程序设计
- USART发送分秒值子程序
//USART发送分秒值子程序
void Txd_Time(void)
{
Usart1_Txd(((min&0xf0)>>4)+0x30); //发送分十位(转化为ASCII码)
Usart1_Txd((min&0x0f)+0x30); //发送分个位(转化为ASCII码)
Usart1_Txd(':'); //发送冒号
Usart1_Txd(((sec&0xf0)>>4)+0x30); //发送秒十位(转化为ASCII码)
Usart1_Txd((sec&0x0f)+0x30); //发送秒个位(转化为ASCII码)
Usart1_Txd(0xd); //发送回车
Usart1_Txd(0xa); //发送换行
}
- USART设置分秒值子程序
//USART设置分秒值子程序
void Rxd_Time(void)
{
if(USART1->SR & 1<<5) //RXNE=1(接收数据寄存器不空)
{
SysTick->CTRL &=-1; //停止定时器
usart1_rxd[rxd_num] - USART1->DR - 0x30; //保存数据
if(++rxd_num == 4)
{
rxd_num =0;
min = (usart1_rxd[0]<<4)+usart1_rxd[1]; //设置分值
sec = (usart1_rxd[2]<<4)+usart1_rxd[3]; //设置秒值
SysTick->CTRL |= 1; //启动定时器
}
}
}
3.3.3用printf()实现通信程序设计
- 用printf()通过USART输出数据除了需要按要求对USART进行初始化操作外,还需要包含stdio.h文件和fpuc()函数
//printf调用函数
int fputc(int ch, FILE *f)
{
return(Usart1_Txd(ch)); //USART1发送并返回数据
}
- Printf()支持的格式字符