新手向:使用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切接收模式

结语

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

相关推荐
CHENKONG_CK8 分钟前
破解制鞋打磨痛点:RFID赋能去毛刺工序自动化升级
网络·单片机·嵌入式硬件·网络协议·tcp/ip
祖力5518 分钟前
ARM时钟
嵌入式硬件·arm·时钟·imx6ull
三佛科技-1873661339733 分钟前
128KB~512KB Flash车规级MCU选型指南(FT32A072 / FT32A103 系列)
单片机·嵌入式硬件
Brilliantwxx1 小时前
【STM32】 SPI Flash 驱动开发实战:阻塞模式驱动 W25Q64(含工程代码)
开发语言·stm32·单片机·嵌入式硬件
纳祥科技1 小时前
拆机拆到芯片级:ARC功放机里的NX7026、NX8420、NX6805
单片机·音视频·智能音箱
老当益壮梁奶奶2 小时前
ARM汇编学习笔记(六):【i.MX6ULL】时钟系统与定时器(EPIT & GPT)
c语言·arm开发·嵌入式硬件·学习·51单片机
youcans_3 小时前
【嵌入式软件AI编程】16. Claude Code 与 VS Code 的协同开发
stm32·mcu·嵌入式·ai编程·claude code
Zw-awa3 小时前
按键接到 STM32 后:GPIO 输入到底读到了什么
stm32
sunoo-2293 小时前
【ARM嵌入式学习笔记Day6】一文打通i.MX6ULL时钟体系:PLL/PFD/预分频+滞回比较器全解析
arm开发·笔记·vscode·单片机·imx6ull·汇编语言
fhq_fn_jgd3 小时前
ARM 时钟
嵌入式硬件