单片机想和其他设备建立通信少了你(串口)可不行

单片机的串口(Serial Port)是一种非常重要且常用的通信接口,下面从基本概念、工作原理、通信协议、应用场景以及使用示例几个方面详细介绍:

基本概念

串口是一种用于在单片机和其他设备(如计算机、传感器、执行器等)之间进行数据传输的接口。它以逐位的方式传输数据,每次只传输一个数据位,具有硬件连接简单、成本低、可靠性高等优点。常见的串口标准有 RS – 232、RS – 485 等。

工作原理

  • 数据发送:单片机将要发送的数据按位依次通过串口发送引脚(TXD)输出。在发送之前,数据通常会被存储在发送缓冲区中,然后按照一定的波特率(数据传输速率)逐位发送出去。
  • 数据接收:单片机通过串口接收引脚(RXD)逐位接收外部设备发送过来的数据。接收到的数据会先被存储在接收缓冲区中,等待单片机进行处理。
  • 通信协议

  • 异步通信
  • 这是单片机串口最常用的通信方式。在异步通信中,数据是一帧一帧地传输的,每帧数据包含起始位、数据位、奇偶校验位(可选)和停止位。
  • 起始位:用于表示一帧数据的开始,通常为低电平。
  • 数据位:要传输的实际数据,一般为 5 – 8 位。
  • 奇偶校验位:用于检测数据传输过程中是否发生错误,分为奇校验和偶校验。
  • 停止位:用于表示一帧数据的结束,通常为高电平,位数可以是 1 位、1.5 位或 2 位。
  • 同步通信
  • 同步通信需要一个时钟信号来同步发送方和接收方的操作。在同步通信中,数据是连续传输的,没有起始位和停止位,而是通过时钟信号来确定每个数据位的传输时刻。
  • 应用场景

  • 调试信息输出:在单片机开发过程中,通过串口将调试信息发送到计算机上,方便开发人员进行调试和故障排查。
  • 与外部设备通信:与传感器、执行器、显示器等外部设备进行数据交换,实现数据采集、控制等功能。
  • 远程通信:通过串口与其他单片机或设备进行远程通信,实现分布式系统的控制和数据传输。
  • 以下是一个简单的 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)持续监测外部信号,当检测到起始位后,开始按位接收数据,将接收到的数据暂存于接收缓冲区。接收完成一帧数据后,通过判断停止位来确认数据接收结束,若有奇偶校验位,还会进行校验操作。

    数据收发流程

    发送流程
    1. 初始化串口:设置波特率、数据位、停止位、奇偶校验位等参数。
    2. 准备数据:将需要发送的数据存储到变量或数组中。
    3. 发送数据:将数据逐字节写入发送缓冲区,等待发送完成标志置位。
    4. 循环发送(可选):若有多个数据需要发送,可通过循环重复步骤 3。
    接收流程
    1. 初始化串口:与发送流程的初始化参数保持一致。
    2. 等待接收:不断检测接收缓冲区是否有数据到来。
    3. 读取数据:当接收到数据后,从接收缓冲区读取数据。
    4. 数据处理:对读取到的数据进行相应的处理,如显示、存储、计算等。

    不同单片机串口数据收发示例

    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));  // 接收数据
            // 可在此处对接收到的数据进行处理
        }
    }

    代码解释

  • 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 函数接收指定长度的数据。
  •  

    作者:Multiple-ji

    物联沃分享整理
    物联沃-IOTWORD物联网 » 单片机想和其他设备建立通信少了你(串口)可不行

    发表回复