请选择 进入手机版 | 继续访问电脑版
搜索
查看: 1904|回复: 26

[原创] No.4 电机套件实验任务一和任务二

[复制链接]

该用户从未签到

20

主题

1039

帖子

243

蝴蝶豆

论坛元老

最后登录
2019-8-21
发表于 2018-9-2 10:18:22 | 显示全部楼层 |阅读模式
本帖最后由 子曰好人 于 2018-9-2 10:21 编辑

经过前期的准备,可以使用电机套件完成一些实验任务了。
首先是任务1和任务2的要求:
task1.png
task2.png
任务一和任务二基于workbench生成的代码来做并不难,因为代码里面提供了很多api函数并且做了很多软件上的保护,可以放心写代码,硬件不会那么容易损坏。

拿到一份陌生的代码除了了解我前面几篇帖子所说的内容外,在开始写代码前还需要了解api函数。我们可以打开mc_api.h看一看workbench都给我们提供了什么函数。
  1. /** @addtogroup MCIAPI
  2.   * @{
  3.   */

  4. typedef enum {UDRC_STATE_IDLE, UDRC_STATE_REQUESTED, UDRC_STATE_EOC} UDRC_State_t;

  5. /* Starts Motor 1 */
  6. bool MC_StartMotor1(void);

  7. /* Stops Motor 1 */
  8. bool MC_StopMotor1(void);

  9. /* Programs a Speed ramp for Motor 1 */
  10. void MC_ProgramSpeedRampMotor1( int16_t hFinalSpeed, uint16_t hDurationms );

  11. /* Programs a Torque ramp for Motor 1 */
  12. void MC_ProgramTorqueRampMotor1( int16_t hFinalTorque, uint16_t hDurationms );

  13. /* Programs a current reference for Motor 1 */
  14. void MC_SetCurrentReferenceMotor1( Curr_Components Iqdref );

  15. /* Returns the state of the last submited command for Motor 1 */
  16. MCI_CommandState_t  MC_GetCommandStateMotor1( void);

  17. /* Stops the execution of the current speed ramp for Motor 1 if any */
  18. bool MC_StopSpeedRampMotor1(void);

  19. /* Returns true if the last submited ramp for Motor 1 has completed, false otherwise */
  20. bool MC_HasRampCompletedMotor1(void);

  21. /* Returns the current mechanical rotor speed reference set for Motor 1, expressed in dHz (tenth of Hertz) */
  22. int16_t MC_GetMecSpeedReferenceMotor1(void);

  23. /* Returns the last computed average mechanical rotor speed for Motor 1, expressed in dHz (tenth of Hertz) */
  24. int16_t MC_GetMecSpeedAverageMotor1(void);

  25. /* Returns the final speed of the last ramp programmed for Motor 1, if this ramp was a speed ramp */
  26. int16_t MC_GetLastRampFinalSpeedMotor1(void);

  27. /* Returns the current Control Mode for Motor 1 (either Speed or Torque) */
  28. STC_Modality_t MC_GetControlModeMotor1(void);

  29. /* Returns the direction imposed by the last command on Motor 1 */
  30. int16_t MC_GetImposedDirectionMotor1(void);

  31. /* Returns the current reliability of the speed sensor used for Motor 1 */
  32. bool MC_GetSpeedSensorReliabilityMotor1(void);

  33. /* returns the amplitude of the phase current injected in Motor 1 */
  34. int16_t MC_GetPhaseCurrentAmplitudeMotor1(void);

  35. /* returns the amplitude of the phase voltage applied to Motor 1 */
  36. int16_t MC_GetPhaseVoltageAmplitudeMotor1(void);

  37. /* returns current Ia and Ib values for Motor 1 */
  38. Curr_Components MC_GetIabMotor1(void);

  39. /* returns current Ialpha and Ibeta values for Motor 1 */
  40. Curr_Components MC_GetIalphabetaMotor1(void);

  41. /* returns current Iq and Id values for Motor 1 */
  42. Curr_Components MC_GetIqdMotor1(void);

  43. /* returns Iq and Id reference values for Motor 1 */
  44. Curr_Components MC_GetIqdrefMotor1(void);

  45. /* returns current Vq and Vd values for Motor 1 */
  46. Volt_Components MC_GetVqdMotor1(void);

  47. /* returns current Valpha and Vbeta values for Motor 1 */
  48. Volt_Components MC_GetValphabetaMotor1(void);

  49. /* returns the electrical angle of the rotor of Motor 1, in DDP format */
  50. int16_t MC_GetElAngledppMotor1(void);

  51. /* returns the current electrical torque reference for Motor 1 */
  52. int16_t MC_GetTerefMotor1(void);

  53. /* Sets the reference value for Id */
  54. void MC_SetIdrefMotor1( int16_t hNewIdref );

  55. /* re-initializes Iq and Id references to their default values */
  56. void MC_Clear_IqdrefMotor1(void);

  57. /* Acknowledge a Motor Control fault on Motor 1 */
  58. bool MC_AcknowledgeFaultMotor1( void );

  59. /* Returns a bitfiled showing faults that occured since the State Machine of Motor 1 was moved to FAULT_NOW state */
  60. uint16_t MC_GetOccurredFaultsMotor1(void);

  61. /* Returns a bitfield showing all current faults on Motor 1 */
  62. uint16_t MC_GetCurrentFaultsMotor1(void);

  63. /* returns the current state of Motor 1 state machine */
  64. State_t  MC_GetSTMStateMotor1(void);

  65. /* programs a user defined ADC regular conversion */
  66. void MC_ProgramRegularConversion(uint8_t bChannel, uint8_t bSampleTime);

  67. /* Returns the value of the last executed user defined ADC regular conversion */
  68. uint16_t MC_GetRegularConversionValue(void);

  69. /* Returns the status of the last requested user defined ADC regular conversion */
  70. UDRC_State_t MC_GetRegularConversionState(void);
