嵌入式单片机---串口通信及相关通信技术

发布于:2025-09-07 ⋅ 阅读:(16) ⋅ 点赞:(0)

一、通信方式分类

(一)按数据传输线路数量划分:串行通信与并行通信

类别 定义 特点
并行通信 多个比特同时通过并行线进行传输 优点:传输速率较高;缺点:占用大量芯片资源
串行通信 将数据拆分成一个个比特,按照先后次序在一根总线上进行发送 优点:系统占用资源少,结构简单;地位:主机间通信的常用方式

(二)按数据传输方向划分:单工、半双工、全双工通信

通信方式 定义 关键特点
单工通信(Simplex) 数据仅能沿固定单一方向传输,一方永久为发送端,另一方永久为接收端 1. 单向不可逆;2. 仅需1根传输总线
半双工通信(Half-Duplex) 数据可沿两个方向传输,但不能同时双向传输,需切换传输方向 1. 双向可逆,但需分时;2. 可共用1根传输总线;3. 存在“发送-接收”的切换
全双工通信(Full-Duplex) 数据可沿两个方向同时传输,通信双方可同时发送和接收数据 1. 双向同步进行;2. 通常需2根独立传输线(如TX/RX);3. 无切换延迟,交互效率最高

二、串口通信(UART)核心知识

(一)串口通信定义

通常指“异步串口通信(UART)”,是串行通信的一种,通过1根发送线(TX)和1根接收线(RX)实现双向数据传输,靠“波特率同步”,广泛用于短距离设备交互(如单片机与电脑、传感器与控制器),属于异步串行全双工通信方式。

(二)串口通信时序

串口通信空闲时数据线为高电平,数据以“帧”为单位传输,1帧包含4个固定部分,时序顺序如下:

        空闲时为高电平

  1. 起始位:帧的开始标志,必为低电平(持续1个“位时间”,$ \text{位时间} = \frac{1}{\text{波特率}} $),用于通知接收端“即将传数据”;
  2. 数据位:实际传输的二进制数据,通常为5~8位(最常用8位,即1个字节),按“低位在前(LSB)、高位在后(MSB)”传输;
  3. 校验位(可选):用于检错,分奇校验(数据位+校验位总“1”的个数为奇数)、偶校验(总“1”的个数为偶数)、无校验(省略);
  4. 停止位:帧的结束标志,为高电平,用于接收端确认1帧结束,以保证下一个字节发送前的起始位能够表现出来。

(三)串口通信速率

  1. 速率决定因素:串口通信速率由“波特率(Baud Rate)”决定,波特率指“每秒传输的信号变化次数”(对串口而言,通常1个信号变化对应1位数据,因此 $ \text{波特率} \approx \text{每秒传输的位数} $,即bps),且收发双方必须设置相同的波特率,否则会因“位时间不匹配”导致数据传输错误。
  2. 常见波特率(单位:bps):1200、2400、4800、9600(常用)、115200等。

三、同步通信与异步通信

通信类型 定义 优点 缺点
同步通信 通信设备之间除了需要数据线之外,还需额外的时钟线(如SCLK),收发双方通过时钟信号“同步节奏”,数据连续传输(无间隙),发送方负责控制时钟线的变化,每发送一个比特,都需要将时钟线按照规则进行改变,通常以“块”为单位传输(如16位、32位) 无需起始/停止位,传输效率高 需额外时钟线,线路成本高,时钟干扰会影响同步
异步通信 无需时钟线,收发双方通过“约定相同的波特率”同步节奏,数据以“帧”为单位传输(每帧含起始/停止位,帧间可有空隙) 线路少(仅TX/RX)、成本低,适合短距离 因波特率偏差可能导致误码(需预留容错空间),效率略低

串口通信归属:串口通信(UART)属于异步通信,无需时钟线,靠起始/停止位和约定波特率实现数据同步。

四、常见电平标准(TTL、RS232、RS485)

三者是串口通信的“电平标准”(定义“0”和“1”对应的电压范围),核心差异是“电压范围”“传输距离”和“抗干扰能力”:

