通讯是指不同计算机设备或是集成电路之间需要进行数据传输的方式,而这些传输的一系列方式就是通讯协议。
7.1 通信基础
一次传输位数而言: 串行与并行
同样的情况下,并行传输的成本更高。
数据通讯的方向:全双工,半双工,单工
通讯时数据同步方式:同步和异步通讯
-
同步: 通信双方会使用一条线作为时钟线,双方按照时钟线进行时钟协调,并规定统一的时钟信号(上升沿或下降沿)对数据线进行采样。
-
异步: 异步通信中并不使用时钟信号,而是在数据线中穿插一些校验或是起始位数据。
**传输单位: 比特率(波特率) ** bit/s, 即每秒传输二进制的位数 波特率还表示每秒钟多少个马元(即多少个二进制位数)
总的来说,目前所接触到的STM32相关的通讯均是设备A发送数据到总线,设备B再从总线上进行数据的读取。
7.2 USART——串口通信
USART串口通信的原理(协议层)是什么?
STM32上实现串口通信的步骤是什么?
串口通信算是一种常用通讯方式,也主要常用于调试设备(即可以将机器的相关信息printf打印在电脑上),STM32上的串口通信主要是为异步串口通信。
7.2.2 物理层
即规定该协议具体需要哪种电子标准去进行通信。这里以RS-232标准,以及RS232信号线(带针为公头,带孔为母头)如下,其标准的COM口(也为DB9接口):
目前的串口通信中(USART)中大多数设备只用RXD(接受数据),TXD(发送数据),GND(地线)这三条线。 因为STM32开发板上存在USB转串口的CH340G芯片,因此可直接用USB实现与主机的串口通信。
7.2.3 协议层
即规定USART数据的传输格式,其主要是通过设备发送方的TXD接口传输至设备接受方的RXD接口,该数据格式通常由起始位、数据位(0-7),校验位和停止位组成。
其中每一格虚线代表一个码元,通讯双方需约定好波特率,常见的为4800 9600 115200等。
起始与停止信号
数据包的起始信号由一个逻辑 0 的数据位表示,而数据包的停止信号可由 0.5、1、1.5 或 2 个逻辑 1 的数据位表示,
只要双方约定一致即可。
有效数据
串口进行数据传输的核心内容,通常为约定的 5 6 7或8位
数据校验位
有效数据之后,会跟一个可选的数据校验位,主要用于检验有效数据的完整性。其检验方法为奇校验odd)、偶校验(even)、0 校验(space)、1 校验(mark)以及无校验(noparity)。
- 奇校验odd:数据位和校验位中1的个数为奇数
- 偶校验even:数据位和校验位中1的个数为偶数
- 无校验No
这么一个包含起始信号有效数据,校验位的完整长度的数据称之为一帧数据。
7.3 STM32下的USART的原理
USART的核心实现原理是什么?
USART(Universal Synchronous Asynchronous Receiver and Transmitter) 全称为通用同步异步收发器,其支持使用DMA,可实现高速数据通信。USART在STM32上最多的应用在于打印信息。**其中STM32中USART的核心原理在于USART的功能图,**再根据功能图整体把握后进行编程就会有一定的思路。
总的来说USART核心原理有4大部分构成:
1号区域的功能引脚
- TX:发送数据输出引脚。
- RX:接收数据输入引脚
- SW_RX:数据接收引脚,只用于单线和智能卡模式,属于内部引脚,没有具体外部引脚。
- nRTS:请求以发送,n表示低电平,当USART准备接受新数据时nRTS 变成低电平;当接收寄存器已满时,nRTS 将被设置为高电平。该引脚只适用于硬件流控制。
- nCTS:清除以发送
- SCLK:仅适用于同步模式,发送器时钟的输出引脚
2.数据寄存器
主要是指USART相关的数据寄存器USART_DR,其只有低9为有效。USART_DR又由两大子寄存器构成,一个是发送可写[^71]的TDR,另一个是接受可读的RDR。
3.控制器
用于进行控制管理(中断控制,发送接收控制等)和时钟同步等相关功能。并由一系列相关寄存器构成。
4.波特率生成器
用于调试串口波特率的相关大小,其生成相关都由具体库函数进行完整封装。
7.4 代码实现
主要是实现开发板与计算机之间采用串口进行通讯
STM32开发板与计算机之间的串口通讯有哪几步?
USART产生的中断与GPIO外部断及设置区别是什么?
实现串口通信,第一步是实现串口初始化操作,其初始化又主要分为:初始化GPIO并将其复用到USART上,USART结构体初始化与USART时钟初始化(同步)并使能,(若涉及到串口中断)再中断向量管家的初始化,最后则是发送和接受函数的改写。
-
USART结构体初始化
typedef struct { uint32_t USART_BaudRate; /*波特率*/ uint16_t USART_WordLength; /*每帧数据的长度*/ uint16_t USART_StopBits; /*停止位个数,一般选择为1 */ uint16_t USART_Parity; /*奇偶校验位,USART_Parity_No(无校验) USART_Parity_Even(偶校验) USART_Parity_Odd (奇数校验)*/ uint16_t USART_Mode; /*模式选择即是收还是发,或者收发一起 USART_Mode_Rx | USART_Mode_Tx; */ uint16_t USART_HardwareFlowControl; /*!硬件流控制,硬件流用于防止发接双方波特率不一致而导致数据丢失或是溢出 硬件流控制通过使用额外的信号线,如 RTS(Request to Send)和 CTS(Clear to Send),让接收方告诉发送方何时可以发送或停止发送数据。 USART_HardwareFlowControl_None:不使用硬件流控制。 USART_HardwareFlowControl_RTS:仅启用 RTS。 USART_HardwareFlowControl_CTS:仅启用 CTS。 USART_HardwareFlowControl_RTS_CTS:同时启用 RTS 和 CTS。 */ } USART_InitTypeDef; // 串口中断优先级配置 NVIC_Configuration(); static void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; /* 嵌套向量中断控制器组选择 */ /* 提示 NVIC_PriorityGroupConfig() 在整个工程只需要调用一次来配置优先级分组*/ 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); } // 使能串口接收中断 USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE); // 使能串口 USART_Cmd(DEBUG_USARTx, ENABLE);
-
USART时钟初始化(仅限同步传输下才能使用到)
typedef struct { uint16_t USART_Clock; /*!时钟使能 */ uint16_t USART_CPOL; /*!时钟极性*/ uint16_t USART_CPHA; /*!时钟相位 */ uint16_t USART_LastBit; /*!最尾位时钟脉冲 */ } USART_ClockInitTypeDef;
void USART_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
// 打开串口GPIO的时钟
DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);
// 打开串口外设的时钟
DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);
// 将USART Tx的GPIO配置为推挽复用模式 即输出为复用
GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP