飞道的博客

STM32 使用IQmath实现SVPWM 正弦波无刷电机控制

426人阅读  评论(0)

         带有浮点运算的MCU在市场上已经越来越多了,但是便宜好开发的却没有。可不可以使用我们常用的ST的103系列的MCU来做一个svpwm的控制器呢?当然是可以了,但是直接使用不太行,因为M3内核的MCU不具备浮点运算功能,F4系列的具有浮点运算功能,可惜价格不便宜,假货还挺多。在这里介绍一下TI的浮点运算库,IQmath。以及如何应用在SVPWM无刷电机控制,充分降低控制器的成本。

IQmath优势:

        用于定点处理器的数学函数库,加快了计算浮点值的速度。

提供Sin,cos,tan,arcsin,arccos,sqrt,fractional mpy,dv等的计算

在以下应用领域可以提高处理速度:

        电机控制

        伺服控制

        音频/图像编码和解码

        定点Q数学

        图形旋转 :根据应用要求调节分辨率

        指定GLOBAL_Q24:可在定点和浮点器件之间实现代码的无缝兼容性。

我们这里主要是对电机控制的应用,下面我们一起看一下程序。


  
  1. case Ready:
  2. Offset_CurrentReading(); //读取偏移量
  3. if(AdcValue.OffestFlag == 1 && Keynob == KeyStart)
  4. {
  5. if(Controdmode == Hallloop)
  6. {
  7. mcState = Start;
  8. IqStartSet = IqStart;
  9. }
  10. else
  11. {
  12. mcState = Align;
  13. }
  14. }
  15. break;

程序中我们在判断控制模式是否为hallloop,紧接着是状态赋值,IqstartSet = Iqstart;

 电机的状态定义了一个enum


  
  1. typedef enum
  2. {
  3. Ready,
  4. Align,
  5. Start,
  6. Run,
  7. Stop,
  8. }McStateTypedef;

IQstart宏定义一个启动电流,调用__IQ().

#define IqStart        _IQ(0.28); //启动电流

在整个控制的过程中主要使用了__IQ(),没有调用其他的函数,下面我们看一下完成的控制部分代码


  
  1. void MC_Control(void)
  2. {
  3. switch(mcState)
  4. {
  5. case Ready:
  6. Offset_CurrentReading(); //读取偏移量
  7. if(AdcValue.OffestFlag == 1 && Keynob == KeyStart)
  8. {
  9. if(Controdmode == Hallloop)
  10. {
  11. mcState = Start;
  12. IqStartSet = IqStart;
  13. }
  14. else
  15. {
  16. mcState = Align;
  17. }
  18. }
  19. break;
  20. case Align:
  21. Motor_Align();
  22. if(TimeStateCount == 0)
  23. {
  24. mcState = Start;
  25. }
  26. break;
  27. case Start:
  28. if(Controdmode == Openloop)
  29. {
  30. mcState = Run;
  31. Angle.Acc_a = _IQ( 0.005); //加速度
  32. Angle.Setp_Max = 50; // 匀速度
  33. }
  34. else if(Controdmode == Hallloop)
  35. {
  36. if(StateFlag.HallStartSetFlag == 0)
  37. {
  38. StateFlag.HallStartSetFlag = 1;
  39. HallStartAngle();
  40. Angle.Acc_a = _IQ( 0.005); //加速度
  41. Angle.Setp_Max = 60; // 匀速度
  42. Angle.Temp = Hall_Three.ele_angleIQ;
  43. TimeStateCount = 5000;
  44. }
  45. HallStart();
  46. ThreeHallanglecale(); //得到角度
  47. if(TimeStateCount == 0)
  48. {
  49. mcState = Run;
  50. }
  51. }
  52. else if(Controdmode == SMOloop)
  53. {
  54. if(StateFlag.StartSetFlag == 0)
  55. {
  56. StateFlag.StartSetFlag = 1;
  57. TimeStateCount = 5000;
  58. Angle.Acc_a = _IQ( 0.005); //加速度
  59. Angle.Setp_Max = 55; // 匀速度
  60. IqStartSet = IqStart;
  61. }
  62. Motor_IFStart();
  63. if(TimeStateCount == 0)
  64. {
  65. mcState = Run;
  66. }
  67. }
  68. break;
  69. case Run:
  70. if(Controdmode == Openloop)
  71. {
  72. Motor_Open();
  73. ThreeHallanglecale(); //得到角度
  74. }
  75. else if(Controdmode == Hallloop)
  76. {
  77. Mode_Hall_loop();
  78. }
  79. else if(Controdmode == SMOloop)
  80. {
  81. SMO_SpeedLoop();
  82. }
  83. break;
  84. case Stop:
  85. StopMotor();
  86. if(Keynob == KeyStart)
  87. {
  88. mcState = Ready;
  89. StateFlag.AlignSetFlag = 0;
  90. StateFlag.StartSetFlag = 0 ;
  91. TimeStateCount = 0;
  92. Hall_Three.OldHall_State = 0;
  93. PWMZD_count = 0;
  94. Hall_Three.Speed_RPM = 0;
  95. Hall_Three.old_ele_angleIQ = 0;
  96. StateFlag.HallStartSetFlag = 0;
  97. }
  98. break;
  99. }

从实验现象来看,电机转动的还是很流畅。

ky_motor Foc 测试视频

实验开发板:开发板


转载:https://blog.csdn.net/richardgann/article/details/128445037
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场