串口、IIC、SPI通信协议精简总结

串行通信协议比较

特性串行(UART/USART)I2CSPI
线数2 (TX, RX)2 (SDA, SCL)4 (MISO, MOSI, SCLK, SS/CS)
数据率低到中等中等
主/从可以是主或从主/从主/从
寻址无寻址7位或10位地址通过片选线 (SS) 进行寻址
拓扑点对点,点到多点多主,多从多主,多从
总线仲裁无总线仲裁通过冲突进行仲裁无总线仲裁
错误处理有限错误检测基本的错误检查有限错误检测
用途一般通信传感器,EEPROM,某些集成电路闪存,传感器,外设
灵活性由于固定大小较不灵活由于寻址更灵活通过各种模式更灵活
电缆长度中等到长短到中等短到中等
常见电压电平TTL, RS-232(可能不同)通常为3.3V或5V通常为3.3V或5V
双工模式全双工或半双工半双工全双工
时钟信号同步或异步同步同步
设备示例USB到串行适配器,微控制器传感器,EEPROM,微控制器闪存,传感器,微控制器

串行通信 (UART/USART) 特性详解

特性描述
定义串行通信是一种逐位传输数据的通信方式。
线数2 (TX, RX) - 分别用于发送和接收数据。
数据率低到中等 - 支持不同速率,例如 9600、115200 bps。
工作模式全双工或半双工 - 可同时发送和接收或只能执行其中一项。
电平标准TTL, RS-232(可能不同) - 标准电平可以是TTL或RS-232。
帧结构起始位、数据位、校验位和停止位组成帧结构。
同步方式可以是同步或异步 - 同步需要时钟信号,异步没有时钟信号。
寻址方式无寻址 - 通常是点对点通信,不需要地址进行寻址。
错误检测有限错误检测 - 常见的错误检测包括奇偶校验和校验和。
适用范围一般通信 - 用于连接各种设备,例如传感器、微控制器等。
典型用途USB到串行适配器、微控制器通信等。
电缆长度中等到长 - 随着电缆长度增加,需注意信号衰减。
优势简单、成本低、易于实现。
劣势电缆长度受限,对电缆质量和环境敏感。

注:TTL (Transistor-Transistor Logic) 是一种低电平逻辑电平标准,RS-232 是一种常见的串口电平标准。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>     
#include <unistd.h>
#include <fcntl.h> 
#include <termios.h>

void error(const char *msg) {
    perror(msg);
    exit(EXIT_FAILURE);
}

int main() {
    // 打开串口设备
    int serial_port = open("/dev/ttyUSB0", O_RDWR); 
    if (serial_port == -1) { 
        error("Error - Unable to open UART.");
    }

    // 配置串口参数
    struct termios options;
    tcgetattr(serial_port, &options);
    cfsetispeed(&options, B9600);
    cfsetospeed(&options, B9600);
    options.c_cflag |= (CLOCAL | CREAD);
    options.c_cflag &= ~PARENB;   // 无校验位
    options.c_cflag &= ~CSTOPB;   // 1停止位
    options.c_cflag &= ~CSIZE;    // 清除数据位设置
    options.c_cflag |= CS8;       // 设置数据位为8位
    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);  // 非规范模式 
    options.c_iflag &= ~(IXON | IXOFF | IXANY);  // 禁用软件流控制
    options.c_oflag &= ~OPOST;   // 原始输出

    tcsetattr(serial_port, TCSANOW, &options);

    // 发送数据
    char tx_buffer[] = "Hello, Serial!";
    if (write(serial_port, tx_buffer, strlen(tx_buffer)) < 0) { 
        error("Error - Unable to write to UART.");
    }

    // 接收数据
    char rx_buffer[256];
    int bytes_read = read(serial_port, rx_buffer, sizeof(rx_buffer));
    if (bytes_read < 0) {
        error("Error - Unable to read from UART."); 
    }

    // 打印接收到的数据
    printf("Received Data: %.*s\n", bytes_read, rx_buffer);

    // 关闭串口
    close(serial_port);

    return 0;
}

I2C通信特性详解

特性描述
定义I2C (Inter-Integrated Circuit) 是一种串行通信协议。
线数2 (SDA, SCL) - 数据线 (SDA) 和时钟线 (SCL)。
数据率中等 - 数据传输速率通常在几百 kHz 到几兆 Hz 之间。
工作模式主/从 - 设备可以是主设备(发起通信)或从设备(被动应答)。
寻址方式7位或10位地址 - 设备通过地址进行唯一寻址。
拓扑多主,多从 - 允许多个主设备和多个从设备存在在同一总线上。
总线仲裁通过冲突进行仲裁 - 多主模式下可能发生仲裁冲突。
错误检查基本的错误检查 - 可以通过 NACK 信号检测错误。
适用范围传感器,EEPROM,某些集成电路等。
典型用途用于连接多个设备,如传感器、EEPROM、实时时钟等。
电缆长度短到中等 - 电缆长度受限,随着电缆长度增加需注意信号衰减。
常见电压电平通常为3.3V或5V。
双工模式半双工 - 数据在两个方向上传输,但不同时进行。
时钟信号同步 - 时钟信号由主设备提供。
设备示例传感器,EEPROM,微控制器等。
灵活性由于寻址更灵活,支持多主模式。
优势适用于连接多个设备,寻址灵活,支持多主模式。
劣势电缆长度受限,错误检测有限。

