本文章主要讲解使用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!!!!一定要看清!!!

编程

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

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

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

可以直接添加到你们自己的工程中,通过单片机直接发送,注意一点哦,这些是我加过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之间如果不加任何延时等待的话,会出现第二个发送函数没法发送出去的情况,针对于此我查找了

解决USART的DMA连续发送异常问题_串口dma发送数据出错-CSDN博客

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

 

对单片机感兴趣但时常因为一个bug解决不了的,建议加群,我喜欢聚在一起唠嗑,有写好的有趣的小demo我也会分享在群里哦

 

附带资源

清单:1,北京时代超群电机的上位机        2,北京时代超群电机的操作手册

 

 

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