串口通信
1.1设备之间的通信方式
| 串行通讯 | 并行通讯 |
原理 | 按顺序传输数据 | 数据全部同步发送 |
优点 | 连线少,节约成本 | 传输速度快 |
缺点 | 传输速度慢 | 连线多,成本高 |
1.2串行通信的分类
按通讯方式分:
同步通信:带时钟同步信号传输。比如:SPI,I²C通信接口
异步通信:不带时钟同步信号。比如:UART(通用异步收发器),单总线
常见的串行通信接口:
按照数据传送方向分:
单工:数据传输是单向的。通信双方中,一方固定为发送端,一方则固定为接收端。信息只能沿一个方向传输,使用一根传输线。如下图(a)
半双工:通信使用同一根传输线,既可以发送数据又可以接收数据,但不能同时进行发送和接收。数据传输允许数据在两个方向上传输,但是,在任何时刻只能由其中的一方发送数据,另一方接收数据。因此半双工模式既可以使用一条数据线,也可以使用两条数据线。半双工通信中每端需有一个收发切换电子开关,通过切换来决定数据向哪个方向传输。因为有切换,所以会产生时间延迟,信息传输效率低些。如下图(b)
全双工:通信允许数据同时在两个方向上传输。因此,全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力。在全双工模式中,每一端都有发送器和接收器,有两条传输线,信息传输效率高。
显然,在其它参数都一样的情况下,全双工比半双工传输速度要快,效率要高。如下图(c)
典型的串口通讯标准:
EIA RS232(通常简称“RS232”): 1962年由美国电子工业协会(EIA)制定。
EIA RS485(通常简称“RS485”): 1983年由美国电子工业协会(EIA)制定。
STM32串口通信
STM32F103ZE中,内置了3个通用同步/异步收发器(USART1、USART2和USART3),和2个通用异步收发器(UART4和UART5)。
UART连线方式
1.单片机与单片机连接
- RXD:数据输入引脚,数据接受;
- TXD:数据发送引脚,数据发送。
对于两个芯片之间的连接,两个芯片GND共地,同时TXD和RXD交叉连接。这里的交叉连接的意思就是,芯片1的RxD连接芯片2的TXD,芯片2的RXD连接芯片1的TXD。这样,两个芯片之间就可以进行TTL电平通信了。
2.单片机与上位机连接
若是芯片与PC机(或上位机)相连,除了共地之外,就不能这样直接交叉连接了。尽管PC机和芯片都有TXD和RXD引脚,但是通常PC机(或上位机)通常使用的都是RS232接口(通常为DB9封装),因此不能直接交叉连接。RS232接口是9针(或引脚),通常是TxD和RxD经过电平转换得到的。故,要想使得芯片与PC机的RS232接口直接通信,需要也将芯片的输入输出端口也电平转换成rs232类型,再交叉连接。
经过电平转换后,芯片串口(TTL)和rs232的电平标准是不一样的:
| TTL | RS232 | RS485 |
"1" | 2.4V-5V | -15V-(-3V) | -6V-(-2V) |
"0" | 0V-0.5V | 3V-15V | 2V-6V |
UART异步通信方式引脚
RXD:数据输入引脚。数据接受。
TXD:数据发送引脚。数据发送。
UART异步通信方式特点
全双工异步通信。
分数波特率发生器系统,提供精确的波特率。
发送和接受共用的可编程波特率,最高可达4.5Mbits/s
可编程的数据字长度(8位或者9位);
可配置的停止位(支持1或者2位停止位);
可配置的使用DMA多缓冲器通信。
单独的发送器和接收器使能位。
检测标志:① 接受缓冲器 ②发送缓冲器空 ③传输结束标志
多个带标志的中断源。触发中断。
其他:校验控制,四个错误检测标志。
串口数据收发过程
串口初始化
STM32串口异步通信需要定义的参数
① 起始位
② 数据位(8位或者9位)
③ 奇偶校验位(第9位)
④ 停止位(1,15,2位)
⑤ 波特率设置
STM32初始化代码
void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart1);
}
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(uartHandle->Instance==USART1)
{
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
}
}
串口函数
(1)HAL_UART_Receive
功能:串口接收
例:HAL_UART_Receive(&huart1,Rec,20,0xff);
说明:HAL_UART_Receive(串口号,接收放哪,要接受多少位,延时)
(2)HAL_UART_Transmit
功能:串口发送
例:HAL_UART_Transmit(&huart1,Rec,20,0XFF);
说明:HAL_UART_Receive(串口号,发送什么,要发送多少位,延时)
(3)__HAL_UART_GET_FLAG
功能:检测串口是否处于空闲状态
例:if((__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)!=RESET))
说明:检测到标志位IDLE置1,说明串口收发处于空闲状态,执行IF语句中的代码
(4)__HAL_UART_GET_FLAG
功能:接收到的数据不为空时,标志位置1
例:if((__HAL_UART_GET_FLAG(&huart1,UART_FLAG_RXNE)!=RESET))
说明:检测到标志位RXNE置1,说明接收到的消息不为空,准备接受消息。执行IF语句中的代码
(5)__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE)
功能:开启IDLE串口中断。IDLE(当串口处于空闲状态时,IDLE置1)
(6)__HAL_UART_DISABLE_IT(&huart1,UART_IT_IDLE)
功能:禁用IDLE串口中断。IDLE(当串口处于空闲状态时,IDLE置1)
(7)__HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE)
功能:开启RXNE串口中断。RXNE(当接受的数据不为空时,RXNE置1)
未完待续