嵌入式常用总线协议记录(I2C,SPI, Modbus 485, CAN(1),字节跳动架构师讲解物联网嵌入式开发开发

80 阅读7分钟

{ sda_high; delay_us(5); scl_high; delay_us(10); sda_low; delay_us(10); scl_low; //使SCL置低,准备发送或者接受数据 delay_us(10); }


结束信号:时钟线高电平的时候,数据线由低变高


![在这里插入图片描述](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/4910339e8c3349b690b7df79f40313e8~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771252007&x-signature=VBKEi6ty2zgJH8DOfxyUgUuvLfI%3D)



void i2c_stop(void) { sda_low; delay_us(5); scl_low; delay_us(10); scl_high; delay_us(5); sda_high; delay_us(10); }


ACK:正常的时钟周期,保持低电平,主机和从机都需要响应ACK



void IIC_Ack(void) { scl_low; //SCL为低,SDA为低,SCL为高,SDA为低,应答低电平有效,SCL为低,产生应答信号 // MYSDA_OUT; sda_low; delay_us(10); scl_high; delay_us(10); scl_low; delay_us(10); sda_high; }


NACK:正常的之中周期,保持高电平,一般在接收数据的最后一个字节,发送NACK,表示接收完成



void IIC_NAck(void) { scl_low; //SCL为低,SDA为高,SCL为高,SCL为低 // MYSDA_OUT; sda_high; delay_us(10); scl_high; delay_us(10); scl_low; }


I2C 发送数据:



void IIC_Send_Byte(u8 txd) {
u8 t;
// MYSDA_OUT; MYIIC_CLK_LOW; //拉低时钟开始数据传输 ,SCL为低,SDA变高或者变低(数据位),SCL变高,SCL变低,期间SDA为1既1,为0既0 for(t=0;t<8;t++) //一个字节8位,一位一位发送 {
MYIIC_CLK_LOW; if((txd&0x80)>>7) //从最高位开始发送,如果是1,发送高电平 MYIIC_DATA_HIGH; else MYIIC_DATA_LOW; txd<<=1; //SDA处理完毕,此时可以将SCL拉高接受数据,拉高以后延时拉低 delay_us(10); // MYIIC_CLK_HIGH; delay_us(10); MYIIC_CLK_LOW; delay_us(5); } }


I2C数据读取 :



//读1个字节,ack=1时,发送ACK,ack=0,发送nACK u8 IIC_Read_Byte(unsigned char ack) { unsigned char i,receive=0; // MYSDA_IN;//SDA设置为输入 for(i=0;i<8;i++ ) { MYIIC_CLK_LOW; //SCL为由低变高,在SCL高的时候去读 SDA的数据 delay_us(10); MYIIC_CLK_HIGH; receive<<=1; //第一次这里还是0,第二次开始每次接收的数据做移动一位,从高位开始接收 if(MYIIC_DATA_STATE)receive++; //如果数据为1,++以后就是1,数据为0,不执行就是0; delay_us(10); } if (!ack) IIC_NAck();//发送nACK else IIC_Ack(); //发送ACK return receive; }


I2C等待 ACK:



u8 MYIIC_Wait_Ack(void) { u8 ucErrTime=0; delay_us(5); MYIIC_DATA_HIGH;delay_us(5); //MCU DATA 置高,外面高就是高,外面低就是低 MYIIC_CLK_HIGH; delay_us(5); //CLK 高电平期间数据有效 while(MYIIC_DATA_STATE) //低电平为有应答,高电平无应答 { ucErrTime++; if(ucErrTime>250) { MYIIC_Stop(); return 1; }
} delay_us(10); MYIIC_CLK_LOW; return 0; }


半双工!!!


## 二、SPI


### SPI 基本介绍


SPI(Serial Peripheral Interface,串行外设接口)是一种高速、全双工、同步通信总线,常用于短距离通讯,主要应用于 EEPROM、FLASH、实时时钟、AD 转换器、还有数字信号处理器和数字信号解码器之间。


SPI的4根线:  
 ![在这里插入图片描述](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/ce56f4fe602d4f24a8da3c121e5dc458~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771252007&x-signature=SlJy%2BqKZIO4RX151YKvIp0ILMvk%3D)


* SDO/MOSI – 主设备数据输出,从设备数据输入;
* SDI/MISO – 主设备数据输入,从设备数据输出;
* SCLK – 时钟信号,由主设备产生;
* CS/SS – 从设备使能信号,由主设备控制。当有多个从设备的时候,因为每个从设备上都有一个片选引脚接入到主设备机中,当我们的主设备和某个从设备通信时将需要将从设备对应的片选引脚电平拉低或者是拉高(一般来说是低电平选中)。


SPI 以主从方式工作,通常有一个主设备和一个或多个从设备。通信由主设备发起,主设备通过 CS 选择要通信的从设备,然后通过 SCLK 给从设备提供时钟信号,数据通过 MOSI 输出给从设备,同时通过 MISO 接收从设备发送的数据。


主设备能够控制时钟,因为SPI通信并不像UART或者IIC通信那样有专门的通信周期,起始信号,结束信号;所以SPI协议能够通过控制时钟信号线,当没有数据交流的时候我们的时钟线要么是保持高电平要么是保持低电平。


### SPI 的通讯模式


SPI 的 有四种模式:


CPOL=0,表示当SCLK=0时处于空闲态,空闲低电平,所以有效状态就是SCLK处于高电平时  
 CPOL=1,表示当SCLK=1时处于空闲态,空闲高电平,所以有效状态就是SCLK处于低电平时  
 CPHA=0,表示数据采样是在第1个边沿  
 CPHA=1,表示数据采样是在第2个边沿


所以最终有 4 种配置可选 :




| CPOL | CPHA |
| --- | --- |
| 1 | 1 |
| 0 | 0 |
| 1 | 0 |
| 0 | 1 |


当 CPHA= 1 的时候:  
 ![在这里插入图片描述](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/000da1de3f51470683247d2943505e17~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771252007&x-signature=fex9Bkmm%2BhCRgEkoji0%2B%2BXf9g14%3D)


当 CPHA= 0 的时候:  
 ![在这里插入图片描述](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/8343fbf292a8462cb93a825b0156fcd8~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771252007&x-signature=Cfep1edvWoUFCo56Y4XAxy1fanU%3D)


不同的从设备可能在出厂时由工厂配置为某种通信模式,无法改变,所以我们得根据从设备的通讯模式来设置主设备的模式。


比如我们常用的 SPI Flash W25QXX 系列,可以在文档资料中看到其支持的工作模式:


![在这里插入图片描述](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/a1fa83f6e76e4f11bc2c866b2b3c66df~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771252007&x-signature=XYB8dLqnPJlVVVkFo8zU1xey9lw%3D)


### SPI速度


已经有器件可达 50Mbps,一般情况下,SPI模块的最大时钟频率为系统时钟频率的1/2。


全双工!!!


## 三、MODBUS RTU 485


### 3.1 RS485


RS-485则是通信线路,只是一种硬件接口。


基本概念:


[RS485百度百科](https://gitee.com/vip204888)


RS485具有A、B两根线,并且通过A、B两根线之间的压差来定义1和0。A和B的压差在+(2-6)V内为高电平,A和B的压差在-(2-6)V内为低电平。由此就定义了RS485的电气接口和电平。


虽然RS485通讯链 用一对双绞线将 各个接口的 “A”“ B” 端连接起来,就可以进行通信了,但是为了保证整个系统的稳定性,还是建议将各个设备共 负极(地),来确保网络的稳定性。


半双工!!!


### 3.2 Modbus 协议


基本概念:


[Modbus通讯协议百度百科](https://gitee.com/vip204888)


在进行多机通信的时候,Modbus协议规定每个控制器必须要知道它们的设备地址,识别按照地址发送过来的数据,决定是否要产生动作,产生何种动作,如果要回应,控制器将生成的反馈信息用Modbus协议发出。


Modbus有两种通信传输方式,一种是ASCII模式,一种是RTU模式。


* RTU方式:也叫十六进制 例如:发送0x03:0000 0011
* ASC方式:0x03 (发送0 :0x30:0011 0000 )( 发送3:0x33:0011 0011)


ASCII 的通信效率低,方便调试,实际应用比较少;工业上都采用RTU方式,效率高。


工业应用上一般 Modbus 485 波特率为9600 或者 4800,因为速度越快传输距离越短,速度太慢也影响效率


### 3.3 Modbus 和 RS485 关系和区别


RS485只是一种硬件接口,他只是把来自单片机UART的信号,翻转电平进行传输,并驱动线缆。  
 所以RS485其实只是一种硬件接口驱动芯片。  
 Modbus是一种软件协议,规定了一种语言。  
 Modbus可以跑在RS485上,也能跑在RS232上,也能跑在POWERBUS。  
 Modbus可以支持多种电气接口,如RS-232、RS-485等,还可以在各种介质上传送,如双绞线、光纤、无线等。


同理。  
 RS485上可以用Modbus,也能用其他自拟协议。协议只是软件。


Modbus只是通信协议的一种,就像汉语和英语一样,就是一种交流的语言,一种机器之间交流的语言。那么在交流之前肯定要有沟通的桥梁吧,那就是传输媒介485或232或其他电气规则,同一种协议可以用不同的传输媒介方式如485或232但是同一传输线路上不能同时存在两种协议.


### 3.4 Modbus-RTU 协议格式说明


![在这里插入图片描述](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/458e0fc7d3034007bfcf145cdb504b1c~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771252007&x-signature=3FCZVErlLAHGAjOdXUKPh0%2F8R8k%3D)


#### 3.4.1 地址码


通讯地址: 0~247



![img](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/d9e4472ea14a41f48e6d48317b48be2b~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771252007&x-signature=V7LNAJsvdSk3oVfWfaNXFuo0gAg%3D)
![img](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/b667d3cb971f4043aaa043796907de75~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771252007&x-signature=yehfd2nNBW4HITo8Vdye0IBBG5o%3D)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://gitee.com/vip204888)**