电平标准 电平定义 特点 应用场景
TTL(晶体管-晶体管逻辑电平) 高电平(1)= 3.3V/5V,低电平(0)= 0V 电压范围小,抗干扰能力弱,传输距离短(通常≤10米) 设备内部短距离通信(如单片机与传感器、模块间的板上通信)
RS232(Recommended Standard 232) 高电平(1)= -15V~-3V,低电平(0)= +3V~+15V(与TTL反相) 采用正负电压,抗干扰能力比TTL强,传输距离中等(通常≤15米),支持全双工(需TX/RX两根线) 早期电脑串口(DB9接口)与外设通信(如Modem、单片机下载),需通过“TTL-RS232转换器”与TTL设备连接
RS485(Recommended Standard 485) 采用“差分信号”(两根线A/B,通过A-B电压差判断电平:A>B时为1,A<B时为0),无固定电压范围(通常差分电压≥200mV即可识别) 差分传输抗干扰能力极强,传输距离远(最大1200米),支持多设备联网(最多32/128台设备共享总线),默认半双工(仅需A/B两根线,全双工需额外两根线) 工业现场长距离、多设备通信(如传感器网络、PLC控制、智能家居总线),需通过“TTL-RS485转换器”与TTL设备连接

五、USB相关

USB(通用串行总线)是一种常用的串行通信接口,具有即插即用、支持热插拔、传输速率较高、可同时为外部设备供电等特点,广泛应用于电脑与外部设备(如U盘、鼠标、键盘、手机等)的连接与数据传输,其通信方式为串行通信,支持全双工传输。

六、51单片机串口通信相关代码

(一)头文件引用

#include <reg52.h>  
#include <stdio.h>  
#include <string.h>  
#include "delay.h"  

(二)串口初始化函数

void init_uart(void)  
{  
    unsigned char t;  
    t = SCON;  
    t &= ~(3 << 6);  
    t |= (1 << 6) | (1 << 4);  
    SCON = t;  

    PCON |= (1 << 7);  

    t = TMOD;  
    t &= ~(3 << 4);  
    t |= (2 << 4);  
    t &= ~(3 << 6);  
    TMOD = t;  
    TH1 = 204;  
    TL1 = 204;  
    TCON |= (1 << 6);  

    IE |= (1 << 7) | (1 << 4);  
}  

(三)单个字符发送函数

void send_char(char ch)  
{  
    SBUF = ch;  
    while((SCON & (1 << 1)) == 0);  
    SCON &= ~(1 << 1);  
}  

(四)缓冲区发送函数

void send_buffer(const char *p, int len)  
{  
    while(len--)  
    {  
        send_char(*p++);  
    }  
}  

(五)串口中断服务函数

void uart_handler(void) interrupt 4  
{  
    if((SCON & (1 << 0)) != 0)  
    {  
        P2 = SBUF;  
        SCON &= ~(1 << 0);  
    }  
}  

(六)全局变量定义

xdata char recv_buffer[64];  
int pos = 0;  

(七)主函数

int main(void)  
{  
    int i = 1;  
    int n = 10;  

    char *p = (char *) &p;  
    xdata char buffer[32];  
    init_uart();  

    while(1)  
    {  
        n = sizeof(int);  
        sprintf(buffer, "int size  =  %d\n", n);  
        send_buffer(buffer, strlen(buffer));  

        n = sizeof(char);  
        sprintf(buffer, "char size  =  %d\n", n);  
        send_buffer(buffer, strlen(buffer));  

        n = sizeof(short);  
        sprintf(buffer, "short size  =  %d\n", n);  
        send_buffer(buffer, strlen(buffer));  

        n = sizeof(double);  
        sprintf(buffer, "double size  =  %d\n", n);  
        send_buffer(buffer, strlen(buffer));  

        n = sizeof(long);  
        sprintf(buffer, "long size  =  %d\n", n);  
        send_buffer(buffer, strlen(buffer));  

        n = sizeof(char *);  
        sprintf(buffer, "char * size  =  %d\n", n);  
        send_buffer(buffer, strlen(buffer));  

        delay(0x9FFF);  
    }  

    return 0;  
}  


网站公告

今日签到

点亮在社区的每一天
去签到