# STM32串口通信

1 什么是串口通讯?

    串行通讯是指仅用一根接收线和一根发送线就能将数据以位进行传输的一种通讯方式。尽管串行通讯的比按字节传输的并行通信慢,但是串口可以在仅仅使用两根线的情况下就能实现数据的传输。

    典型的串口通信使用3根线完成,分别是地线、发送、接收。由于串口通信是异步的,所以端口能够在一根线上发送数据同时在另一根线上接收数据。串口通信最重要的参数是波特率、数据位、停止位和奇偶的校验。对于两个需要进行串口通信的端口,这些参数必须匹配,这也是能够实现串口通讯的前提。如下是串行通讯示数据传输意图。

嵌入式分享合集31-串口_串口通讯

2 串口通讯的通讯协议

    最初数据是模拟信号输出简单过程量,后来仪表接口出现了RS232接口,这种接口可以实现点对点的通信方式,但这种方式不能实现联网功能,这就促生了RS485。

    我们知道串口通信的数据传输都是0和1,在单总线、I2C、UART中都是通过一根线的高低电平来判断逻辑1或者逻辑0,但这种信号线的GND再与其他设备形成共地模式的通信,这种共地模式传输容易产生干扰,并且抗干扰性能也比较弱。所以差分通信、支持多机通信、抗干扰强的RS485就被广泛的使用了。

    RS485通信最大特点就是传输速度可以达到10Mb/s以上,传输距离可以达到3000米左右。大家需要注意的是虽然485最大速度和最大传输距离都很大,但是传输的速度是会随距离的增加而变慢的,所以两者是不可以兼得的。

3 串口通讯的物理层

    串口通讯的物理层有很多标准,例如上面提到的,我们主要讲解RS-232标准,RS-232标准主要规定了信号的用途、通讯接口以及信号的电平标准。

嵌入式分享合集31-串口_串口通讯_02

    在上面的通讯方式中,两个通讯设备的"DB9接口"之间通过串口信号线建立起连接,串口信号线中使用"RS-232标准"传输数据信号。由于RS-232电平标准的信号不能直接被控制器直接识别,所以这些信号会经过一个"电平转换芯片"转换成控制器能识别的"TTL校准"的电平信号,才能实现通讯。

    下图为DB9标准串口通讯接:

嵌入式分享合集31-串口_嵌入式硬件_03

   DB9引脚说明:

嵌入式分享合集31-串口_数据_04

    上表中的是计算机端的DB9公头标准接法,由于两个通讯设备之间的收发信号(RXD与TXD)应交叉相连,所以调制调解器端的DB9母头的收发信号接法一般与公头的相反,两个设备之间连接时,只要使用"直通型"的串口线连接起来即可。

嵌入式分享合集31-串口_单片机_05

  串口线中的RTS、CTS、DSR、DTR及DCD信号,使用逻辑 1表示信号有效,逻辑0表示信号无效。例如,当计算机端控制DTR信号线表示为逻辑1时,它是为了告知远端的调制调解器,本机已准备好接收数据,0则表示还没准备就绪。

4 波特率

    波特率是指数据信号对载波的调制速率,它用单位时间内载波调制状态改变的次数来表示。

嵌入式分享合集31-串口_串口_06

    比如波特率为9600bps;代表的就是每秒中传输9600bit,也就是相当于每一秒中划分成了9600等份。

    因此,那么每1bit的时间就是1/9600秒=104.1666...us。约0.1ms。既然是9600等份,即每1bit紧接着下一个比特,不存在额外的间隔。两台设备要想实现串口通讯,这收发端设置的波特率必须相同,否则是没办法实现通讯的

    收发波特率一致可以实现通讯:

    收发波特率不一致,导致RX端不能正常接收:

5 串口通讯的数据结构

嵌入式分享合集31-串口_串口_07

起始位: 起始位必须是持续一个比特时间的逻辑0电平,标志传输一个字符的开始,接收方可用起始位使自己的接收时钟与发送方的数据同步。

    数据位: 数据位紧跟在起始位之后,是通信中的真正有效信息。数据位的位数可以由通信双方共同约定。传输数据时先传送字符的低位,后传送字符的高位。

    奇偶校验位: 奇偶校验位仅占一位,用于进行奇校验或偶校验,奇偶检验位不是必须有的。如果是奇校验,需要保证传输的数据总共有奇数个逻辑高位;如果是偶校验,需要保证传输的数据总共有偶数个逻辑高位。

    停止位: 停止位可以是是1位、1.5位或2位,可以由软件设定。它一定是逻辑1电平,标志着传输一个字符的结束。

    空闲位: 空闲位是指从一个字符的停止位结束到下一个字符的起始位开始,表示线路处于空闲状态,必须由高电平来填充。

