MODBUS协议介绍,通过MODBUS协议控制伺服电机工作

news2024/11/24 16:24:26

1.前言

modbus协议本身的介绍,请大家自行查阅资料。本文简单介绍一下如何通过MODBUS协议组装控制指令。

最近搞了一个项目,要驱动伺服电机工作。通过下位机STM32 407 100封脚 给伺服电机发控制指令。电机和下位机之前的通信采用RS485串口通信,发送和接收数据的格式使用是MODBUS协议。

2.前言

2.1 读寄存器

分为读寄存器,即从电机的寄存器里面读值,来获得一些电机的运行状态信息等。

读寄存器的格式 地址:功能码:寄存器地址:读寄存器个数:CRC校验
在这里插入图片描述

2.1 写寄存器

写寄存器,即通过往电机的寄存器里面写值,然后再通过电机内部的控制算法,控制电机运转。
写寄存器的格式,分为写单个寄存器和多个寄存器。
写单个寄存器:
地址:功能码:寄存器地址:写入数值:CRC校验
在这里插入图片描述

写多个寄存器:
地址:功能码:需要写的第一个寄存器地址:写入个数:字节数:写入数值:CRC校验

在这里插入图片描述
需要注意,这些指令都是以16进制的形式存在的。
当组装指令时,需要根据 前面组装的指令数据,生成CRC校验码。

这里提供两种生成CRC16校验码的代码,一个是动态生成,空间复杂度小,但负载大。另一个静态生成,空间复杂度大,负载小。
动态:

//MODBUS-RTU协议使用的CRC16算法
uint16_t modbus_crc16(uint8_t* data, uint16_t size)
{
    uint16_t crc = 0xFFFF;
    for (uint16_t i = 0; i < size; ++i)
    {
        crc ^= (*data++);
        for (uint8_t b = 0; b < 8; ++b)
        {
            if (!(crc & 0x1))
                crc >>= 1;
            else
            {
                crc >>= 1;
                crc ^= 0xA001;
            }
        }
    }
    return crc;
}

静态:

// 查表法计算CRC,速度快,空间复杂度大
static const uint8_t aucCRCHi[] = {
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
	0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
	0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
	0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
	0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
	0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
	0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
	0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
	0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
	0x00, 0xC1, 0x81, 0x40
};
static const uint8_t aucCRCLo[] = {
	0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
	0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
	0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
	0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
	0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
	0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
	0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
	0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
	0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
	0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
	0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
	0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
	0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
	0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
	0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
	0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
	0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
	0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
	0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
	0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
	0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
	0x41, 0x81, 0x80, 0x40
};
uint16_t CRC16_Modbus(uint8_t *pucFrame, uint8_t usLen)
{
	uint8_t  ucCRCHi = 0xFF;
	uint8_t  ucCRCLo = 0xFF;
	int iIndex;
	while (usLen--)
	{
		iIndex = ucCRCLo ^ *(pucFrame++);
		ucCRCLo = (uint8_t)(ucCRCHi ^ aucCRCHi[iIndex]);
		ucCRCHi = aucCRCLo[iIndex];
	}
	return (uint16_t)(ucCRCHi << 8 | ucCRCLo);
}

另外提供一个把16进制数字组成的字符串,计算其CRC校验码的程序:

uint16_t hexStringToCRC16(const char* hexStr) {
    size_t len = strlen(hexStr);
    if (len % 2 != 0) {
        fprintf(stderr, "Hex string must have an even number of characters.\n");
    }

    size_t dataLen = len / 2;
//	printf("dataLen =%d\n", dataLen);
    uint8_t* data = (uint8_t*)malloc(sizeof(uint8_t) * dataLen + 4);
    if (!data) {
        fprintf(stderr, "Memory allocation failed.\n");
    }

    // Convert hex string to binary data  
	
    for (size_t i = 0; i < len; i += 2) {
        sscanf(&hexStr[i], "%2hhx", &data[i / 2]);
    }
	
    // Calculate CRC-16 of the binary data  
    uint16_t crc = CRC16_Modbus(data, dataLen);

    // Free the allocated memory  
    free(data);

	data = NULL; //释放之后指向空,防止野指针

    return crc;
}

