新手向:使用STM32通过RS485通信接口控制步进电机

新手向:使用STM32通过RS485通信接口控制步进电机

准备工作

本文使用的STM32芯片是STM32F407ZGTx,使用的电机是57步进电机,驱动器是用的是时代超群的RS485总线一体化步进电机驱动器(42 型:ZD-M42P-485)。使用到的其他设备有:MOXA盒(串口调试),ST-LINK/V2(下程序),另外电源、电源线以及其他电子设备等忽略不计。

使用到的软件有:Keil uVision5,STM32CubeMX,SSCOM v5.10a(串口调试助手),M42P-S-Too(封装好的直接发串口数据控制电机的软件)

硬件调试

先放一个硬件接口图

最开始的时候,对板子还不太熟悉,我们想先确认一下电机的运动状态,以及驱动器的串口指令等等。因此,采用计算机直接发送串口指令到MOXA盒,再将串口数据传入RS485驱动器,最后再驱动电机。

计算机直接发送串口指令可以使用M42P-S-Too(封装好的直接发串口数据控制电机的软件),直接控制电机。并且软件底部会有对应的串口的指令。

RS485驱动器电气结构图:

RS485串口通讯的相关原理可以参考以下链接:

终于讲透了,史上最详细的RS485串口通讯!-CSDN博客

【正点原子STM32】RS485串行通信标准(串口基础协议 和 MODBUS协议、总线连接、通信电路、通信波形图、RS485相关HAL库驱动、RS485配置步骤、)_stm32 rs485-CSDN博客

通过以上方法,可以让电机初步转起来。

软件调试

这里讲一个关键的点。在面对不同的STM32的芯片的时候,在我经过了两天的尝试之后发现,建立工程最好的办法就是借助STM32CubeMX。如果是自己按照以前正点原子的教程自己来添加文件夹一步步设置的话,面对不同的库(正点原子的是标准库,这里使用的是HAL库)不同的芯片,很容易出现其他问题。当然STM32CubeMX生成的工程文档也是基于HAL库来的。

设置好需要用的端口,通信接口,引脚之后,点击右上角GENERATE CODE,即可直接生成工程文件。

这里的ioc文件就是CubeMX的工程,下次可以直接从这里打开。

点击MDK-ARM文件夹,里面的.uvprojx格式的文件,就是Keil所需的工程文件。

打开Keil,在main函数中直接可以开始编写程序,CubeMX生成的工程文档使用起来会比较方便。

这里给一个新建工程文档的教程参考:

如何使用STM32CubeMX快速配置工程【简单入门】_哔哩哔哩_bilibili

我在调试电机的时候,先将要传入RS485的控制电机的数据传入RS422的端口,这样可以通过MOXA盒,用串口助手来验证我的通信。

c 复制代码
// 电机控制指令数组
const uint8_t resetCmd[] = {0x01, 0x06, 0x07, 0xD0, 0x00, 0x01, 0x48, 0x87};  // 复位指令
const uint8_t forwardCmd[] = {0x01, 0x10, 0x07, 0xD4, 0x00, 0x02, 0x04, 
                             0x00, 0x00, 0x03, 0xE8, 0xD9, 0x8E};  // 正转1000步
const uint8_t reverseCmd[] = {0x01, 0x10, 0x07, 0xD6, 0x00, 0x02, 0x04, 
                             0x00, 0x00, 0x03, 0xE8, 0x58, 0x57};  // 反转1000步

void timer_1Hz_callback(void *p_arg)  // 电机控制任务
{
    OS_ERR err;
    p_arg = p_arg;
    static uint8_t initFlag = 0;  // 初始化标志
    static uint8_t direction = 0;  // 电机方向:0=正转, 1=反转
    

    while(1) {
        OSTimeDly(4000, OS_OPT_TIME_PERIODIC, &err);  // 4秒延时
        
        if(initFlag == 0) {
            // 首次执行:发送复位指令
            HAL_UART_Transmit(&huart1, (uint8_t*)resetCmd, sizeof(resetCmd), 100);
            initFlag = 1;
            direction = 0;
            continue;  // 跳过本次循环剩余部分
        }
        
        if(direction == 0) {
            // 正转指令
            HAL_UART_Transmit(&huart1, (uint8_t*)forwardCmd, sizeof(forwardCmd), 100);
    					OSTimeDly(5000, OS_OPT_TIME_DLY, &err);  // 延时5秒[5](@ref)
    					HAL_UART_Transmit(&huart1, (uint8_t*)resetCmd, sizeof(resetCmd), 100);
            direction = 1;  // 下次反转
        } else {
            // 反转指令
            HAL_UART_Transmit(&huart1, (uint8_t*)reverseCmd, sizeof(reverseCmd), 100);
    					OSTimeDly(5000, OS_OPT_TIME_DLY, &err);  // 延时5秒[5](@ref)
    					HAL_UART_Transmit(&huart1, (uint8_t*)resetCmd, sizeof(resetCmd), 100);
            direction = 0;  // 下次正转
        }
        
        HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_9);  // 翻转LED1
    }

}

串口助手SSCOM v5.10a中会收到这个以下代码:

然后将该部分代码改写之后,从RS485通信接口输出即可。但是需要注意,RS485通信跟RS422通信不同,RS485需要通过频繁的切发送/接收来完成通信。

c 复制代码
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_SET);  // 485切发送模式

/*xxxxx(这里补充你要发送的代码)*/

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_RESET);  // 485切接收模式

结语

本文的需求是控制步进电机的运动,来控制吊舱的转动,是一个角动量守恒的一个科普展演。需求很简单,但由于博主研究方向并不是嵌入式软件,所以不太熟悉,仅限于新手向参考。欢迎跟各位多多交流!

相关推荐
DIY机器人工房4 小时前
简单理解:新唐 NuMicro M483这款MCU
stm32·diy机器人工房·新唐 numicro m480·m480
某林2125 小时前
基于SLAM Toolbox的移动机器人激光建图算法原理与工程实现
stm32·嵌入式硬件·算法·slam
DTI07016 小时前
xilinx的vivado工具综合一直转圈圈,卡死后如何解决?
嵌入式硬件·fpga开发
点灯小铭8 小时前
基于单片机的去皮计价与超重报警电子秤设计与实现
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
章鱼哥嵌入式开发10 小时前
【 STM32 ADC电压采集与串口显示系统】
stm32·单片机·课程设计·嵌入式学习·实验室测量
树上掉下一只鱼10 小时前
STM32F4xxx系列 - DAC生成噪声波
stm32
HappyShengxiang11 小时前
TI发布全新Cortex-M33的MCU产品MSPM33C321A
单片机·嵌入式硬件·mcu·电赛
✧˖‹gσσ∂ иιghт›✧12 小时前
stm32 cube max+keil5的环境怎么printf重定向
stm32·单片机·嵌入式硬件
芋头莎莎13 小时前
keil 4 51单片机的安装教程
单片机·嵌入式硬件·51单片机
xingzhemengyou113 小时前
STM32 时钟树
stm32·单片机