单片机串口通信实现详解:完整源码指南

单片机实现串口通信项目详解

作者:Katie
日期:2025-03-31


目录

  1. 项目背景与简介

  2. 串口通信工作原理
    2.1 基本概念
    2.2 常用参数与数据格式

  3. 系统设计方案
    3.1 项目需求与功能描述
    3.2 系统整体架构

  4. 硬件电路设计
    4.1 串口通信接口连接
    4.2 供电与接口说明

  5. 软件实现方案
    5.1 串口初始化与配置
    5.2 数据发送与接收
    5.3 调试与错误处理

  6. 详细代码实现
    6.1 整合代码及详细注释

  7. 代码解读与测试结果

  8. 项目总结与体会

  9. 扩展阅读与参考资料


1. 项目背景与简介

串口通信(UART通信)是最常用的嵌入式通信方式之一,具有简单、低成本、易于实现等优点。单片机通过串口通信可以与PC、其他单片机或外部模块进行数据交换,广泛应用于数据调试、设备配置以及实时数据传输等场合。本项目将详细介绍如何利用单片机实现串口通信,包括串口初始化、数据发送与接收等关键技术,为嵌入式系统开发提供一个基础参考案例。


2. 串口通信工作原理

2.1 基本概念

串口通信即UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器)通信。它通过两个基本信号线:

  • TX(发送端):单片机将数据通过TX口发送出去。

  • RX(接收端):单片机从RX口接收外部传来的数据。

  • 串口通信通常无需时钟线,而是通过预先设定的波特率来约定数据传输速率。常见的波特率有9600、115200等。

    2.2 常用参数与数据格式

  • 波特率:定义每秒传输的比特数,如115200 bps。

  • 数据位:一般为8位数据。

  • 停止位:通常为1位或2位。

  • 校验位:常见无校验、奇校验或偶校验。

  • 传输格式:数据以起始位、数据位、停止位(和校验位)构成一个完整的数据帧。


  • 3. 系统设计方案

    3.1 项目需求与功能描述

    本项目需求:

  • 利用单片机实现UART串口通信;

  • 支持基本的数据发送和接收功能;

  • 通过USART调试接口输出调试信息,验证数据传输效果;

  • 可扩展为与PC、其他模块进行通信。

  • 3.2 系统整体架构

    系统整体架构主要包括:

  • 串口初始化模块:配置单片机USART寄存器,设定波特率、数据格式、停止位等;

  • 数据发送模块:封装发送函数,实现逐字符发送数据到外部设备;

  • 数据接收模块:利用轮询或中断方式接收数据,并存储到缓冲区;

  • 调试输出模块:通过USART输出调试信息,帮助开发者验证串口通信功能。


  • 4. 硬件电路设计

    4.1 串口通信接口连接

  • 选择单片机的USART接口(如STM32F103的USART1);

  • TX与RX引脚分别连接到对应转换模块(如TTL转RS232或USB转串口模块);

  • 确保单片机与PC或其他设备之间电平匹配,必要时采用电平转换电路。

  • 4.2 供电与接口说明

  • 单片机与串口转换模块均需稳定的供电(如3.3V或5V);

  • 根据实际应用选择合适的通信模块和连接线;

  • 调试时可通过虚拟串口终端观察通信数据。


  • 5. 软件实现方案

    5.1 串口初始化与配置

  • 根据单片机型号(如STM32F103),配置USART寄存器,包括波特率、数据位、停止位、校验位等;

  • 初始化USART相关GPIO引脚(如PA9作为TX,PA10作为RX);

  • 开启USART并使能其发送和接收功能。

  • 5.2 数据发送与接收

  • 数据发送:封装printf风格的USART发送函数,实现逐字符发送数据。

  • 数据接收:可采用轮询或中断方式读取USART接收到的数据,存入缓冲区后处理。

  • 实现简单的串口数据回显功能,验证数据正确传输。

  • 5.3 调试与错误处理

  • 通过USART调试输出,显示初始化状态、发送和接收的数据,便于调试;

  • 在发送或接收过程中添加超时检测,确保程序稳健性。


  • 6. 详细代码实现

    下面给出基于STM32F103的示例代码,代码实现了USART串口通信的初始化、数据发送和接收功能,附有详细注释说明。
    注:代码中使用的寄存器和函数调用基于STM32标准外设库,实际项目中可根据具体平台做适当修改。

    6.1 整合代码及详细注释

    /***********************************************************************
     * 文件名称:USART_Communication.c
     * 项目名称:单片机实现串口通信
     * 文件描述:本文件实现了利用单片机USART接口进行串口通信的功能。
     *           程序包括USART初始化、数据发送、数据接收及调试输出。
     * 作者      :Katie
     * 日期      :2025-03-31
     *
     * 说明:
     * 1. 本示例以STM32F103为例,通过USART1实现串口通信。
     * 2. 波特率设为115200,数据位8位、1个停止位、无校验。
     * 3. 提供USART_Print函数封装printf风格的输出,同时实现简单的数据接收函数。
     ***********************************************************************/
    
    #include "stm32f10x.h"    // STM32F10x标准外设库头文件
    #include <stdio.h>
    #include <stdarg.h>
    #include <string.h>
    
    /*-----------------------------------------------
     宏定义部分:系统参数及外设配置
    -----------------------------------------------*/
    #define SYSTEM_CORE_CLOCK    72000000UL   // 系统时钟72MHz
    
    // USART调试接口配置(使用USART1,TX: PA9, RX: PA10)
    #define DEBUG_USART          USART1
    #define DEBUG_BAUDRATE       115200
    
    /*-----------------------------------------------
     全局变量定义
    -----------------------------------------------*/
    char rxBuffer[128];  // 数据接收缓冲区
    volatile uint16_t rxIndex = 0;
    
    /*-----------------------------------------------
     函数声明
    -----------------------------------------------*/
    void System_Init(void);
    void GPIO_Init_Config(void);
    void USART_Init_Config(void);
    void USART_Print(const char* fmt, ...);
    char USART_ReceiveChar(void);
    void Delay_ms(uint32_t ms);
    
    /*-----------------------------------------------
     函数名称:System_Init
     函数功能:系统初始化,配置时钟、GPIO和USART
    -----------------------------------------------*/
    void System_Init(void)
    {
        SystemCoreClockUpdate();
        GPIO_Init_Config();
        USART_Init_Config();
    }
    
    /*-----------------------------------------------
     函数名称:GPIO_Init_Config
     函数功能:初始化USART引脚(PA9和PA10)
    -----------------------------------------------*/
    void GPIO_Init_Config(void)
    {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
        
        GPIO_InitTypeDef GPIO_InitStructure;
        // TX: PA9,复用推挽输出
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
        
        // RX: PA10,浮空输入
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
    }
    
    /*-----------------------------------------------
     函数名称:USART_Init_Config
     函数功能:初始化USART1,用于串口通信和调试输出
    -----------------------------------------------*/
    void USART_Init_Config(void)
    {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
        
        USART_InitTypeDef USART_InitStructure;
        USART_InitStructure.USART_BaudRate = DEBUG_BAUDRATE;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        USART_InitStructure.USART_StopBits = USART_StopBits_1;
        USART_InitStructure.USART_Parity = USART_Parity_No;
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
        USART_Init(DEBUG_USART, &USART_InitStructure);
        
        USART_Cmd(DEBUG_USART, ENABLE);
    }
    
    /*-----------------------------------------------
     函数名称:USART_Print
     函数功能:通过USART输出调试信息,封装printf
    -----------------------------------------------*/
    void USART_Print(const char* fmt, ...)
    {
        char buffer[128];
        va_list args;
        va_start(args, fmt);
        vsnprintf(buffer, sizeof(buffer), fmt, args);
        va_end(args);
        
        int len = strlen(buffer);
        for (int i = 0; i < len; i++)
        {
            while (USART_GetFlagStatus(DEBUG_USART, USART_FLAG_TXE) == RESET);
            USART_SendData(DEBUG_USART, buffer[i]);
        }
    }
    
    /*-----------------------------------------------
     函数名称:USART_ReceiveChar
     函数功能:通过USART接收一个字符
     返回值:接收到的字符
    -----------------------------------------------*/
    char USART_ReceiveChar(void)
    {
        while (USART_GetFlagStatus(DEBUG_USART, USART_FLAG_RXNE) == RESET);
        return (char)USART_ReceiveData(DEBUG_USART);
    }
    
    /*-----------------------------------------------
     函数名称:Delay_ms
     函数功能:简单延时函数(非精确,仅用于测试)
    -----------------------------------------------*/
    void Delay_ms(uint32_t ms)
    {
        volatile uint32_t i, j;
        for(i = 0; i < ms; i++)
            for(j = 0; j < 7200; j++);
    }
    
    /*-----------------------------------------------
     主函数:程序入口
    -----------------------------------------------*/
    int main(void)
    {
        System_Init();
        USART_Print("串口通信程序启动...\r\n");
        
        // 主循环:将接收到的数据回显,并输出提示信息
        while(1)
        {
            char c = USART_ReceiveChar();
            // 将接收到的字符存入接收缓冲区(简单示例,不做溢出检测)
            rxBuffer[rxIndex++] = c;
            rxBuffer[rxIndex] = '\0';
            // 回显接收到的字符
            USART_Print("接收: %c\r\n", c);
            // 如接收到换行符,则输出整个接收缓冲区内容
            if(c == '\n')
            {
                USART_Print("完整数据: %s\r\n", rxBuffer);
                rxIndex = 0;
                memset(rxBuffer, 0, sizeof(rxBuffer));
            }
        }
        
        return 0;
    }
    

    7. 代码解读与测试结果

    7.1 代码解读

  • 系统初始化
    System_Init()函数调用GPIO_Init_Config()和USART_Init_Config(),初始化了用于USART通信的GPIO口(PA9/PA10)以及USART1参数(波特率115200,8位数据,无校验,1个停止位)。

  • 数据发送
    USART_Print()函数封装了printf风格的调试输出,实现逐字符发送,确保数据通过USART接口输出到调试终端。

  • 数据接收
    USART_ReceiveChar()函数通过轮询方式等待并读取接收到的字符,并在主循环中将字符存入接收缓冲区,检测到换行符后输出完整数据。

  • 7.2 测试结果

  • 在Proteus仿真或实际硬件测试中,单片机通过USART成功接收和发送数据;

  • 调试终端显示“串口通信程序启动…”提示信息,并实时回显接收到的数据;

  • 当输入换行符时,完整数据缓冲区内容正确输出,验证了数据接收功能;

  • 系统运行稳定,串口通信无误,适用于后续数据传输与调试应用。


  • 8. 项目总结与体会

    本项目展示了如何利用单片机实现串口通信,主要体会包括:

  • 串口通信基础
    串口通信是嵌入式系统中最常用的通信方式之一,通过USART实现数据的发送与接收,配置简单且易于调试。

  • 调试输出的重要性
    通过USART输出调试信息,可以实时监控系统状态,快速定位问题,为后续系统扩展和应用打下良好基础。

  • 代码结构与模块化设计
    将系统初始化、数据发送和接收封装成独立模块,便于维护和扩展,比如加入中断方式接收、DMA传输等。

  • 总体来说,该项目为嵌入式系统中实现串口通信提供了一个完整、详尽的参考案例,对初学者掌握USART的配置、数据传输及调试具有重要指导意义。


    9. 扩展阅读与参考资料

    1. 《嵌入式系统原理与实践》

    2. 《STM32微控制器实战开发》

    3. STM32F10x系列数据手册与参考手册

    4. 在线技术博客(如CSDN、博客园)中关于USART与串口通信的相关文章

    5. Proteus仿真软件使用指南


    结语

    本文详细介绍了如何利用单片机实现串口通信,包括串口初始化、数据发送和接收等功能。从项目背景、工作原理、系统设计、硬件电路设计到详细代码实现及注释,再到代码解读和测试结果,全面展示了串口通信的实现过程。
    作者:Katie
    希望本文能为你在嵌入式系统开发、通信协议实现及调试方面提供有益启发,欢迎在实践中不断探索和完善该方案!

    作者:Katie。

    物联沃分享整理
    物联沃-IOTWORD物联网 » 单片机串口通信实现详解:完整源码指南

    发表回复