有问题,欢迎大家留言评论或者私信。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2208011.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

seaCMS v12.9代码审计学习(下半)

文章目录 admin/admin_safe.php任意文件下载CSRF 添加管理员账户CSRF配合XSS弹cookie admin/admin_safe.php任意文件下载 在admin_safe.php文件下有着这么一段代码&#xff0c;他的作用时检查action的值是否为download&#xff0c;如果为download那么将你传入的文件直接打印给…

LeetCode题练习与总结:二叉树的序列化与反序列化--297

一、题目描述 序列化是将一个数据结构或者对象转换为连续的比特位的操作&#xff0c;进而可以将转换后的数据存储在一个文件或者内存中&#xff0c;同时也可以通过网络传输到另一个计算机环境&#xff0c;采取相反方式重构得到原数据。 请设计一个算法来实现二叉树的序列化与…

校园网环境下基于OpenWRT的路由器选型与解决方案

校园网环境下基于OpenWRT的路由器选型与解决方案 网页认证(锐捷认证)解除校园网设备限制,路由器选型和解决方案 openwrt 我们学校校园网一个账号只能登录两台设备&#xff0c;多了直接就退出联网状态&#xff0c;然后校园网是基于锐捷认证进行认证的&#xff0c;然后通过ment…

基于逻辑回归实现乳腺癌预测

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

使用IDEA生成API文档

1. 在IDEA中&#xff0c;Tools->Generate JavaDoc Scope 2.Output Directory里面放&#xff0c;生成的目录。 Other command line arguments:-encoding utf-8 -charset utf-8&#xff08;解决乱码&#xff09; 3.点击ok&#xff0c;生成的效果图

构建数字文化产业链,拓展文化产业发展空间

在当今全球化和数字化的双重浪潮下&#xff0c;文化产业正以前所未有的速度进行变革和升级。作为文化与科技深度融合的产物&#xff0c;数字文化产业链正以其独特的魅力和无限的潜力&#xff0c;引领文化产业向更高层次、更广领域迈进。 数字文化产业链的构建&#xff0c;不仅…

特斯拉智驾路线影响国内OEM组织架构变革,Robotaxi重塑汽车定位搅动风云

智驾研发组织面向端到端进行调整,车企内部研发资源聚焦,智驾方案选择将快速收敛 特斯拉在智驾领域的技术方向被国内车企当作学习的范本,而技术路线的切换往往伴随组织架构的调整。特斯拉 FSD 团队人员规模在数百人,但数据积累和训练算力领先。智驾研发迈向端到端使得车企研…

QD1-P13 HTML 表单标签(form)

本节学习 HTML 表单标签&#xff1a;form ‍ 本节视频 www.bilibili.com/video/BV1n64y1U7oj?p13 ‍ 知识点1&#xff1a;form标签的用途 ​form​ 标签在HTML中用于创建一个表单&#xff0c;它允许用户输入数据&#xff0c;然后可以将这些数据发送到服务器进行处理。以下…

JS 运算符

目录 1. 赋值运算符 2. 一元运算符 2.1 自增 2.1.1 前置自增 2.1.2 后置自增 2.1.3 前置与后置自增对比 3. 比较运算符 3.1 字符串比较 4. 逻辑运算符 4.1 案例 5. 运算符优先级 1. 赋值运算符 2. 一元运算符 2.1 自增 2.1.1 前置自增 2.1.2 后置自增 2.1.3 前置与后…

户外防火值守:太阳能语音监控杆的参数及技术特点

随着假期旅游的热潮日渐高涨&#xff0c;我们游览各大景区、公园或森林区域时&#xff0c;经常会与各种智能设备不期而遇。这些高科技产品不仅提升了旅游体验&#xff0c;更在无形中保障了游客的安全与景区的环境保护。在我最近的旅行经历中&#xff0c;尤其是在深圳大鹏旅游景…

