MyIsunny

 

stm32HAL库通过MODBUS,RS485,控制伺服电机(已实现验证)


本文章主要讲解使用stm32驱动AIMtor的伺服电机(自带驱动器版本),北京时代超群电机厂产

基础必备知识
在讲解之前,首先得明白MODBUS和RS485到底是啥东西:

https://blog.csdn.net/weixin_49576307/article/details/132231422?fromshare=blogdetail&sharetype=blogdetail&sharerId=132231422&sharerefer=PC&sharesource=m0_61763784&sharefrom=from_link

如果你了解了这俩东西之后去驱动这个就很简单啦,也就是说单片机只需要输出一个串口信号,给伺服电机发信息就行。

硬件选择
只需要去网上购买一个TTL转RS485的转换模块即可,这里尤为注意!!!

1,不要购买野火的那个模块,那个模块的接收和发送需要你自己去通过IO口控制,正常我们去控制伺服电机是不会这样控制的,所以没有这个特别需求的话,千万不要买!!!

2,看清模块手册,有的模块手册比如野火的这款,左边是TX接TX!!!!一定要看清!!!
image


编程
DMA+空闲中断
好,在搞清上述两点之后,我们就可以去编程控制了,博主采用了CUMX+keil的编程方式去控制

串口部分采用DMA转运加空闲中断的方式去发送和接收伺服电机的HEX数据包,初始化设置的教程参考

STM32串口通信的三种方式———HAL库实现_stm32 hal 串口-CSDN博客

文章最后一个大节,直接照抄即可。

CRC实现
MODBUS.C
`#include "MODBUS.h"

size_t size;
uint16_t crc_16;
uint8_t crc_8[2];

/*
* @name MODBUS_Sent
* @brief MODBUS数据发送
* @param data->数组指针,size->长度
*/
void MODBUS_Sent(uint8_t *data,uint8_t size)
{
// size=sizeof(data)/sizeof(data[0]);
crc_16=CRC_Check(data,size);
crc_8[1]=crc_16&0xff;
crc_8[0]=(crc_16>>8)&0xff;

HAL_UART_Transmit_DMA(&huart1,data,size);
while(huart1.gState!=HAL_UART_STATE_READY)
{
	HAL_Delay(1);
}
HAL_UART_Transmit_DMA(&huart1,crc_8,sizeof(crc_8));

}

/*
* @name CRC_Check
* @brief CRC校验
* @param CRC_Ptr->数组指针,LEN->长度
* @retval CRC校验值
*/
uint16_t CRC_Check(uint8_t *CRC_Ptr,uint8_t LEN)
{
uint16_t CRC_Value = 0;
uint8_t i = 0;
uint8_t j = 0;

CRC_Value = 0xffff;
for(i=0;i<LEN;i++)  //LEN为数组长度
{
    CRC_Value ^= *(CRC_Ptr+i);
    for(j=0;j<8;j++)
    {
        if(CRC_Value & 0x00001)
            CRC_Value = (CRC_Value >> 1) ^ 0xA001;
        else
            CRC_Value = (CRC_Value >> 1);
    }
}
CRC_Value = ((CRC_Value >> 8) +  (CRC_Value << 8)); //交换高低字节

return CRC_Value;

}

`
​上述代码实现了CRC校验+发送的功能,前提是你已经跟着上面的链接完成了DMA转运+空闲中断的基本配置并成功实现。
MODBUS.h

#ifndef __MODBUS_H
#define __MODBUS_H

#include "main.h"
void MODBUS_Sent(uint8_t *data,uint8_t size);
uint16_t CRC_Check(uint8_t *CRC_Ptr,uint8_t LEN);
void MODBUS_Moter_Command(void);



#endif

​​​主要代码就这些,后面的话就是博主自己写的一些交互功能,比如按键控制电机使能或失能

这里展出一些博主通过上位机的发送函数以及自己的研究记录后,自己记录的一些功能命令包
image

可以直接添加到你们自己的工程中,通过单片机直接发送,注意一点哦,这些是我加过CRC校验的,单片机中的代码在发送时只需要发送内容即可,CRC校验位单片机可以自己计算并发送。

一些插曲
值得一提的是,在发送代码段中两个HAL_UART_Transmit_DMA挨在一块会出问题

	HAL_UART_Transmit_DMA(&huart1,data,size);
	while(huart1.gState!=HAL_UART_STATE_READY)
	{
		HAL_Delay(1);
	}
	HAL_UART_Transmit_DMA(&huart1,crc_8,sizeof(crc_8));


这一段实际上困扰了一段时间,因为我发现在两个HAL_UART_Transmit_DMA之间如果不加任何延时等待的话,会出现第二个发送函数没法发送出去的情况,针对于此我查找了

https://blog.csdn.net/m0_56377077/article/details/145738529?fromshare=blogdetail&sharetype=blogdetail&sharerId=145738529&sharerefer=PC&sharesource=m0_61763784&sharefrom=from_link

这篇博客给了多种方案,我试过之后,经验证,博主用的这个应该是很稳的,至少目前没出错

​获取方式:qq群1079267694

posted on 2026-01-27 11:54  MyIsunny  阅读(3)  评论(0)    收藏  举报

导航