常用通信时序(UART、IIC、SPI,RS232、RS485)及协议(Modbus)

  • 通讯时序
    • 1. UART
    • 2. IIC
    • 3. SPI
    • 4. RS323
    • 5. RS485
  • 通信协议
    • 1. Modbus
      • 1.1. 帧组成结构
      • 1.2. 实战案例讲解

通讯时序

1. UART

通讯时序图:

类 型:串行异步通信
总线定义:
TXD:发送数据线
RXD:接收数据线
数据传输:
①接收方RX初始电平为1
②带起始位0和停止位1
③先发送低位再高位
④传输数据位以字节为单位,一次只能传输一字节
⑤以波特率为时基约定通信双方接收和发送时间点
注意事项:
在进行UART通信时,双方的波特率必须一致

模拟UART通信伪算法
作用:将从串口接收到的数据+1再发送出去
读取方法:采取中断模拟波特率的方式,在每个数据位的中间处读取数据,因此我们可以看出,读取起始位的时候是一半的波特率,后面都是完整的波特率,这样就能保证每次都是在数据位的中间去读取数据。
实现流程:
①while(RxdPin)
②StartRxd();
③while(RxdEnd)
④StartTxd(RxdBuff+1);
⑤while(RxdEnd);
程序解析:
① 等待RXD引脚出现低电平,即起始信号
② 启动接收,实质就是开启中断,在中断里接收,中断的间隔就是设置的特率,即每达到一个波特率中断就会执行一次,接收起始信号时波特率为一半。
③ 经过了②开启了中断之后,到达了设定的波特率就会进入中断处理数据,当中断处理完起始信号、8位数据位、停止信号之后就会置位接收结束标志位告诉程序接收完毕。
④ 将保存在接收缓冲区的数据+1再发送出去,和接收的方法大同小异。
⑤ 等待中断发送完毕,置位发送标志位

2. IIC

通讯时序图:

类 型:串行同步通信
总线定义:
SCL : 时钟线
SDA: 数据线
数据传输:
① 默认两总线因为上拉电阻的缘故保持高电平
② 带起始信号和停止位信号
③ 先发送高位再低位
④ 传输数据位以字节为单位,只要不发送停止信号可以无限传输数据
⑤ 以当前时钟线和数据线的高低电平状态来决定当前是何种信号
注意事项:
① IIC总线必须外接上拉电阻。
② 规定当SCL处于低电平时,SDA是可以变化的,当SCL为高电平是读取SDA的时间,因此这段时间SDA必须是一个稳定的电平状态,不允许发生改变。
③ IIC通信是没有命令和数据概念的,比如OLED的IIC通信模式,会涉及到IIC发送的是地址还是命令,这是由OLED的驱动决定的,IIC只能读写数据而已(读1/写0),比如OLED就规定了,如果你在当前传输协议中写入了一个0x00,那么后面传输的所有数据都为命令,如果写入的是0x40,那么后面的就全是数据了。

IIC通信流程(写入数据):
① I2cStart();
② I2cWriteByte(I2cAddress);
③ I2cWaitAck();
④ I2cWriteByte(RegisterAddress);
⑤ I2cWaitAck();
⑥ I2cWriteByte(Data);
⑦ I2cWaitAck();
⑧ I2cStop();

程序解释
①:此为I2c的起始信号,根据时序图我们可以看出,初始状态SDA和SCL都为高电平,当开始进行IIC通信时,SDA先拉低,继而SCL拉低,这就完成了IIC的起始信号。
②:此为I2c写数据的函数,具体实现过程根据时序图可知有以下步骤:

  1. 拉低SCL
  2. 改SDA的引脚模式为输出
  3. 循环8次
  4. 写入需要写入的SDA的数据(延迟一下)(从高到低以字节为单位发送)
  5. 拉高SCL通知从机读取数据写入(延迟一下)
  6. 拉低SCL
  7. 循环8次
  8. 拉低SCL以便接收Ack
  9. 拉高SDA,也叫释放总线,用于后面接收Ack(接收到则SDA被从机拉低)

③:等待Ack,拉高SCL读取,再拉低SCL释放
④:停止信号,首先都输出低电平,SCL拉高(延迟一下)SDA拉高(延迟一下)
上面只是演示了IIC写操作的流程,其实读操作也是一样的,唯一不同的两个地方,一是在发送第二个寄存器地址的时候,最后一位应改为写模式,第二个就是读写操作函数上的区别,唯一的区别就是写入的时候,是输出SDA的电平,而读取的时候是检测SDA的电平,其他地方是一样的

3. SPI

类 型:高速全双工同步通信总线
总线定义:
SCS/NSS、CS: 片选使能(可以自定义引脚而不用硬件规定引脚)
SCL : 时钟线
MOSI: 主发从收
MISO: 主收从发

