ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

嵌入式常用总线协议记录(I2C,SPI, Modbus 485, CAN...)

嵌入式常用总线协议记录(I2C,SPI, Modbus 485, CAN...) 常用的总线协议I2CSPICANMODBUS RTU485随笔记录除了CAN总线其他都用过无数次了有时间再补一补把太基础了目录一、I2CI2C速度I2C软件实现二、SPISPI 基本介绍SPI 的通讯模式SPI速度三、MODBUS RTU 4853.1 RS4853.2 Modbus 协议3.3 Modbus 和 RS485 关系和区别3.4 Modbus-RTU 协议格式说明3.4.1 地址码3.4.2 功能码3.4.3 数据区3.4.4 CRC校验3.4.5 寄存器地址与PLC组态地址四、CAN一、I2CI2C速度I2C 通讯的速度有100K 400K 3.4M一般来说比较少 三种bps。I2C软件实现起始信号时钟线高电平的时候数据线由高变低voidi2c_start(void){sda_high;delay_us(5);scl_high;delay_us(10);sda_low;delay_us(10);scl_low;//使SCL置低准备发送或者接受数据delay_us(10);}结束信号时钟线高电平的时候数据线由低变高voidi2c_stop(void){sda_low;delay_us(5);scl_low;delay_us(10);scl_high;delay_us(5);sda_high;delay_us(10);}ACK正常的时钟周期保持低电平主机和从机都需要响应ACKvoidIIC_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表示接收完成voidIIC_NAck(void){scl_low;//SCL为低SDA为高SCL为高SCL为低// MYSDA_OUT;sda_high;delay_us(10);scl_high;delay_us(10);scl_low;}I2C 发送数据voidIIC_Send_Byte(u8 txd){u8 t;// MYSDA_OUT;MYIIC_CLK_LOW;//拉低时钟开始数据传输 SCL为低SDA变高或者变低数据位SCL变高SCL变低期间SDA为1既1为0既0for(t0;t8;t)//一个字节8位一位一位发送{MYIIC_CLK_LOW;if((txd0x80)7)//从最高位开始发送如果是1发送高电平MYIIC_DATA_HIGH;elseMYIIC_DATA_LOW;txd1;//SDA处理完毕此时可以将SCL拉高接受数据拉高以后延时拉低delay_us(10);//MYIIC_CLK_HIGH;delay_us(10);MYIIC_CLK_LOW;delay_us(5);}}I2C数据读取 ://读1个字节ack1时发送ACKack0发送nACKu8IIC_Read_Byte(unsignedcharack){unsignedchari,receive0;// MYSDA_IN;//SDA设置为输入for(i0;i8;i){MYIIC_CLK_LOW;//SCL为由低变高在SCL高的时候去读 SDA的数据delay_us(10);MYIIC_CLK_HIGH;receive1;//第一次这里还是0第二次开始每次接收的数据做移动一位从高位开始接收if(MYIIC_DATA_STATE)receive;//如果数据为1以后就是1数据为0不执行就是0delay_us(10);}if(!ack)IIC_NAck();//发送nACKelseIIC_Ack();//发送ACKreturnreceive;}I2C等待 ACKu8MYIIC_Wait_Ack(void){u8 ucErrTime0;delay_us(5);MYIIC_DATA_HIGH;delay_us(5);//MCU DATA 置高外面高就是高外面低就是低MYIIC_CLK_HIGH;delay_us(5);//CLK 高电平期间数据有效while(MYIIC_DATA_STATE)//低电平为有应答高电平无应答{ucErrTime;if(ucErrTime250){MYIIC_Stop();return1;}}delay_us(10);MYIIC_CLK_LOW;return0;}半双工二、SPISPI 基本介绍SPISerial Peripheral Interface串行外设接口是一种高速、全双工、同步通信总线常用于短距离通讯主要应用于 EEPROM、FLASH、实时时钟、AD 转换器、还有数字信号处理器和数字信号解码器之间。SPI的4根线SDO/MOSI – 主设备数据输出从设备数据输入;SDI/MISO – 主设备数据输入从设备数据输出;SCLK – 时钟信号由主设备产生;CS/SS – 从设备使能信号由主设备控制。当有多个从设备的时候因为每个从设备上都有一个片选引脚接入到主设备机中当我们的主设备和某个从设备通信时将需要将从设备对应的片选引脚电平拉低或者是拉高一般来说是低电平选中。SPI 以主从方式工作通常有一个主设备和一个或多个从设备。通信由主设备发起主设备通过 CS 选择要通信的从设备然后通过 SCLK 给从设备提供时钟信号数据通过 MOSI 输出给从设备同时通过 MISO 接收从设备发送的数据。主设备能够控制时钟因为SPI通信并不像UART或者IIC通信那样有专门的通信周期起始信号结束信号所以SPI协议能够通过控制时钟信号线当没有数据交流的时候我们的时钟线要么是保持高电平要么是保持低电平。SPI 的通讯模式SPI 的 有四种模式CPOL0表示当SCLK0时处于空闲态空闲低电平所以有效状态就是SCLK处于高电平时CPOL1表示当SCLK1时处于空闲态空闲高电平所以有效状态就是SCLK处于低电平时CPHA0表示数据采样是在第1个边沿CPHA1表示数据采样是在第2个边沿所以最终有 4 种配置可选 模式CPHACPHA说明000空闲时SCLK为低电平数据在第一个边沿即上升沿采样101空闲时SCLK为低电平数据在第二个边沿即下降沿采样210空闲时SCLK为高电平数据在第一个边沿即下降沿采样311空闲时SCLK为高电平数据在第二个边沿即上升沿采样模式0CPOL0, CPHA0 - 空闲时SCLK为低电平数据在第一个边沿即上升沿采样。模式1CPOL0, CPHA1 - 空闲时SCLK为低电平数据在第二个边沿即下降沿采样。模式2CPOL1, CPHA0 - 空闲时SCLK为高电平数据在第一个边沿即下降沿采样。模式3CPOL1, CPHA1 - 空闲时SCLK为高电平数据在第二个边沿即上升沿采样。当 CPHA 1 的时候当 CPHA 0 的时候不同的从设备可能在出厂时由工厂配置为某种通信模式无法改变所以我们得根据从设备的通讯模式来设置主设备的模式。比如我们常用的 SPI Flash W25QXX 系列可以在文档资料中看到其支持的工作模式SPI速度已经有器件可达 50Mbps一般情况下SPI模块的最大时钟频率为系统时钟频率的1/2。全双工三、MODBUS RTU 4853.1 RS485RS-485则是通信线路,只是一种硬件接口。基本概念RS485百度百科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通讯协议百度百科在进行多机通信的时候Modbus协议规定每个控制器必须要知道它们的设备地址识别按照地址发送过来的数据决定是否要产生动作产生何种动作如果要回应控制器将生成的反馈信息用Modbus协议发出。Modbus有两种通信传输方式一种是ASCII模式一种是RTU模式。RTU方式也叫十六进制 例如发送0x03:0000 0011ASC方式0x03 发送0 0x300011 0000 发送30x330011 0011ASCII 的通信效率低方便调试实际应用比较少工业上都采用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 协议格式说明3.4.1 地址码通讯地址 0~247对于一主多从的通讯架构中主机为0。从设备地址为 1~247。主机发送地址码 0 一般称为广播数据从机无需响应。3.4.2 功能码ModBus通讯规约可定义的功能码为1到127。比如 03H 为 读寄存器功能码 16H 为 写寄存器功能码。从设备的回应数据包格式回应数据包和主机查询的数据包格式包是一致的正常回应时功能码与主机发的功能码一致1~127异常的回应功能码要在收到的功能码基础上加上128 例如发 0x03 收0x03 1283.4.3 数据区常见的功能码的数据吗格式一般在Modbus通用协议中已经做了规范。比如 对于03功能码后面跟的数据包括 2个字节表示寄存器地址2个字节表示想要读取的寄存器个数返回的3功能码后接1个字节的返回字节个数该个数应为上述读取寄存器个数的两倍因为一个寄存器对应两个字节比如上图中返回的数据应该是 01 03 20 xxxxxxx再看个例子3.4.4 CRC校验CRC 校验CRC - 16 低位在前高位在后。这个CRC校验代码网上也很多下面是我自己上传的一个资源CRC校验代码3.4.5 寄存器地址与PLC组态地址如图所示对于从机而言有寄存器地址 和 PLC组态地址的分别寄存器PLC地址指存放于控制器中的地址这些控制器可以是PLC也可以使触摸屏或是文本显示器。PLC地址一般采用10进制描述共有5位其中第一位代码寄存器类型。寄存器modbus协议地址指通信时使用的寄存器地址在实际编程中由于寄存器PLC地址前缀的区分作用所以只需说明后4位数而且需转换为4位十六进制地址。例如PLC地址40001对应寻址地址0x000040002对应寻址地址0x0001寄存器寻址地址一般使用16进制描述。再如PLC寄存器地址40003对应协议地址0002PLC寄存器地址30003对应协议地址0002。在实际编程中由于前缀的区分作用所以只需说明后4位数而且需转换为4位十六进制地址。支持 Modbus 协议的设备或软件使用时用户直接设置或看到的应当是 Modbus 数据地址。Modbus 地址所访问的数据是通过各种 “功能”读写而来。 功能码是 Modbus 地址的底层。 如果 Modbus 通 信的一方提供的所谓 Modbus 协议只有功能码则需要注意了解此 功能号与 Modbus 地址间的对应关系。四、CAN通常四线线路实现全双工数据传输二线线路实现单工或半双工数据传输。在采用频分法、时间压缩法、回波抵消技术时二线线路也可实现全双工数据传输。
返回列表