这里是引用
串行通信协议详解 UART IIC SPI 串口-I2C-SPI协议区分对比 保姆级解说教程
以上视频是我对3种协议的讲解。
对比表
我们也可以看一下,UART、IIC和SPI对比表
特性 | 串口 | IIC | SPI |
---|---|---|---|
通信速率(最大) | 230400 bps | 400 kbps(快速) | 高达72 MHz(主机) |
通信线数量 | 2 根 | 2 根 | 4 根 |
通信距离 | 短距离 | 短距离 | 短距离 |
通信协议 | 异步串行 | 同步串行 | 同步串行 |
硬件复杂度 | 低 | 中等 | 中等 |
软件复杂度 | 低 | 中等 | 中等 |
主从设备支持 | 支持(从设备) | 支持(主/从设备) | 支持(主/从设备) |
多设备通信 | 支持 | 支持 | 支持 |
数据传输完整性 | 低 | 高 | 高 |
UART其实也是可以进行多设备通信。在多设备通信时,需要使用分时复用技术或者基于协议的多点通信技术。其中分时复用技术将多个设备连接到同一串口,通过在不同时间间隔内交替发送数据来实现多设备通信;而基于协议的多点通信技术则使用特定的通信协议来允许多个设备连接到同一串口进行通信。因此,在选择通信协议时,需要考虑实际应用需求以及硬件和软件资源的限制。
6个demo
以下我用51单片机和STM32单片机分别做了6个demo,仅供参考
UART,51版本
这个程序使用定时器1控制串口通信的波特率,其中FREQ和BAUD分别表示单片机的工作频率和波特率。在初始化函数init_serial()中,将定时器1配置为模式2,并计算出需要设定的初值,然后启动定时器1。同时,将串口配置为模式1,允许接收,开启串口中断并开启总中断。在串口中断处理函数serial_interrupt()中,处理接收到的数据和发送下一条数据。主循环中可以进行其他任务的处理。注意,需要根据实际的硬件接口来配置串口相关的引脚和波特率等参数。
#include<reg52.h>
#define FREQ 11059200 // 单片机工作频率
#define BAUD 9600 // 波特率
void init_serial() {
TMOD &= 0x0F;
TMOD |= 0x20; // 定时器1工作在模式2
TH1 = 256 - FREQ / (BAUD * 32);
TR1 = 1; // 启动定时器1
SCON = 0x50; // 串口工作在模式1,允许接收
ES = 1; // 开启串口中断
EA = 1; // 开启总中断
}
void serial_interrupt() interrupt 4 {
if (RI) {
RI = 0; // 清除接收中断标志
// 处理接收到的数据
// ...
}
if (TI) {
TI = 0; // 清除发送中断标志
// 发送下一条数据
// ...
}
}
void main() {
init_serial();
// 主循环
while(1) {
// ...
}
}
UART,STM32版本
这个程序使用USART1控制串口通信的波特率,其中FREQ和BAUD分别表示单片机的工作频率和波特率。在初始化函数init_serial()中,先使能USART1和GPIOA的时钟,然后配置PA9为复用推挽输出模式,PA10为浮空输入模式。接着,配置USART1的参数,包括波特率、字长、停止位、校验位等等,并使能USART1。发送一个字节时,先等待发送缓冲区为空,然后调用USART_SendData()发送一个字节。接收一个字节时,先等待接收缓冲区非空,然后调用USART_ReceiveData()读取一个字节。
STm32F103单片机控制串口通信的简单程序,波特率为9600:
#include "stm32f10x.h"
#define FREQ 72000000 // 单片机工作频率
#define BAUD 9600 // 波特率
void init_serial() {
// 使能USART1和GPIOA的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
// 配置PA9为复用推挽输出模式,PA10为浮空输入模式
GPIO_InitTypeDef gpio_init;
gpio_init.GPIO_Pin = GPIO_Pin_9;
gpio_init.GPIO_Mode