复制代码
上面这些api函数是对单个电机的操作,包含了启动、调速、调转矩、以及电机各种状态的获取。
看了任务一的要求,个人认为电机控制还是需要与外部交互好一点,电机启停不可控对于大功率的电机控制来说比较危险。
任务一代码:
  1. void task_1(void)
  2. {
  3.     MC_ProgramSpeedRampMotor1(3000/6,1000);
  4.     MC_StartMotor1();
  5.     HAL_Delay(10000);
  6.     MC_StopMotor1();
  7.     HAL_Delay(10000);
  8. }
复制代码
主函数添加的代码:
  1. /* Infinite loop */
  2.   /* USER CODE BEGIN WHILE */
  3.   while (1)
  4.   {
  5.       
  6.       if(GPIO_PIN_SET == HAL_GPIO_ReadPin(LED11_GPIO_Port,LED11_Pin))
  7.       {
  8.               task_1();
  9.       }
  10.       else
  11.       {
  12.             MC_StopMotor1();
  13.       }
  14.       realspeed = MC_GetMecSpeedAverageMotor1()*6;
  15.   /* USER CODE END WHILE */
复制代码
按键中断处理函数代码在ui_task.c这个文件中:
  1. void UI_HandleStartStopButton_cb (void)
  2. {
  3. /* USER CODE BEGIN START_STOP_BTN */
  4.   HAL_GPIO_TogglePin(LED11_GPIO_Port,LED11_Pin);
  5. /* USER CODE END START_STOP_BTN */
  6. }
复制代码
这样可以通过按键来控制任务的运行并且可以通过led的亮灭来观察系统所处的状态。LED11是驱动板上的一颗led,引脚号是PB2,可以通过cubemx来设置初始化代码。
通过monitor可以看到速度变化曲线图:
任务一速度变化截图.png
ok,任务一完成。
-------------------------------------------------------------
任务二代码:
  1. void task_2(void)
  2. {
  3.         int16_t Speed_Kp,Speed_Ki;
  4.         MCT_Handle_t * pMctHdl;
  5.         MC_ProgramSpeedRampMotor1(3000/6,1000);
  6.         MC_StartMotor1();
  7.         HAL_Delay(3000);
  8.         MC_StopMotor1();
  9.         HAL_Delay(1000);
  10.      pMctHdl = GetMCT(M1);
  11.      Speed_Kp = PID_GetKP(pMctHdl->pPIDSpeed);
  12.      Speed_Ki = PID_GetKI(pMctHdl->pPIDSpeed);
  13.      PID_SetKP(pMctHdl->pPIDSpeed,Speed_Kp*2);
  14.      PID_SetKI(pMctHdl->pPIDSpeed,Speed_Ki*2);
  15.      MC_ProgramSpeedRampMotor1(3000/6,1000);
  16.      MC_StartMotor1();
  17.      HAL_Delay(3000);
  18.      MC_StopMotor1();
  19.      HAL_Delay(1000);
  20.      PID_SetKP(pMctHdl->pPIDSpeed,Speed_Kp/2);
  21.      PID_SetKI(pMctHdl->pPIDSpeed,Speed_Ki/2);
  22.      MC_ProgramSpeedRampMotor1(3000/6,1000);
  23.      MC_StartMotor1();
  24.      HAL_Delay(3000);
  25.      MC_StopMotor1();   
  26.         HAL_GPIO_WritePin(LED11_GPIO_Port,LED11_Pin,GPIO_PIN_RESET);
  27. }
复制代码
主函数代码和任务一相同,只是把task_1()改成task_2()就行了。最后一行把LED引脚拉低是为了让代码只运行一次,多次运行可以通过按键进行操作。
任务2速度截图.png
可以看到和预期结果是一致的,原始PI调节速度快,有超调现象;Kp、Ki同时增大一倍的时候,调节加快了,并且超调现象被抑制了;当Kp、Ki同时缩小一倍时可以看到虽然调节很快,但是有严重的超调现象。

通过monitor的图形显示速度波形极大的方便调试PID的过程,ST考虑得真周到。

我在这里有个疑问,这个plotter只能显示参考速度的波形吗,还能不能添加其他变量来查看系统某个变量的变化趋势呢。之前我一直是用的Jscope,但是Jscope需要连接Jlink来查看,对于这款套件来说需要额外连接Jlink调试器,有一点点麻烦。后面调试有必要我还是会使用Jscope来查看一些变量的波形,并且分享到论坛。

任务一和任务二已完成,欢迎大家留言讨论。




回复

使用道具 举报

该用户从未签到

66

主题

1567

帖子

114

蝴蝶豆

版主

最后登录
2019-8-22
发表于 2018-9-2 18:27:19 | 显示全部楼层
这个只显示了速度波形,其实要想显示更多东西,就在通讯协议里面加就好了,ST这个是串口的,板子和上位机通讯协议已经固定了,想要显示更多可以自己搞个上位机;
回复 支持 反对

使用道具 举报

该用户从未签到

20

主题

1039

帖子

243

蝴蝶豆

论坛元老

最后登录
2019-8-21
 楼主| 发表于 2018-9-2 19:05:16 | 显示全部楼层
freeelectron 发表于 2018-9-2 18:27
这个只显示了速度波形,其实要想显示更多东西,就在通讯协议里面加就好了,ST这个是串口的,板子和上位机通 ...

好的,有时间我去了解一下通讯协议的代码,尝试显示其他变量。另外一个就是觉得plotter采样率有点低,Jscope采样率1kHz在好些时候都显得不太够用。
回复 支持 反对

使用道具 举报

该用户从未签到

15

主题

180

帖子

2

蝴蝶豆

高级会员

最后登录
2019-4-15
发表于 2018-9-14 09:20:41 | 显示全部楼层
这套板最大可以承受多大的电压,官方给的不是8-48V吗,但是我的刚到40V下面那个nucle板就烧了
回复 支持 反对

使用道具 举报

该用户从未签到

20

主题

1039

帖子

243

蝴蝶豆

论坛元老

最后登录
2019-8-21
 楼主| 发表于 2018-9-14 09:29:48 | 显示全部楼层
ff321 发表于 2018-9-14 09:20
这套板最大可以承受多大的电压,官方给的不是8-48V吗,但是我的刚到40V下面那个nucle板就烧了
...

我没试过其他电压,一直用的12V,你是不是正负极接反了
回复 支持 反对

使用道具 举报

该用户从未签到

15

主题

180

帖子

2

蝴蝶豆

高级会员

最后登录
2019-4-15
发表于 2018-9-14 09:47:12 | 显示全部楼层
子曰好人 发表于 2018-9-14 09:29
我没试过其他电压,一直用的12V,你是不是正负极接反了

不是,我是从24V慢慢升上去的,
回复 支持 反对

使用道具 举报

该用户从未签到

20

主题

1039

帖子

243

蝴蝶豆

论坛元老

最后登录
2019-8-21
 楼主| 发表于 2018-9-14 10:04:26 | 显示全部楼层
ff321 发表于 2018-9-14 09:47
不是,我是从24V慢慢升上去的,

我后面尝试一下高电压再给你反馈吧,主要是现在我也没有高电压的电机,所以一直用的12V
回复 支持 反对

使用道具 举报

该用户从未签到

15

主题

180

帖子

2

蝴蝶豆

高级会员

最后登录
2019-4-15
发表于 2018-9-14 10:57:54 | 显示全部楼层
子曰好人 发表于 2018-9-14 10:04
我后面尝试一下高电压再给你反馈吧,主要是现在我也没有高电压的电机,所以一直用的12V ...

好的,还是小心点吧
回复 支持 反对

使用道具 举报

该用户从未签到

20

主题

1039

帖子

243

蝴蝶豆

论坛元老

最后登录
2019-8-21
 楼主| 发表于 2018-9-14 18:52:52 | 显示全部楼层
ff321 发表于 2018-9-14 10:57
好的,还是小心点吧

上电40V驱动板坏了,底板还是好的,这个可能需要告知一下ST了
回复 支持 反对

使用道具 举报

该用户从未签到

0

主题

2

帖子

0

蝴蝶豆

中级会员

最后登录
2019-3-23
发表于 2018-9-19 09:21:24 | 显示全部楼层
freeelectron 发表于 2018-9-2 18:27
这个只显示了速度波形,其实要想显示更多东西,就在通讯协议里面加就好了,ST这个是串口的,板子和上位机通 ...

板子和上位机通讯协议是啥
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|手机版|Archiver|论坛-意法半导体STM32/STM8技术社区

GMT+8, 2019-8-23 09:14 , Processed in 0.103420 second(s), 21 queries , MemCache On.

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表