6 单双工通讯

    单工: 数据传输只支持数据在一个方向上传输;

    半双工: 允许数据在两个方向上传输,但某一时刻只允许数据在一个方向上传输,实际上是一种切换方向的单工通信,不需要独立的接收端和发送端,两者可合并为一个端口;

    全双工: 允许数据同时在两个方向上传输,因此全双工通信是两个单工方式的结合,需要独立的接收端和发送端。

嵌入式分享合集31-串口_串口_08

7 STM32中的串口通讯

    STM32串口通信接口有两种,分别是:UART(通用异步收发器)、USART(通用同步异步收发器),对于大容量STM32F10x系列芯片,分别由3个USART和两个UART。

嵌入式分享合集31-串口_串口_09

  TXD:数据发送引脚;

    RXD:数据输入引脚

    对于两芯片的间的连接,两个芯片GND共地,同时TXD和RXD交叉连接,这样两个芯片间可进行TTL电平通信。

    但如果对于芯片和PC机相连,除了共地条件外,不能使用如上的直接交叉连接,虽然两者都有TXD和RXD引脚,但通常PC机使用的是RS232接口(9针),通常是TXC和RXD经过电平转换得到,故如果要使芯片与PC机的RS232接口直接通信,需要将芯片的输入输出端口也电平转换为RS232类型,再交叉连接。

    二者的电平标准不同:

  • 单片机的点评标准(TTL电平):+5V表示1,0V表示0;
  • RS232电平标准:+15/+13V表示0,-15/-13表示1。

嵌入式分享合集31-串口_嵌入式硬件_10

 因此单片机与PC机进行串口通信应该遵循:在单片机串口与上位机给出的RS232口之间,通过电平转换电路实现TTL电平与RS232电平间的转换。

    如果使用USB转串口也可以实现串口通讯,USB转串口电路图如下所示。

嵌入式分享合集31-串口_数据_11

   STM32中串口通讯已经给大家建好了相应的库函数,大家在使用和配置串口的时候直接进行调用库函数和配置就行了

    请大家参照一下代码:

1、初始化结构体代码

typedef struct {
 uint32_t USART_BaudRate; // 波特率
 uint16_t USART_WordLength; // 字长
 uint16_t USART_StopBits; // 停止位
 uint16_t USART_Parity; // 校验位
 uint16_t USART_Mode; // USART 模式
 uint16_t USART_HardwareFlowControl; // 硬件流控制
 } USART_InitTypeDef;
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

2、NVIC配置中断优先级

NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;

  /* 嵌套向量中断控制器组选择 */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

  /* 配置USART为中断源 */
  NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;
  /* 抢断优先级*/
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  /* 子优先级 */
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  /* 使能中断 */
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  /* 初始化配置NVIC */
  NVIC_Init(&NVIC_InitStructure);
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

3、USART配置函数

void DEBUG_USART_Config(void)
{
 GPIO_InitTypeDef GPIO_InitStructure;
 USART_InitTypeDef USART_InitStructure;

 /* 第一步:初始化GPIO */
  // 打开串口GPIO的时钟
 DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);
  // 将USART Tx的GPIO配置为推挽复用模式
 GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);

  // 将USART Rx的GPIO配置为浮空输入模式
 GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
 GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure); 

 /* 第二步:配置串口的初始化结构体 */
  // 打开串口外设的时钟
 DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);
 // 配置串口的工作参数
 // 配置波特率
 USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE;
 // 配置 针数据字长
 USART_InitStructure.USART_WordLength = USART_WordLength_8b;
 // 配置停止位
 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(DEBUG_USARTx, &USART_InitStructure);

/*--------------------------------------------------------*/
 // 串口中断优先级配置
 NVIC_Configuration();

 // 使能串口接收中断
 USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE);
/*--------------------------------------------------------*/

 /* 第三步:使能串口 */ 
  // 使能串口
 USART_Cmd(DEBUG_USARTx, ENABLE); 
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.


# UART与COM接口

简单的讲UART

    嵌入式里面说的串口,一般是指UART(Universal Asynchronous Receiver Transmitter:通用异步收发器)。

    但是我们经常搞不清楚它和COM口的区别,以及RS232与TTL等关系。

    实际上UART、COM指的是硬件物理接口形式,而TTL、RS-232是指的电平标准。

    UART有VCC、GND、RX、TX这4个Pin,如下图所示。

    用的TTL电平,  低电平(0V)为0,高电平(3.3V)为1。