模 式:
CPOL:0—SCL空闲为低电平 1—SCL空闲为高电平
CPHA:0—SCL基数边沿采样 1—SCL偶数边沿采样
主要是用来适配和各种不同种类的SPI协议器件通信

通讯时序图:




数据传输:
① 拉低SCS为起始信号,拉低SCS之前的SCL电平由CPOL决定
② 在边沿触发和采样,具体哪个边沿采样哪个边沿触发是根据CPHA来决定的
③ 不规定一次时序传输的字节数,但是要和从机能一次接收的字节数保
持一致
④ 可设置数据传输字节是先高后低还是先低后高
⑤ 根据时序图可知数据接收和发送是同时进行的,也就是全双工通信

4. RS323

5. RS485

通信协议

1. Modbus

简介:modbus是一种串行半双工的通信协议,主要有以下几个种类:
Modbus-RTU+Modbus-ASCII
Modbus-TCP
Modbus-Plus
一般的话,一个设备只会有以上的一种协议

  一般来说,Modbus-RTU+Modbus-ASCII主要应用在RS-232,RS485,RS-422上,在工业上应用较多。Modbus-RTU是一种紧凑的,采用2进制的数据表示方式,不方便人们阅读,而Modbus-ASCII方便阅读,但是比较麻烦。目前来说,主要还是用Modbus-RTU类型,下面主要介绍Modbus——RTU格式的使用方法。

1.1. 帧组成结构

一帧的结构主要由:设备地址+功能码+数据+RTC校验组成

地址:占1字节,范围0-255,有效范围为1-257,其他的都是特殊用途的,比如255就是广播地址,即所有的从设备都响应。一般正常通信的话是根据主机发送的从机地址来辨别主机是和哪个从机进行通信的。

功能码:功能码顾名思义就是表示你这条数据帧是准备干嘛的,是读还是写这些。

数据:功能码的不同数据也会有所不同,这个等到下面的实战讲解再提

RTC校验:实际上就是通过一种公式将所有数据帧计算成一个值,然后接收和发送的对比这个值,如果是一模一样的说明发送正确,只要有一个位的数据出错RTC校验出来的值就会不同。

1.2. 实战案例讲解

先介绍一下我们主要使用的3个功能码

0x03:读n个寄存器的数据
0x06:写一个寄存器的数据
0x10:写多个寄存器的数据

假设我主机向从机发送帧数据为:01 03 0101 0001 840A
从机回复数据为       :01 03 02 1234 B533

  实际的数据帧是用字节表示的,为了方便阅读我把相同功能的字节整合在一起成为2个字节,根据上面所讲的数据帧的结构和功能码的作用我们大致可读出这两句指令所代表的的含义。

主机的数据帧解析
01为设备地址

03为功能码

0101这两个字节因为都是代表读取的寄存器的地址,寄存器地址是要16位表示的,因此我给他们整合在一起

0001是指我只读1个寄存器的数据

840A是RTC计算出来的16位的校验位,这个是软件计算出来的,我们真正通过协议发送的时候是不需要加这两个字节的。

从机回复数据解析
前面两个字节是一样的,我们不去理会,从02开始,意思是读取数据的字节数是2个,为什么是2个?因为寄存器地址是16位的,就是2字节,所以我们一般收到的从机回复的读取数据的字节数都是2的倍数,紧跟着1234是数据内容,这里是我瞎写的,真正实际读取的话,读取到的就是你这个寄存器内部的实际值是多少这里就会显示多少。后面就不用说了,也是校验位,也是通过返回的数据帧软件自动计算出来的

再用两个例子来说明一下
主发:01 06 0000 0001 480A
从回:01 06 0000 0001 480A
解释:在设备1中修改其寄存器0000的值为0001发送的释义相同。

主发:02 10 0000 0001 02 1122 2A19
从回:02 10 0000 0001 01C9
解释:在设备2中的0000为起始地址连续修改0001(即修改1个寄存器的值)个寄存器的值,一共2个字节的内容为为1122,从设备回复你修改的寄存器起始地址及修改的个数即可,内容不必回复,因为有校验位核对。

主发:03 10 0000 0002 04 1122 3344 425A
从回:03 10 0000 0002 41C8
解释:在从设备3中的0000为起始地址连续修改0002个寄存器的值,一共4个字节的内容为1122和3344,校验位为425A,从机回复内容同上。

