单片机想和其他设备建立通信少了你(串口)可不行
单片机的串口(Serial Port)是一种非常重要且常用的通信接口,下面从基本概念、工作原理、通信协议、应用场景以及使用示例几个方面详细介绍:
基本概念
串口是一种用于在单片机和其他设备(如计算机、传感器、执行器等)之间进行数据传输的接口。它以逐位的方式传输数据,每次只传输一个数据位,具有硬件连接简单、成本低、可靠性高等优点。常见的串口标准有 RS – 232、RS – 485 等。
工作原理

通信协议
应用场景
以下是一个简单的 51 单片机串口通信示例代码,实现了单片机通过串口向计算机发送数据的功能:
#include <reg51.h>
// 初始化串口
void UART_Init() {
TMOD |= 0x20; // 设置定时器 1 为模式 2
TH1 = 0xFD; // 设置波特率为 9600
TL1 = 0xFD;
SCON = 0x50; // 设置串口为模式 1,允许接收
TR1 = 1; // 启动定时器 1
}
// 发送一个字符
void UART_SendChar(char c) {
SBUF = c; // 将字符写入发送缓冲区
while (!TI); // 等待发送完成
TI = 0; // 清除发送完成标志
}
// 发送字符串
void UART_SendString(char *str) {
while (*str) {
UART_SendChar(*str++);
}
}
void main() {
UART_Init(); // 初始化串口
while (1) {
UART_SendString("Hello, World!\r\n"); // 发送字符串
for (int i = 0; i < 10000; i++); // 延时
}
}
串口数据收发的模式
以下为你详细介绍单片机串口数据的收发相关内容,包括原理、流程以及不同单片机的代码示例。
原理
数据发送
单片机将待发送的数据存储在发送缓冲区,按照设定的波特率(每秒传输的比特数),把数据逐位从发送引脚(TXD)输出。发送前会添加起始位,数据传输结束后添加停止位,部分情况还会加入奇偶校验位来保证数据传输的准确性。
数据接收
接收引脚(RXD)持续监测外部信号,当检测到起始位后,开始按位接收数据,将接收到的数据暂存于接收缓冲区。接收完成一帧数据后,通过判断停止位来确认数据接收结束,若有奇偶校验位,还会进行校验操作。
数据收发流程
发送流程
- 初始化串口:设置波特率、数据位、停止位、奇偶校验位等参数。
- 准备数据:将需要发送的数据存储到变量或数组中。
- 发送数据:将数据逐字节写入发送缓冲区,等待发送完成标志置位。
- 循环发送(可选):若有多个数据需要发送,可通过循环重复步骤 3。
接收流程
- 初始化串口:与发送流程的初始化参数保持一致。
- 等待接收:不断检测接收缓冲区是否有数据到来。
- 读取数据:当接收到数据后,从接收缓冲区读取数据。
- 数据处理:对读取到的数据进行相应的处理,如显示、存储、计算等。
不同单片机串口数据收发示例
51单片机
#include <reg51.h>
// 初始化串口
void UART_Init() {
TMOD |= 0x20; // 设置定时器 1 为模式 2
TH1 = 0xFD; // 设置波特率为 9600
TL1 = 0xFD;
SCON = 0x50; // 设置串口为模式 1,允许接收
TR1 = 1; // 启动定时器 1
}
// 发送一个字符
void UART_SendChar(char c) {
SBUF = c; // 将字符写入发送缓冲区
while (!TI); // 等待发送完成
TI = 0; // 清除发送完成标志
}
// 接收一个字符
char UART_ReceiveChar() {
while (!RI); // 等待接收完成
RI = 0; // 清除接收完成标志
return SBUF; // 返回接收到的字符
}
void main() {
char receivedChar;
UART_Init(); // 初始化串口
while (1) {
UART_SendChar('A'); // 发送字符 'A'
receivedChar = UART_ReceiveChar(); // 接收字符
// 可在此处对接收到的字符进行处理
}
}
32单片机 基于hal库
#include "stm32f1xx_hal.h"
UART_HandleTypeDef huart1;
// 串口初始化
void UART_Init() {
huart1.Instance = USART1;
huart1.Init.BaudRate = 9600;
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;
if (HAL_UART_Init(&huart1) != HAL_OK) {
Error_Handler();
}
}
// 发送数据
void UART_SendData(uint8_t *pData, uint16_t Size) {
HAL_UART_Transmit(&huart1, pData, Size, HAL_MAX_DELAY);
}
// 接收数据
void UART_ReceiveData(uint8_t *pData, uint16_t Size) {
HAL_UART_Receive(&huart1, pData, Size, HAL_MAX_DELAY);
}
int main(void) {
HAL_Init();
UART_Init();
uint8_t sendData[] = "Hello, STM32!";
uint8_t receiveData[20];
while (1) {
UART_SendData(sendData, sizeof(sendData)); // 发送数据
UART_ReceiveData(receiveData, sizeof(receiveData)); // 接收数据
// 可在此处对接收到的数据进行处理
}
}
代码解释
UART_Init
函数:设置定时器 1 为模式 2 以产生波特率,配置串口工作模式为模式 1 并允许接收,最后启动定时器 1。UART_SendChar
函数:将字符写入发送缓冲区,等待发送完成标志 TI
置位,然后清除该标志。UART_ReceiveChar
函数:等待接收完成标志 RI
置位,清除该标志后返回接收到的字符。UART_Init
函数:使用 HAL 库配置串口的波特率、数据位、停止位、奇偶校验位等参数,并初始化串口。UART_SendData
函数:调用 HAL_UART_Transmit
函数发送指定长度的数据。UART_ReceiveData
函数:调用 HAL_UART_Receive
函数接收指定长度的数据。
作者:Multiple-ji