目录
一. 什么是串口
串口,全称为串行接口(Serial Interface),是一种采用串行通信方式的硬件接口标准,主要用于设备间的简单、低速数据传输。串行接口的特点是逐位顺序发送和接收数据,即一次只传输一个数据位,在一根或者一对传输线上完成双向通信。
二. RS-232
2.1 基本概念
RS-232(Recommended Standard 232)是最初由EIA(Electronic Industries Alliance,电子工业联盟)制定的一种串行通信接口标准。后来改由TIA(Telecommunications Industry Association,电信行业协会)接手管理,并且现在通常被称为EIA/TIA-232或简称RS-232C。这个标准定义了数据终端设备(DTE)如个人计算机与数据通信设备(DCE)如调制解调器之间点对点的串行通信电气特性、信号线功能和协议。
2.2 RS-232电平与CMOS/TTL电平对比
RS-232电平:
- RS-232是串行通信的一种标准,它定义了电气特性而非具体的逻辑电路类型。
- RS-232使用的是非平衡的负逻辑电平,即逻辑“1”(标记为Mark)通常表示-3V至-15V的电压范围,而逻辑“0”(标记为空闲Space)则表示+3V至+15V的电压范围。这个标准设计用于长距离通信,具有较强的抗干扰能力,但需要额外的电平转换芯片(如MAX3232)将TTL/CMOS电平转换为RS-232电平。
TTL(Transistor-Transistor Logic)电平:
- TTL电平常见于集成电路内部或短距离设备间通信。
- 在典型的5V供电系统中,TTL逻辑高电平(逻辑“1”)一般定义为约2.4V至5V之间,逻辑低电平(逻辑“0”)为0V至0.8V左右。对于3.3V供电系统,这些值相应降低。
- TTL电平可以直接连接到兼容的TTL或CMOS输入,无需额外的电平转换。
CMOS(Complementary Metal-Oxide-Semiconductor)电平:
- CMOS电平与TTL电平类似,也是用于集成电路内部和直接连接的设备间的通信。
- CMOS电平可以兼容TTL电平,但是CMOS器件的阈值电压(逻辑切换点)可以根据电源电压和具体器件有所不同,例如,在5V电源下,输入高电平可能被定义为大约3.5V以上,而输入低电平为1.5V以下。
- CMOS逻辑门通常具有更高的噪声容限,这意味着输入信号可以在一定范围内变化而不影响输出状态。
2.3 RS-232接口介绍(DB9)
相互通讯的两个设备间,一个设备发送数据,一个设备接收数据。
一般情况下,发送数据的设备称为DTE,如计算机;接收数据的设备称为DCE,如调制解调器。
以公头为例,有9条信号线,其中,
- RXD:用于接收DCE发来的数据信号,即输入;
- TXD:用于发送DTE的信号,即输出。公头和母头的RXD和TXD应交叉连接;
- GND:用于平衡设备双方的地电位,即共地。
- 其他信号线如DCD、DTR、DSR、RTS、CTS等,使用逻辑1表示有效信号,逻辑0表示无效信号。如DTE端的RTS信号线置1时,是为了告知DCE设备本机已准备好 接收数据,而置0则表示未准备就绪。
三. STM32串口
3.1 usart与uart
UART(通用异步收发器)**是一种用于串行通信的硬件接口,它支持全双工异步通信。在异步通信模式下,UART不依赖于外部时钟信号来同步数据传输;相反,数据传输通过起始位、数据位、奇偶校验位(可选)以及停止位来进行同步。UART主要用于设备间相对较低速率的数据交换,如传感器数据读取、显示屏数据输出等场合。
USART(通用同步异步收发器)**则扩展了UART的功能,除了支持全双工异步通信之外,还能够进行同步通信。在同步通信模式下,USART可以利用一个单独的时钟线(例如SPI-like模式)来精确地同步发送和接收数据,这使得它适用于需要更高数据传输速率和更严格同步要求的应用场景。
尽管两者都能实现全双工通信,允许同时进行发送和接收操作,但USART因其额外的同步通信能力,在某些高速或特定同步通信需求的系统中更为灵活和适用。而在只需要异步通信的情况下,UART和USART在功能上是可以互换的。
3.2 STM32的USART主要特征
全双工异步通信: 全双工通信意味着USART可以在同一时间发送和接收数据,不需要交替进行。在异步通信模式下,USART不依赖于外部时钟信号来同步数据传输,而是使用起始位、数据位、奇偶校验位(可选)和停止位来完成一帧数据的传输。
单线半双工通信: 这种模式下,通信仅在一个方向上发生,或者在同一时间内只能在一个方向上传输数据,然后切换方向。例如,在某些低速或简单的通信协议中,如单总线接口,只有一根数据线用于传输信息。
单独的发送器和接收器使能位: STM32的USART模块通常具有独立的控制位来启用或禁用发送器(TX)和接收器(RX)。通过软件配置这些位,可以灵活地控制USART的发送和接收功能,以便根据需要打开或关闭数据流。
可配置使用DMA的多缓冲器通信: USART支持与DMA控制器结合使用,实现数据的自动传输,无需CPU持续干预。当配置为使用DMA时,USART可以连续地将数据从内存缓冲区发送到串行线或将串行线接收到的数据直接存入内存缓冲区,大大减轻了CPU负担并提高了数据吞吐量。
多个带标志的中断源: USART提供了多种中断源,包括数据准备好发送/接收中断、传输结束中断、数据溢出中断、噪声错误中断、奇偶校验错误中断等。每个中断都有相应的状态标志,一旦发生指定事件,相应标志位置位,并触发中断请求。通过设置和清除这些标志以及相关的中断使能位,开发者能够精细地控制USART响应各种通信事件的方式,提高系统的实时性和可靠性。
3.3 STM32F1/F4/F7的USART框图
3.4 STM32串口的配置
3.4.1 F103为例
void uart_init(u32 bound)
{
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟
//USART1_TX GPIOA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
//USART1_RX GPIOA.10初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
//USART 初始化设置
USART_InitStructure.USART_BaudRate = bound;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART1, &USART_InitStructure); //初始化串口1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
USART_Cmd(USART1, ENABLE); //使能串口1
}
void USART1_IRQHandler(void) //串口1中断服务程序
{
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断
{
}
}
3.4.2 F407为例
void usart1_init(uint32_t baud)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //串口1硬件时钟的使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //端口A硬件时钟的使能
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;//配置PA9 PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出,增强驱动能力
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //引脚速度为100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //无内部上拉电阻
GPIO_Init(GPIOA,&GPIO_InitStructure);
//将PA9和PA10连接到串口1的硬件
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9, GPIO_AF_USART1);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
USART_InitStructure.USART_BaudRate = baud; //波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位(8位)
USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位(1位)
USART_InitStructure.USART_Parity = USART_Parity_No; //不校验
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //模式为(发送与接收)
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //不流控(流量控制)
USART_Init(USART1,&USART_InitStructure); //初始化串口1
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //USART1通道
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //打开中断通道
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应优先级
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级
NVIC_Init(&NVIC_InitStructure);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //USART1中断使能(收到一个字节就触发中断)
USART_Cmd(USART1,ENABLE); //启动串口1
}
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1,USART_IT_RXNE) == SET)//中断被触发
{
}
}