大疆C板使用C610电调驱动M2006电机(hal库)

文章讲述了作者在尝试使用大疆C板驱动M2006电机时遇到的问题,包括代码正确但电机不转的情况,详细解析了CubeMX配置和代码移植过程,以及为何电机未响应的原因,最后提到将代码移植到STM32F103的注意事项。
摘要由CSDN通过智能技术生成

大疆C板使用C610电调驱动M2006电机,以及遇到代码没问题但电机不转的问题

前言

一般来说,加入实验室后,学长学姐们一般把任务丢给你,怎么完成任务就要靠你自己,而有些时候某些神奇的bug真的会让人听想死的。比如我在转大疆M2006电机的时候,我反复比对我的代码和官方提供的代码,明明没有问题,但就是没办法让电机转起来,这很离谱。当然,我会在文章后面,写出我自己遇到的一些bug,希望对你能有所帮助。

大疆的官方文档

大疆有提供C板的代码,去大疆官网就可以下载,本篇文章也是基于大疆提供的代码教程来写。
在这里插入图片描述

翻到底下,你就能看到大疆提供的C板的一些资料,建议仔细阅读

在这里插入图片描述

这里面是大疆提供的C板的例程,非常适合学习使用
在这里插入图片描述

CubeMX的配置

(1)首先是芯片的选择了,C板的芯片选择STM32F407IGHx。
在这里插入图片描述

(2)时钟树这边直接配置最大的168。
在这里插入图片描述

(3)RCC这边选择Crystal/Ceramic Resonator
在这里插入图片描述

(4)SYS这边选择Serial Wire
在这里插入图片描述

(5)然后是CAN引脚的配置了,这一步有点坑,就是你仔细看大疆提供的C板原理图,CAN1的引脚定义是PD0,PD1,而不是CubeMX自动配置的那个。但是CAN2就是CubaMX自动配置的那个了。所以说读原理图是个好习惯。
在这里插入图片描述
接着是Parameter Settings的配置了。
其中CubeMX里面调频率:总线频率/分频系数/(同步段+BS1+BS2+1),这个是计算公式,当然,你也可以直接和官方配置的一样,也就是按照我下面那个配置。

如果先把Time Quanta in Bit Segment 1配置成10,那么Time Quanta in Bit Segment 2就不能配置成3,这时因为Baud Rate最大只能是1Mbit/s,那么你可以先把Time Quanta in Bit Segment 1配置成14,然后再把Time Quanta in Bit Segment 2配置成3,最后再配置Time Quanta in Bit Segment 1为10,这样就可以了。

值得一提的是Operating Mode这个选项,我们在驱动电机的时候,一般是使用Normal,但它总共有四个收发模式,常规模式(Normal),回环模式(Loopback),静默模式(Silent),静默回环模式(Loopback combined with Silent),其中回环模式我用到过一次,也就是CAN自发自收点亮LED灯(没错,万物的尽头是点灯),通过点灯这个程序,会更好的了解CAN通信的原理。

同理,CAN2的配置也是一样的。

在这里插入图片描述
配置好后,直接生成工程代码就行,然后打开代码所在的文件夹。

移植大疆的代码

这里面要移植的就是四个文件(两个.c 两个.h)

打开大疆的14.CAN这个文件,然后把里面的application和bsp这两个文件复制到你自己生成的工程文件夹下。

在这里插入图片描述
然后打开你自己生成的工程文件夹,添加好文件路径,添加好文件夹下的四个文件(也有可能是五个,因为我发现大疆给的还有struct_typedef.h这个文件,另外四个是CAN_receive.c CAN_receive.h bsp_can.c bsp_can.h)

添加好后,在main.c里面添加头文件,这里都比较简单了。
在这里插入图片描述
然后在int main()里面添加can_filter_init();以及如果之后要写pid的代码,也可以再写上获取电机数据的指针,其中指针的声明在int main()外面,而指针的定义,大疆已经帮我们写好了,可以直接跳转定义去看指针里面的元素包含什么,当然这些都是后话了。

在这里插入图片描述
在这里插入图片描述
继续说回can_filter_init()这个函数,可以跳转定义看一下,这个是用来配置滤波器和掩码的,当然大疆已经帮我们配置好了,我们直接用就行了。

接着是while(1)里面的代码了,里面的两个函数,可以跳转定义看一下它的用法
在这里插入图片描述
在这里插入图片描述
函数的使用也是比较简单的,但需要注意的是,你要清楚你的电调的ID,官方的while(1)函数里面是4个ID都给值,可以驱动4个M2006电机,而自己使用的时候,只要明白自己电调的ID,就不需要4个都给值。

接着是还有一点,无论你给的是1000、还是4000、还是10000,电机都会全速转动,这很刺激,所以如果想要控制电机低速转动,就需要配合pid使用了,单纯控制速度的话,就只需要单环pid,如果需要控制电机转动角度的话,就需要配合串级pid使用了。这个又是后面的事情了。

为什么代码正确,电机却不会转

到此为止,我们的代码都已经配置好了,但是一烧录,诶,我的电机怎么不转。这里面可能有两个原因,一个是我上面说的,你的CAN1引脚没有复用成PD0与PD1,另一个就是keil自动把你代码优化了(这个是真狗)

打开魔法棒这里,选择C/C++,然后你能看到Optimization这个选项这里,可能显示的是Level 3,那么改掉它,改成Level 0,这样你的电机就可以转了。

是不是觉得有点难崩,看了半天的代码问题,结果却是keil本身的问题。

接着是移植到f103的板子上