注:I2C 是一种常见的串行通信协议,广泛用于连接各种集成电路和外设。

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>

#define I2C_DEVICE "/dev/i2c-1"  // I2C设备路径,根据实际情况修改

void error(const char *msg) {
    perror(msg);
    exit(EXIT_FAILURE);
}

int main() {
    // 打开I2C设备
    int i2c_fd = open(I2C_DEVICE, O_RDWR);
    if (i2c_fd == -1) {
        error("Error - Unable to open I2C device.");
    }

    // 设置I2C从设备地址
    int slave_address = 0x48;  // 请根据实际从设备地址修改
    if (ioctl(i2c_fd, I2C_SLAVE, slave_address) < 0) {
        error("Error - Unable to set I2C slave address.");
    }

    // 发送数据
    char tx_buffer[] = "Hello, I2C!";
    if (write(i2c_fd, tx_buffer, sizeof(tx_buffer)) != sizeof(tx_buffer)) {
        error("Error - Unable to write to I2C device.");
    }

    // 接收数据
    char rx_buffer[256];
    if (read(i2c_fd, rx_buffer, sizeof(rx_buffer)) < 0) {
        error("Error - Unable to read from I2C device.");
    }

    // 打印接收到的数据
    printf("Received Data: %s\n", rx_buffer);

    // 关闭I2C设备
    close(i2c_fd);

    return 0;
}

SPI通信特性详解

特性描述
定义SPI (Serial Peripheral Interface) 是一种全双工串行通信协议。
线数4 (MISO, MOSI, SCLK, SS/CS) - MISO: 主设备到从设备数据线,MOSI: 从设备到主设备数据线,SCLK: 时钟线,SS/CS: 片选线。
数据率高 - 支持高达几百 Mbps 到几 Gbps 的数据传输速率。
工作模式主/从 - 主设备发起通信,从设备被动应答。
寻址方式通过片选线 (SS/CS) 进行寻址 - 每个从设备连接到不同的片选线。
拓扑多主,多从 - 允许多个主设备和多个从设备存在在同一总线上。
总线仲裁无总线仲裁 - 没有多主模式下的总线仲裁。
错误检查有限错误检测 - 可以通过校验和等手段进行错误检测。
适用范围闪存,传感器,外设等。
典型用途连接外设,如闪存、传感器、显示器等。
电缆长度短到中等 - 电缆长度受限,随着电缆长度增加需注意信号衰减。
常见电压电平通常为3.3V或5V。
双工模式全双工 - 可同时进行数据发送和接收。
时钟信号同步 - 时钟信号由主设备提供。
设备示例闪存,传感器,微控制器等。
灵活性通过各种模式更灵活 - 支持不同的时钟极性和相位配置。
优势高速数据传输,支持全双工通信,灵活的时钟和模式配置。
劣势对布线和电缆长度要求较高,相对复杂。

注:SPI是一种常用的串行通信协议,特别适用于高速数据传输和连接外围设备。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h> 
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>

#define SPI_DEVICE "/dev/spidev0.0"  // SPI设备路径,根据实际情况修改

void error(const char *msg) {
    perror(msg);
    exit(EXIT_FAILURE);
}

int main() {
    // 打开SPI设备
    int spi_fd = open(SPI_DEVICE, O_RDWR);
    if (spi_fd == -1) {
        error("Error - Unable to open SPI device.");
    }

    // 配置SPI设备
    uint8_t mode = SPI_MODE_0;  // SPI模式,可以根据需要修改
    uint8_t bits = 8;           // 数据位数,可以根据需要修改
    uint32_t speed = 1000000;   // 时钟速率,可以根据需要修改
    if (ioctl(spi_fd, SPI_IOC_WR_MODE, &mode) < 0 ||
        ioctl(spi_fd, SPI_IOC_WR_BITS_PER_WORD, &bits) < 0 ||
        ioctl(spi_fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0) {
        error("Error - Unable to configure SPI device.");
    }

    // 发送和接收数据
    uint8_t tx_buffer[] = {0x01, 0x02, 0x03};  // 请根据实际需求修改
    uint8_t rx_buffer[sizeof(tx_buffer)] = {0};

    struct spi_ioc_transfer transfer = {
        .tx_buf = (unsigned long)tx_buffer,
        .rx_buf = (unsigned long)rx_buffer,
        .len = sizeof(tx_buffer),
        .speed_hz = speed,
        .bits_per_word = bits,
    };

    if (ioctl(spi_fd, SPI_IOC_MESSAGE(1), &transfer) < 0) {
        error("Error - Unable to perform SPI transaction.");
    }

    // 打印接收到的数据
    printf("Received Data:");
    for (int i = 0; i < sizeof(rx_buffer); i++) {
        printf(" %02x", rx_buffer[i]);
    }
    printf("\n");

    // 关闭SPI设备
    close(spi_fd);

    return 0;
}

  • 21
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值