常用通信时序之UART、IIC、SPI(基于STM32)相关推荐

  1. 单片机-硬件接口(UART/IIC/SPI/RS232/USB/CAN)异同

    1.中文名  USART:通用同步异步收发器   UART(Universal Asynchronous Receiver Transmitter:通用异步收发器)  I2C(INTER IC BUS ...

  2. 0.96寸OLED显示屏标准库移植HAL库(模拟IIC) - 基于STM32

    ** 0.96寸OLED显示屏标准库移植HAL库,使用模拟IIC ** 由于项目的需要使用OLED屏显示,并且现有的项目程序是基于HAL库编写的,而手头能找到的程序是标准库的驱动程序,大概看了一下代码 ...

  3. IIC通讯 | 基于STM32的LM75模块的使用以及故障排查

    开幕先抱怨一下,小小模块没有说明文档,客服一问三不知,原理图也不提供,害人不浅,啊啊啊啊啊. 最初的设计中,LM75模块的电路是设计在了板子上 后来为了测温更加方便准确,选择了外接的方案,于是板子上只 ...

  4. IIC,SPI,UART,单总线

    IIC与SPI通信 IIC SPI通信 IIC与SPI的比较 UART 单总线 因为面试时被问到IIC和SPI通信,所以又重新学习了一下. IIC IIC顾名思义就是两根线,一根SCL(时钟线),一根 ...

  5. 1024之牛客之错误笔记+uart/IIC/232/485/SPI总结

    目录 牛客之错误笔记: uart/IIC/232/485/SPI总结: 牛客之错误笔记: [1.转义字符    \"                 %%     "是用\转义 % ...

  6. android 串口通信_使用UART与ZYBO进行通信常用外设设计方案

    作者:Wilson Qiu,Xilinx工程师 常用外设设计 使用UART与ZYBO进行通信 ZYNQ学习过程中一个重要环节是进行调试,当然在SDK中进行调试时,设置断点进行单步调试非常高效.但是ZY ...

  7. 快速对比UART、SPI、I2C通信的区别与应用

    参考:带你快速对比SPI.UART.I2C通信的区别与应用! 作者:一口Linux 网址:https://mp.weixin.qq.com/s/4_RSM2jk2W6nTboO1W8HCw 电子设备之 ...

  8. UART、SPI、I2C串行通讯协议解释 同步/异步 全双工/半双工通信含义

    欢迎加入QQ技术交流群:100479172 一.什么是同步/异步通信? 同步通信:一方发送,另一方应答,否则不进行下一次传输(带时钟同步信号传输). 异步通信:一方发送,不考虑另一方是否收到,直接进行 ...

  9. 基于stm32单片机的模拟IIC时序(附源码)

    我下面要说的是基于stm32单片机的模拟IIC时序,以及是一些要注意的事项:结合自己所做的MMA7455加速度传感器,我把模拟IIC的源代码贴了出来,大家可以参考一下. 1.因为在IIC协议中,当总线 ...

最新文章

  1. test markdown
  2. c++学习笔记内联函数,函数重载,默认参数
  3. 剑指offer:数组中只出现一次的数字
  4. go语言基础到提高(13)-同步
  5. 抽取+生成:一种基于背景知识的参考感知网络对话模型
  6. python简笔画绘制 数据驱动绘图_python:绘制枫叶简笔画
  7. SAP Spartacus运行时错误 - The pipe cxUrl could not be found!
  8. html中只能上传文件word,HTML文件表单,接受Word文档(HTML file form, accept Word documents)...
  9. java forkjoinpool_Java并发——Fork/Join框架与ForkJoinPool
  10. 为什么开发环境如此之乱
  11. 陈纪修老师《数学分析》 第07章:定积分 笔记
  12. Manjaro Gnome Hidpi 缩放问题
  13. 小程序如何cdn加速服务器,小程序能用cdn加速吗
  14. mysql聚合函数匹配_MySQL 05章_模糊查询和聚合函数
  15. windows下使用精灵标注图片
  16. 2017滴滴校招 数字和为sum的方法数(DP)
  17. ios微信多开教程(最简单实用 亲测可用)
  18. C语言学习日记(9)——用C语言写一个爱心
  19. vue 实现静默打印、打印预览
  20. 员工股权激励_激励技术员工的5种方法

热门文章

  1. vue 给标签添加data属性_在Vue中获取自定义属性方法:data-id的实例
  2. python导出excel数据表中追加数据_python pandas在已存在的excel中追加数据
  3. 往数组里添加键值对_框架都是花哨的东西!js才是根基,分享一下给原生js数组的操作...
  4. 慢日志定位到备份锁表Waiting for global read lock原因
  5. MySQL分页查询中该避开的坑
  6. java快速排序泛型_泛型算法_快速排序源码
  7. nexus+7+android+5.0++wifi+代理,谷歌Nexus5吃上安卓8.0:除了WiFi全不能正常工作
  8. java string传递_Java,将String从一种方法传递到另一种方法
  9. python中module错误_python错误:“module”对象不可调用数学中心
  10. # Please enter the commit message for your changes. Lines starting # with ‘#‘ will be ignored