单片机的串口(Serial Port)是一种非常重要且常用的通信接口,下面从基本概念、工作原理、通信协议、应用场景以及使用示例几个方面详细介绍:
基本概念
串口是一种用于在单片机和其他设备(如计算机、传感器、执行器等)之间进行数据传输的接口。它以逐位的方式传输数据,每次只传输一个数据位,具有硬件连接简单、成本低、可靠性高等优点。常见的串口标准有 RS - 232、RS - 485 等。
工作原理
- 数据发送:单片机将要发送的数据按位依次通过串口发送引脚(TXD)输出。在发送之前,数据通常会被存储在发送缓冲区中,然后按照一定的波特率(数据传输速率)逐位发送出去。
- 数据接收:单片机通过串口接收引脚(RXD)逐位接收外部设备发送过来的数据。接收到的数据会先被存储在接收缓冲区中,等待单片机进行处理。
通信协议
- 异步通信:
- 这是单片机串口最常用的通信方式。在异步通信中,数据是一帧一帧地传输的,每帧数据包含起始位、数据位、奇偶校验位(可选)和停止位。
- 起始位:用于表示一帧数据的开始,通常为低电平。
- 数据位:要传输的实际数据,一般为 5 - 8 位。
- 奇偶校验位:用于检测数据传输过程中是否发生错误,分为奇校验和偶校验。
- 停止位:用于表示一帧数据的结束,通常为高电平,位数可以是 1 位、1.5 位或 2 位。
- 同步通信:
- 同步通信需要一个时钟信号来同步发送方和接收方的操作。在同步通信中,数据是连续传输的,没有起始位和停止位,而是通过时钟信号来确定每个数据位的传输时刻。
应用场景
- 调试信息输出:在单片机开发过程中,通过串口将调试信息发送到计算机上,方便开发人员进行调试和故障排查。
- 与外部设备通信:与传感器、执行器、显示器等外部设备进行数据交换,实现数据采集、控制等功能。
- 远程通信:通过串口与其他单片机或设备进行远程通信,实现分布式系统的控制和数据传输。
以下是一个简单的 51 单片机串口通信示例代码,实现了单片机通过串口向计算机发送数据的功能:
- #include
-
- // 初始化串口
- 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
-
- // 初始化串口
- 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)); // 接收数据
- // 可在此处对接收到的数据进行处理
- }
- }
代码解释
- 51 单片机:
UART_Init
函数:设置定时器 1 为模式 2 以产生波特率,配置串口工作模式为模式 1 并允许接收,最后启动定时器 1。UART_SendChar
函数:将字符写入发送缓冲区,等待发送完成标志TI
置位,然后清除该标志。UART_ReceiveChar
函数:等待接收完成标志RI
置位,清除该标志后返回接收到的字符。
- STM32 单片机:
UART_Init
函数:使用 HAL 库配置串口的波特率、数据位、停止位、奇偶校验位等参数,并初始化串口。UART_SendData
函数:调用HAL_UART_Transmit
函数发送指定长度的数据。UART_ReceiveData
函数:调用HAL_UART_Receive
函数接收指定长度的数据。
评论记录:
回复评论: