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

2023-05-16

常用通信时序(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,从机回复内容同上。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

常用通信时序之UART、IIC、SPI(基于STM32) 的相关文章

  • (11)色块跟踪

    色块跟踪 一 查看色块追踪的文件位置 xff1a 在ros simple follower文件下的simple followe的Launch文件 二 可调整识别色块的阈值 xff0c 追踪过程中最大速度 xff0c 中距值 xff0c PI
  • (6)ROS与STM32之间的联系

    ROS与STM32之间的联系 简介两者之间的关系两者之间的通信ROS如何在代码层面去接收stm32发送过来的数据1 整体框架2 机器人底盘类3 构造函数4 主函数5 循环功能函数6 析构函数 简介 1 如何实现ROS与stm32之间的通信
  • keil 局部变量不能查看值,显示为not in scope

    关于编译器的优化 xff0c 参考网上的8051系列的说明如下 xff1a xfeff xfeff 0级优化 xff1a 1 常数折叠 xff1a 只要有可能 xff0c 编译器就执行将表达式化为常数数字的计算 xff0c 其中包括运行地址
  • 算法——均方根检波

    均方根检波 1 均方根检波技术2 高精度采样技术3 STM32的ADC4 程序工程文件 1 均方根检波技术 1 均值检波电路通常采用电容充放电电路作为平均值电路 2 由于输出为整流平均值 xff0c 要求电容充放电时间常数相等 3 电容充放
  • 二.LVGL学习——(lv_obj基础对象)

    二 LVGL学习 xff08 lv obj基础对象 xff09 1 介绍2 对象的工作机制3 对象的创建与删除4 Screen 屏幕对象5 实例代码 xff08 1 xff09 6 实例代码 xff08 2 xff09 1 介绍 LVGL是
  • 三.LVGL学习——(Buttons styles)

    三 LVGL学习 xff08 Buttons styles xff09 1 按钮对象样式 2 程序 定义三个lv style t变量 static lv style t style btn 按钮1按下前的样式变量 static lv sty
  • 51单片机串行通信原理

    51单片机串行通信原理 计算机通信串行通信异步通信同步通信数据传送速率传输方向 单片机串行口串行口特殊功能寄存器串行口控制寄存器SCON电源控制寄存器PCON 波特率的设定与计算 PC与多个单片机通信串口如何使用 计算机通信 计算机通信 x
  • 基于动态窗口法(DWA)的局部避障算法研究及MATALB的实现

    一 动态窗口法基本概念 1 1 速度采样空间 1 2 评价函数 二 基于Matlab的机器人局部避障仿真 一 动态窗口法基本概念 动态窗口方法 DynamicWindowApproach 是一种可以实现实时避障的局部规划算法 xff0c 通
  • ROS(python)如何实现1个节点同时订阅2个话题,并实现话题同步,调用同一个callback

    1 创建talker1 span class token comment usr bin env python span span class token comment license removed for brevity span s
  • java与c++的性能比较

    java与c 43 43 的性能比较 参考其他文章 一 从编译器的角度分析性能差异 许多程序员印象中可能认为c 43 43 相比较于java语言性能会更好一点 xff0c 运行速度会快一点 这其中主要是因为java刚出现的时候JIT编译技术
  • OO-数字串char*与数值int_double之间转换

    OO 数字串char 与数值int double之间转换 文章目录 OO 数字串char 与数值int double之间转换 一 任务描述二 TestCase 2 测试集 需要填空的代码源代码 xff08 可以复制在编译器里面自行调试 xf
  • Altium Designer 生成 BOM(Bill of Material)

    画好图后 xff0c 生成 BOM xff08 Bill of Material xff09 xff1a 1 选择 Reports xff08 报告 xff09 gt gt Bill of Materials 材料清单 2 选择BOM表表头
  • CAN总线协议:标准CAN和扩展CAN

    CAN通讯协议是一个载波侦听 基于报文优先级碰撞检测和仲裁 xff08 CSMA CD 43 AMP xff09 的多路访问协议 CSMA的意思是总线上的每一个节点在企图发送报文前 xff0c 必须要监听总线 xff0c 当总线处于空闲时
  • c++new操作符笔记

    c 43 43 new语句 功能 xff1a 堆区开辟一组数据 语法 xff1a new 数据类型 注意点 xff1a new创建的数据会返回该数据对应的类型指针 xff0c 另外堆区开辟的数据由程序员手动释放
  • 循环冗余校验

    循环冗余校验 xff08 CRC xff09 是一个错误检测码在数字常用网络和存储设备 xff0c 以检测到的原始数据的意外改变 进入这些系统的数据块将根据其内容的多项式除法运算的余数获得一个简短的校验值 在检索时 xff0c 将重复计算
  • 串口通讯(USART)

    对于通讯协议 xff0c 我们也以分层的方式来理解 xff0c 最基本的是把它分为物理层和协议层 物理层规定通讯系统中具有机械 电子功能部分的特性 xff0c 确保原始数据在物理媒体的传输 协议层主要规定通讯逻辑 xff0c 统一收发双方的
  • curl解析工具

    main span class token keyword package span span class token namespace com span class token punctuation span alone span c
  • c语言实现进制的转化

    编写一个函数实现数制的转换 xff0c 不用递归 xff0c 用数组实现 在主函数中输入一个十进制数 xff0c 输出相应的十六进制数 span class token macro property span class token dir
  • springboot项目多环境配置(详细步骤)

    说明 xff1a 使用springboot实现项目多环境配置 xff01 目录 一 application properties多环境配置二 application yaml多环境配置 一 application properties多环境
  • 二叉树递归遍历(C语言实现)

    span class token macro property span class token directive hash span span class token directive keyword include span spa

随机推荐

  • n&(1<<i)用法

    1 lt lt i 是将1左移i位 xff0c 即第i位为1 xff0c 其余位为0 xff1b 例如1 lt lt 2 则0001 gt 0100 n amp 1 lt lt i 是将左移i位的1与n进行按位与 xff0c 即为保留n的第
  • C++如何将数字常量转换为字符串

    头文件 xff1a include lt string gt 功能 xff1a 将数字常量转换为字符串 参数 xff1a value 返回值 xff1a 转换好的字符串 定义于头文件 std string to string int val
  • 动态数组(C语言)

    span class token macro property span class token directive hash span span class token directive keyword include span spa
  • STM32使用串口空闲中断接收不定长数据帧-USART_IT_IDLE使用(不使用DMA方式)

    STM32使用串口空闲中断接收不定长数据帧 USART IT IDLE使用 xff08 不使用DMA方式 xff09 前言串口空闲中断介绍清中断方法串口中断处理函数串口中断用到的全局变量定义串口初始化 xff08 使能接收中断 空闲中断 x
  • C语言编程规范

    一 头文件编程规范 三大原则 设计层面 xff1a 1 头文件中适合放置接口声明 xff0c 不适合放实现 2 头文件职责单一 3 头文件应向稳定的方向包含 八项规则 编码层面 xff1a 1 只能通过包含头文件的方式使用其他模块提供的接口
  • struct2数据传输格式错误

    n incompatible version 1 1 14 of the APR based Apache Tomcat Native library is installed while Tomcat requires version 1
  • 简单自定义协议的封包和解包

    简单自定义协议的封包和解包 一 通信协议1 百度百科的解释2 过于简单的通信协议引发的问题3 通信协议常见内容1 帧头2 设备地址 类型3 命令 指令4 命令类型 功能码5 数据长度6 数据7 帧尾8 校验码 4 通信协议代码实现 xff0
  • 如何计算C语言中结构体的大小:结构体内存对齐

    结构体的对齐规则 xff1a 1 第一个成员在与结构体变量偏移量为0的地址处 2 其他成员变量要对齐到某个数字 xff08 对齐数 xff09 的整数倍的地址处 xff08 对齐数 61 编译器默认的一个对齐数 与 该成员大小的较小值 xf
  • C语言实现大小端转换

    C语言实现大小端转换 xff1a 大端模式 xff1a 数据的高字节保存在内存的低地址中 xff0c 而数据的低字节保存在内存的高地址中 数字999 换算成补码就是 xff1a 0000 0011 1110 0111 xff0c 大端存储模
  • Flask全局拦截器&局部拦截器

    拦截器 在开发网站时 xff0c 不同路由下有可能需要做一些重复的判断 例如购物网站中管理员想要获取所有订单的信息 xff0c 需要首先判断管理员是否登录 xff0c 如果没有登录肯定是没有权限的 同理 xff0c 管理员的其他操作同样需要
  • C struct 简单实现 class

    以车为对象 xff0c 用C来写C 43 43 的class车 在C中没有类 xff0c 所以用struct来代替 xff0c 而class中对应的类对象函数就用函数指针来代替 span class token keyword typede
  • 2019年全国大学生电子设计竞赛综合测评题解析

    2019年全国大学生电子设计竞赛综合测评题解析 题目如下 xff0c 设计制作电路产生下列四路信号 xff1a 1 频率为19kHz 21kHz连续可调的方波脉冲信号 xff0c 幅度不小于3 2V xff1b 2 与方波同频率的正弦波信号
  • char转string

    在平常做算法题的时候 xff0c 经常会碰到遍历字符串 xff0c 然后将在将目前遍历的子串与已经遍历过的进行其他操作时 xff0c 我们需要将子串由char类型转换为string类型 以下是几种简单的方法 1 使用赋值 61 includ
  • 进程和线程、单线程、多线程和多进程

    欢迎学习交流 xff01 xff01 xff01 持续更新中 文章目录 进程和线程理论知识二者区别 单线程和多线程多线程和多进程 进程和线程 由于理论概念难以理解 xff0c 我在查资料的过程中经常能看到这样一个形象的比喻 xff1a 进程
  • Linux下TCP、UDP、UDP广播通信代码及运行

    一 网络环境配置 网络通信方式可选择一台主机里的两个虚拟机 xff0c 也可以两台主机里的两个虚拟机 xff0c 本文采用方式二 主机一IP地址为192 168 1 109 主机二IP地址为192 168 1 24 必须使两台主机在一个网段
  • 8086/8088CPU内部结构,引脚图,物理地址与逻辑地址

    文章目录 第2章 80X86微处理器的工作原理2 1 80x86处理器2 2 8086 8088微处理器2 2 1 8086 8088微处理器的内部结构2 2 2 8086 8088微处理器的寄存器 2 3 8086 8088微处理器总线功
  • 《强化学习周刊》第11期:强化学习应用之模拟到真实

    No 11 智源社区 强化学习组 强 化 学 习 研究 观点 资源 活动 关于周刊 强化学习作为人工智能领域研究热点之一 xff0c 它在模拟到真实领域中的应用研究进展与成果也引发了众多关注 为帮助研究与工程人员了解该领域的相关进展和资讯
  • 【基于GCC】STM32的printf函数重定向

    重定向c库函数printf到串口 添加 write函数 在keil借助的是fputc函数 xff0c 而gcc用fputc就不行了 xff0c 需要用 write函数 xff0c 函数原型如下 xff1a int write span cl
  • VSCode使用Clangd

    前言 在使用微软的C C 43 43 插件时 xff0c 遇到较大项目时 xff0c 代码提示速度非常的慢 xff0c 这时可以使用clangd 1 系统安装clangd 版本选择 xff1a Linux github仓库 https gi
  • 常用通信时序之UART、IIC、SPI(基于STM32)

    常用通信时序 xff08 UART IIC SPI xff0c RS232 RS485 xff09 及协议 xff08 Modbus xff09 通讯时序1 UART2 IIC3 SPI4 RS3235 RS485 通信协议1 Modbus