嵌入式分享合集31-串口_串口_12

COM口也就是DB9接头,是我们台式机上面常用的口,如下图。现在家用PC上基本上见不到这个接口了,如果确有需求,可以用USB转串口的方式来替代。

    DB9接头有9个Pin, 用的RS232电平,  它是负逻辑电平,它定义+5~+12V为低电平,而-12~-5V为高电平。

嵌入式分享合集31-串口_数据_13

详细的说

UART的特征

    一般UART控制器在嵌入式系统里面都跟在CPU一起,像STM32芯片就是这样,有多个UART控制器。相关案例: STM32与51单片机串口通信实例

    引脚介绍,COM口的Pin虽多,但是常用的也是这几个:

  • VCC:供电Pin,一般是3.3V
  • GND:接地Pin,如果RX接收数据有问题,就要接上这个Pin
  • RX:接收数据Pin
  • TX:发送数据Pin

    在调试的时候,多数情况下我们只引出即可。比如调试GPS模块,IC数据直接通过UART上传,直接用了两个线连出了RX、TX,连上串口转USB小板,  电脑从串口直接获取数据,这样跳过了开发板,测试了GPS的数据有没有问题。

使用方法

    我们常用UART口进行调试,但是UART的数据要传到电脑上分析就要匹配电脑的接口。通常我们电脑使用接口有COM接和USB接口,但是要想连上这两种接口都要需要进行硬件接口转换和电平转换。

    如果连接电脑COM口, 需要一个类似下图的转换小板, 它实现了TTL电平和RS232电平互转, 我之前使用过, 但是现在很少用了。

 如果要连接USB接口, 需要类似下面的小板, 它实现了TTL电平和USB电平的转换, 这种使用的较多。

    电路图和连接如下, 通常上面有个专门转换芯片。

嵌入式分享合集31-串口_嵌入式硬件_14

总结

  • 串口、COM口是指的硬件接口形式
  • TTL、RS-232、RS-485是指的高低电平判定标准
  • 接设备的时候,一般只接GND、RX、TX,以避免与目标设备上的供电冲突
  • PL2303、CP2102芯片是USB转TTL串口的芯片,用USB来扩展串口
  • MAX232芯片是 TTL电平与RS232电平的专用双向转换芯片,可以TTL转RS-232,也可以RS-232转TTL
  • TTL标准是低电平为0,高电平为1(+5V电平)
  • RS-232标准是正电平为0,负电平为1(±15V电平)
# UART

UART——通用异步收发传输器,UART 作为异步串口通信协议的一种,工作原理是将传输数据的每个字符一位接一位地传输。在应用程序开发过程中使用频率较高的数据总线。

基于UART的数据传输是异步形式的串行数据传输。基于UART的串行数据传输不需要使用时钟信号来同步传输的发送端和接收端,而是依赖于发送设备和接收设备之间预定义的配置。

对于发送设备和接收设备来说,两者的串行通信配置(波特率、单位字的位数、奇偶校验、起始位数与结束位、流量控制)应该设置为完全相同。通过在数据流中插入特定的比特序列,可以指示通信的开始与结束。当发送一个字节数据的时候,需要在比特流的开头加上起始位,并在比特流的末尾加上结束位。数据字节的最低位紧接在起始位之后。

UART 串口的特点是将数据一位一位地顺序传送,只要2 根传输线就可以实现双向通信,一根线发送数据的同时用另一根线接收数据。

UART 串口通信有几个重要的参数,分别是波特率、起始位、数据位、停止位和奇偶检验位,对于两个使用UART 串口通信的端口,这些参数必须匹配,否则通

嵌入式分享合集31-串口_串口_15

  • 起始位:表示数据传输的开始,电平逻辑为“0” 。
  • 数据位:可能值有5、6、7、8、9,表示传输这几个bit 位数据。一般取值为8,因为一个ASCII 字符值为8 位。
  • 奇偶校验位:用于接收方对接收到的数据进行校验,校验“1” 的位数为偶数(偶校验) 或奇数(奇校验),以此来校验数据传送的正确性,使用时不需要此位也可以。
  • 停止位:表示一帧数据的结束。电平逻辑为“1”。
  • 波特率:串口通信时的速率,它用单位时间内传输的二进制代码的有效位(bit) 数来表示,其单位为每秒比特数bit/s(bps)。常见的波特率值有4800、9600、14400、38400、115200 等,数值越大数据传输的越快,波特率为115200 表示每秒钟传输115200 位数据。