推荐几款适合跨境电商外贸的爬虫软件

在当今数据驱动的时代&#xff0c;自动化爬虫工具和软件成为了许多企业和个人获取数据的重要手段&#xff0c;特别是跨境电商、外贸等业务&#xff0c;对数据的需求非常大&#xff0c;比如对amazon、tiktok、shopee等网站数据的监测和获取。 这里会介绍6款功能强大、操作简便的…

回溯法与迭代法详解:如何从手机数字键盘生成字母组合

在这篇文章中&#xff0c;我们将详细介绍如何基于手机数字键盘的映射&#xff0c;给定一个仅包含数字 2-9 的字符串&#xff0c;输出它能够表示的所有字母组合。这是一个经典的回溯算法问题&#xff0c;适合初学者理解和掌握。 问题描述 给定一个数字字符串&#xff0c;比如 …

vue3+FullCalendar+Element-plus修改的日程安排表

实现效果 安装Fullcalendar相关插件 npm install fullcalendar/core fullcalendar/daygrid fullcalendar/timegrid fullcalendar/list fullcalendar/interaction --save代码中使用到了时间转换和element-plus&#xff0c;安装dayjs和element-plus npm install element-plus e…

03 django管理系统 - 部门管理 - 部门列表

部门管理 首先我们需要在models里定义Dept类 # 创建部门表 class Dept(models.Model):name models.CharField(max_length100)head models.CharField(max_length100)phone models.CharField(max_length15)email models.EmailField()address models.CharField(max_length2…

MySql的binlog与数据的恢复

目录 什么是binlogbinlog的作用binlog的三种模式binlog的开启数据的恢复与回滚binlog日志的删除 什么是binlog binlog我们一般叫做归档日志&#xff0c;他是mysql服务器层的日志&#xff0c;跟存储引擎无关&#xff0c;他记录的是所有DDL和DML的语句&#xff0c;不包含查询语句…

文本语义检索系统的搭建过程,涵盖了召回、排序以及Milvus召回系统、短视频推荐等相关内容

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下本文详细介绍了文本语义检索系统的搭建过程&#xff0c;涵盖了召回、排序以及Milvus召回系统的相关内容。通过使用PyTorch框架&#xff0c;我们提供了样例代码&#xff0c;以帮助读者更好地理解和实践。该系统具有广…

基于STM32的车牌识别系统

基于STM32的车牌识别系统硬件设计 在智能交通系统中&#xff0c;车牌识别技术扮演着至关重要的角色。它不仅用于道路交通监控&#xff0c;还广泛应用于小区和停车场管理、收费站管理系统、车流统计以及移动车载系统等领域。本文将详细介绍基于STM32单片机的车牌识别系统的硬件…

Vue3 + TypeScript + Vite + Echarts

Vue3 TypeScript Vite Echarts 1、创建工程 npm create vitelatestcd echarts npm install npm run dev2、安装项目依赖模块 npm install types/node --save-devnpm install vue-router4npm install animate.css --save npm install gsap --savenpm install fetch --save …

2024年源代码加密软件推荐,十款超好用的源代码加密软件推荐

在当今数字化时代&#xff0c;源代码的安全性对于企业和开发者来说至关重要。无论是为了保护知识产权&#xff0c;还是为了防止恶意攻击&#xff0c;选择一款可靠的源代码加密软件都是必不可少的。本文将为您推荐2024年十款超好用的源代码加密软件&#xff0c;帮助您在保护代码…

10款超好用的电脑加密软件推荐|2024年常用电脑加密软件排行榜

随着数字化办公的普及&#xff0c;企业的数据安全面临前所未有的挑战。文件的泄露、窃取和丢失不仅会影响企业的商业利益&#xff0c;还可能导致客户隐私泄露&#xff0c;进而影响企业声誉。因此&#xff0c;选择一款合适的加密软件来保护公司机密文件变得尤为重要。2024年&…