当前位置:   article > 正文

【教程】用STM32 MotorControl Workbench 5.4.3(FOC电机库)从零创建一个工程,正弦波驱动联控智能24V无刷电机_stm32电机库

stm32电机库

联控智能24V无刷电机FOC5.4.3工程下载地址:百度网盘 请输入提取码

本教程采用联控智能STM32F405RG低压单电机开发板,采用的无刷电机为联控智能24V无刷电机,如下图所示。

单片机晶振大小为8MHz,驱动电机使用了3个IR2101S预驱芯片和6个IRF540N N-MOS管。

单片机的运行频率为84MHz。虽然STM32F405RG的最高运行频率是168MHz,但是可能是因为板子上滤波电容的滤波效果不好,在168MHz频率下运行程序,电机转一会自动就停了,通过调试器可以发现进入了Hard Fault。单片机的运行频率越高,对滤波电容的质量要求也就越高,尤其是VCAP 2.2μF电容,不然即使程序是正确的,也会莫名其妙进入HardFault,而且经常是刚进入一个函数,第一句话都还没执行就HardFault了。把单片机主频降至84MHz,而保持APB1时钟42MHz,APB2时钟84MHz不变,就能解决电机转一会儿就自动停下,程序卡死的问题。

另外,调试电机时,最好采用可调电压的稳压电源,这样的电源可以配置电流保护模式,比如可以配置到0.6A,这样板子的最大电流就不会超过0.6A,可以在开发过程中有效地保护电机和开发板,防止MOS管因程序问题,电流过大而烧坏。

笔者使用的电机库是5.4.3非FULL版本。注意电机库是分为FULL版本和非FULL版本的。FULL版本是完全开源的版本,在ST官网是需要申请后才能下载的(笔者就没申请通过,下载不了)。非FULL版本的代码没有完全开源,可以在ST官网直接下载,不开源的代码在工程中是一个lib库。

首先,启动MotorControl Workbench 5.4.3软件:

新建一个空白工程:

下面这些全部保持默认设置,直接点击OK:

然后选择单片机。低压板的单片机用的是STM32F405RG,但是里面却没有405的选项,所以选一个最接近的407IG:

然后,我们将转子位置检测方式设为霍尔传感器方式,对话框中的其他配置不用动:

电源供电电压检测配置:电机的额定电压为24V,板子的工作电压为2~32V(软件检测到电压不对将无法启动电机,可起到保护作用)

根据板子原理图上的分压电阻配置Bus Voltage Sensing:

联控智能板子上默认没有焊热敏电阻,所以把Temperature Sensing的勾去掉:

相电流检测电阻和运放放大倍数的配置:

板子上相电流检测电阻的大小为0.05Ω,经过运放放大5倍,然后叠加上VREF(=3.3V÷2)后,送到单片机的ADC通道上。

也就是:放大后的电压=1.65+5×放大前的电阻电压

过流保护:因为运放叠加了1.65V的VREF上去,所以把电流阈值设置为2.5V。相电流过大时自动关闭电机。

——————————————————————————————————————————————————————

接下来就比较重要了,涉及到了电机的参数。

这款电机参数:

极对数(Pole Paires)为2极对,最大转速(电机上面写了的)是3000rpm,额定电流1.8Apk,额定电压24V,相电阻Rs为1.5Ω,相电感Ls为0.6mH,反电动势B-Emf constant为4.0Vrms/krpm(Vrms是电压有效值,krpm是每分钟几千转)。

霍尔传感器的安装角度为120°(决定了霍尔值的取值范围),放置的电角度为300°。

不采用编码器,所以去掉Quadrature encoder前面的勾。

Torque和Flux的PI值的配置也很重要,这个填错了,电机能转起来但是电流会特别大!其他的保持默认即可。

电机库支持按键启动或关闭电机,但是这是用外部中断实现的,没有消抖的功能!我们取消勾选这个功能,一会儿自己实现带消抖的按键起停功能:

配置电机引脚,霍尔引脚还有串口引脚:

根据开发板原理图,配置相电流和电源电压检测用的ADC引脚:

保存工程,然后点击代码生成按钮:

选择开发工具为Keil MDK 5,然后开始生成工程:

工程生成完了,还需要RUN STM32CubeMX一下,配置系统时钟,以及按键检测引脚。

先配置启动和关闭电机的按键(PC7),带上拉电阻输入,按下时按键为低电平:

配置时钟树,系统时钟设为84MHz,APB1时钟为42MHz,APB2时钟为84MHz,避免因为板子上滤波电容的问题,单片机在高频率下运行不稳定而进入HardFault,电机转一会儿就自动停转

配置完了之后,点击GENERATE CODE生成工程,用Keil打开,改下main.c代码,加上串口打印,还有按键起停的代码。

包含stdio.h头文件:

  1. /* USER CODE BEGIN Includes */
  2. #include <stdio.h>
  3. /* USER CODE END Includes */

重定向printf函数到串口3:

  1. /* Private user code ---------------------------------------------------------*/
  2. /* USER CODE BEGIN 0 */
  3. int fputc(int ch, FILE *fp)
  4. {
  5. if (fp == stdout)
  6. {
  7. if (ch == '\n')
  8. HAL_UART_Transmit(&huart3, (uint8_t *)"\r\n", 2, HAL_MAX_DELAY);
  9. else
  10. HAL_UART_Transmit(&huart3, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
  11. return ch;
  12. }
  13. return EOF;
  14. }
  15. /* USER CODE END 0 */

main函数里面加上printf打印,以及按键起停(带按键消抖)的功能:

一定要保证刚才配置电机工程的时候取消了Start/Stop Button的勾选,以免生成的代码中含有EXTI中断处理的代码,按键按一下处理两遍,按下按键后电机启动又马上停止。

还有就是,启动电机前必须要执行MC_ProgramSpeedRampMotor1,不然会出错!这个在电机库的注释里面是说了的:

  * One of the following commands must be executed before calling MC_StartMotor1():
  *
  * - MC_ProgramSpeedRampMotor1()
  * - MC_ProgramTorqueRampMotor1()
  * - MC_SetCurrentReferenceMotor1()
  *
  * Failing to do so results in an unpredictable behaviour.

  1. /* USER CODE BEGIN 2 */
  2. printf("STM32F405RG Motor\n");
  3. printf("SystemCoreClock=%u\n", SystemCoreClock);
  4. /* USER CODE END 2 */
  5. /* Infinite loop */
  6. /* USER CODE BEGIN WHILE */
  7. while (1)
  8. {
  9. if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) == GPIO_PIN_RESET)
  10. {
  11. HAL_Delay(15);
  12. if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) == GPIO_PIN_RESET)
  13. {
  14. if (MC_GetSTMStateMotor1() == IDLE)
  15. {
  16. printf("Motor is started!\n");
  17. MC_ProgramSpeedRampMotor1(200, 100);
  18. MC_StartMotor1();
  19. }
  20. else
  21. {
  22. printf("Motor is stopped!\n");
  23. MC_StopMotor1();
  24. }
  25. while (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) == GPIO_PIN_RESET)
  26. HAL_Delay(15);
  27. }
  28. }
  29. /* USER CODE END WHILE */
  30. /* USER CODE BEGIN 3 */
  31. }
  32. /* USER CODE END 3 */

编译代码,下载到板子运行。板子的供电电压为24V。(联控智能的板子上没有复位键,需要关闭电源再打开,程序才真正开始运行)

按下按键,可以发现电机可以转起来,而且可以转很久不会自动停。再次按下按键,电机才停转。

---------------------------------------------------------------------------------------------------------------------------------------------------------------

HardFault错误定位代码:

  1. void HardFault_Handler(void)
  2. {
  3. /* USER CODE BEGIN HardFault_IRQn 0 */
  4. uint32_t addr = 0, *mem;
  5. mem = (uint32_t *)__current_sp();
  6. if (mem >= (uint32_t *)0x20000000 && mem < (uint32_t *)0x20020000 - 5)
  7. addr = mem[5];
  8. /* USER CODE END HardFault_IRQn 0 */
  9. TSK_HardwareFaultTask();
  10. printf("Hard Error! addr=0x%08x\n", addr);
  11. /* Go to infinite loop when Hard Fault exception occurs */
  12. while (1);
  13. }

这个代码可以打印出出错的代码的具体位置。可以在Keil中根据Flash地址定位到出错代码所在的文件和行数。(注意这里的addr实际上是出错代码的下一行代码的位置)

不过这在本工程里面没什么用,因为电机自动停转时遇到的HardFault是硬件引起的。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/247989
推荐阅读
相关标签
  

闽ICP备14008679号