如果你想在f103板子上驱动M2006的电机的话,注意配上一个CAN收发器。一般来说STM32搭配的收发器型号为SN65HVD230,但也可以搭配别的啦。

接着其余的配置就和f407差不多,但是f103只有一个CAN,所以官方的那四个文件还需要稍微修改修改,以及配置的时候,f407与f103的时钟树不太一样,CubeMX配置频率时候,也要重新计算一下,如果有时间,我应该还会写一篇关于移植到f103上的文章。

下面是一个示例代码,展示了如何使用STM32CubeMX控制四个M2006电机的转动。请根据你的具体需求进行适当的修改和调整。 ```c #include "main.h" #include "stm32f4xx_hal.h" // 定义PWM输出通道和引脚 #define MOTOR1_PWM_CHANNEL TIM_CHANNEL_1 #define MOTOR1_PWM_PIN GPIO_PIN_0 #define MOTOR2_PWM_CHANNEL TIM_CHANNEL_2 #define MOTOR2_PWM_PIN GPIO_PIN_1 #define MOTOR3_PWM_CHANNEL TIM_CHANNEL_3 #define MOTOR3_PWM_PIN GPIO_PIN_2 #define MOTOR4_PWM_CHANNEL TIM_CHANNEL_4 #define MOTOR4_PWM_PIN GPIO_PIN_3 // 定义PWM频率和占空比 #define PWM_FREQUENCY 20000 // PWM频率为20kHz #define PWM_RESOLUTION 1000 // PWM分辨率为1000,即占空比从0到100% TIM_HandleTypeDef htim1; void MX_GPIO_Init(void); void MX_TIM1_Init(void); int main(void) { HAL_Init(); MX_GPIO_Init(); MX_TIM1_Init(); // 启动定时器 HAL_TIM_Base_Start(&htim1); // 启动PWM输出通道 HAL_TIM_PWM_Start(&htim1, MOTOR1_PWM_CHANNEL); HAL_TIM_PWM_Start(&htim1, MOTOR2_PWM_CHANNEL); HAL_TIM_PWM_Start(&htim1, MOTOR3_PWM_CHANNEL); HAL_TIM_PWM_Start(&htim1, MOTOR4_PWM_CHANNEL); // 设置M2006电机的初始转速 __HAL_TIM_SET_COMPARE(&htim1, MOTOR1_PWM_CHANNEL, 0); __HAL_TIM_SET_COMPARE(&htim1, MOTOR2_PWM_CHANNEL, 0); __HAL_TIM_SET_COMPARE(&htim1, MOTOR3_PWM_CHANNEL, 0); __HAL_TIM_SET_COMPARE(&htim1, MOTOR4_PWM_CHANNEL, 0); while (1) { // 控制电机转动 __HAL_TIM_SET_COMPARE(&htim1, MOTOR1_PWM_CHANNEL, 500); // 设置电机1的占空比为50% __HAL_TIM_SET_COMPARE(&htim1, MOTOR2_PWM_CHANNEL, 750); // 设置电机2的占空比为75% __HAL_TIM_SET_COMPARE(&htim1, MOTOR3_PWM_CHANNEL, 250); // 设置电机3的占空比为25% __HAL_TIM_SET_COMPARE(&htim1, MOTOR4_PWM_CHANNEL, 1000); // 设置电机4的占空比为100% HAL_Delay(1000); // 延时1秒 // 停止电机转动 __HAL_TIM_SET_COMPARE(&htim1, MOTOR1_PWM_CHANNEL, 0); // 设置电机1的占空比为0% __HAL_TIM_SET_COMPARE(&htim1, MOTOR2_PWM_CHANNEL, 0); // 设置电机2的占空比为0% __HAL_TIM_SET_COMPARE(&htim1, MOTOR3_PWM_CHANNEL, 0); // 设置电机3的占空比为0% __HAL_TIM_SET_COMPARE(&htim1, MOTOR4_PWM_CHANNEL, 0); // 设置电机4的占空比为0% HAL_Delay(1000); // 延时1秒 } } void MX_GPIO_Init(void) { // 配置PWM输出引脚 GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = MOTOR1_PWM_PIN|MOTOR2_PWM_PIN|MOTOR3_PWM_PIN|MOTOR4_PWM_PIN; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF1_TIM1; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } void MX_TIM1_Init(void) { // 配置定时器 htim1.Instance = TIM1; htim1.Init.Prescaler = (HAL_RCC_GetHCLKFreq() / PWM_FREQUENCY) - 1; htim1.Init.CounterMode = TIM_COUNTERMODE_UP; htim1.Init.Period = PWM_RESOLUTION - 1; htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim1.Init.RepetitionCounter = 0; htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; if (HAL_TIM_PWM_Init(&htim1) != HAL_OK) { Error_Handler(); } TIM_OC_InitTypeDef sConfigOC = {0}; sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 0; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, MOTOR1_PWM_CHANNEL) != HAL_OK) { Error_Handler(); } if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, MOTOR2_PWM_CHANNEL) != HAL_OK) { Error_Handler(); } if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, MOTOR3_PWM_CHANNEL) != HAL_OK) { Error_Handler(); } if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, MOTOR4_PWM_CHANNEL) != HAL_OK) { Error_Handler(); } } ``` 请注意,这只是一个简单的示例代码,用于演示如何使用STM32CubeMX控制四个M2006电机的转动。你需要根据你的硬件连接和具体需求进行适当的修改和调整。还请参考STM32CubeMX和相关的STM32文档,以获得更详细和准确的配置和编程信息。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值