OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5079|回复: 7

我使用的SPWM驱动三相无刷电机的思路,希望帮忙想下速度改变的其他方式

[复制链接]

11

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
78
金钱
78
注册时间
2015-1-31
在线时间
7 小时
发表于 2015-7-21 10:10:16 | 显示全部楼层 |阅读模式
5金钱
关于正弦曲线的的sin值我用了公式法和采样点的方式,还没弄懂这两种的优劣,希望求解
首先我用一个时钟输出三路PWM
然后在时钟中断中改变占空比,因为需要相差120,所以就将三路PWM的起始占空比改变位正选线上相差为120的点,然后通过累加的方式,逐步改变占空比
     TIM4->CCR1=((sin(2*3.1415926/NUM*PWMch1)+1)*times);
      TIM4->CCR2=((sin(2*3.1415926/NUM*PWMch2)+1)*times);
      TIM4->CCR3=((sin(2*3.1415926/NUM*PWMch3)+1)*times);
这是用公式改变的方式,其中NUM为采样点个数,PWMch1表示累加数(需要循环),times是倍数

我改变速度的方式
  if(count%T==0&&flag==0)   //每T次中断改变一次占空比
count是每次中断+1   在0和采样点数之间循环,T表示T次中断后改变一次占空比,我用这种方式条件速度,自己想的,不知道大家是怎么调节的,因为后面涉及到PID条件,我这种方式总决定有些问题,忘指教

最佳答案

查看完整内容[请看2#楼]

[mw_shl_code=c,true]#include "p33fxxxx.h" #include "svm.h" //--------------------------------------------------------------------- // These are the definitions for various angles used in the SVM // routine. A 16-bit unsigned value is used as the angle variable. //用一个16位的无符号数代表角度 // The SVM algorithm determines the 60 degree sector //SVM算法决定的60°扇区 #define VECTOR1 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

7

主题

109

帖子

0

精华

初级会员

Rank: 2

积分
195
金钱
195
注册时间
2014-3-13
在线时间
47 小时
发表于 2015-7-21 10:10:17 | 显示全部楼层
[mw_shl_code=c,true]#include "p33fxxxx.h" #include "svm.h" //--------------------------------------------------------------------- // These are the definitions for various angles used in the SVM // routine. A 16-bit unsigned value is used as the angle variable. //用一个16位的无符号数代表角度 // The SVM algorithm determines the 60 degree sector //SVM算法决定的60°扇区 #define VECTOR1 0 // 0 degrees #define VECTOR2 0x2aaa // 60 degrees #define VECTOR3 0x5555 // 120 degrees #define VECTOR4 0x8000 // 180 degrees #define VECTOR5 0xaaaa // 240 degrees #define VECTOR6 0xd555 // 300 degrees #define SIXTY_DEG 0x2aaa // 60 degrees //--------------------------------------------------------------------- // This is the maximum value that may be passed to the SVM // function without overmodulation. This limit is equivalent // to 0.866, which is sqrt(3)/2. //最大值可能会超出SVM的极限,这限定了等价输出为0.866,即sin 60°; #define VOLTS_LIMIT 28300 // This sinewave lookup table has 171 entries. (1024 points per // electrical cycle -- 1024*(60/360) = 171) // The table covers 60 degrees of the sine function. //表格包含60°的正弦函数方程 最大值为32767 2^15 //int sinetable[] __attribute__((far,section(".const,r")))= const int sinetable[] = //1024/6=171 {0 ,201 ,401 ,602 ,803 ,1003 ,1204 ,1404 ,1605 ,1805 ,2005 ,2206 , 2406 ,2606 ,2806 ,3006 ,3205 ,3405 ,3605 ,3804 ,4003 ,4202 ,4401 ,4600 , 4799 ,4997 ,5195 ,5393 ,5591 ,5789 ,5986 ,6183 ,6380 ,6577 ,6773 ,6970 , 7166 ,7361 ,7557 ,7752 ,7947 ,8141 ,8335 ,8529 ,8723 ,8916 ,9109 ,9302 , 9494 ,9686 ,9877 ,10068,10259,10449,10639,10829,11018,11207,11395,11583, 11771,11958,12144,12331,12516,12701,12886,13070,13254,13437,13620,13802, 13984,14165,14346,14526,14706,14885,15063,15241,15419,15595,15772,15947, 16122,16297,16470,16643,16816,16988,17159,17330,17500,17669,17838,18006, 18173,18340,18506,18671,18835,18999,19162,19325,19487,19647,19808,19967, 20126,20284,20441,20598,20753,20908,21062,21216,21368,21520,21671,21821, 21970,22119,22266,22413,22559,22704,22848,22992,23134,23276,23417,23557, 23696,23834,23971,24107,24243,24377,24511,24644,24776,24906,25036,25165, 25293,25420,25547,25672,25796,25919,26042,26163,26283,26403,26521,26638, 26755,26870,26984,27098,27210,27321,27431,27541,27649,27756,27862,27967, 28071,28174,28276,28377}; //--------------------------------------------------------------------- // The function SVM() determines which sector the input angle is // located in. Then, the modulation angle is normalized to the current // 60 degree sector. Two angles are calculated from the normalized // angle. These two angles determine the times for the T1 and T2 // vectors. The T1 and T2 vectors are then scaled by the modulation // amplitude and the duty cycle range. Finally, the T0 vector time // is the time left over in the PWM counting period. // The SVM() function then calculates three duty cycle values based // on the T0, T1, and T2 times. The duty cycle calculation depends // on the // appropriate duty cycle values depending on the type of SVM to be // generated. //--------------------------------------------------------------------- void SVM(int volts, unsigned int angle) { //电压 角度 angle——角度 // These variables hold the normalized sector angles used to find t1, t2. // 变量 标准化 扇区 角度 unsigned int angle1, angle2; // These variables hold the space vector times. // 变量 空间矢量 unsigned int half_t0,t1,t2,tpwm; // Calculate the total PWM count period, which is twice the value in the PTPER register. // 两次PTPER寄存器的值计算PWM总数 tpwm = PTPER << 1; // Limit volts input to avoid overmodulation. // 限制输入电压,避免过调 if(volts > VOLTS_LIMIT) volts = VOLTS_LIMIT; //最大电压控制到28300 if(angle < VECTOR2) // 0° ~ 59° { angle2 = angle - VECTOR1; // Reference SVM angle to the current sector //angle2 = angle - 0° angle1 = SIXTY_DEG - angle2; // Calculate second angle referenced to sector //angle1 = 60°- angle2 t1 = sinetable[(unsigned char)(angle1 >> 6)]; // Look up values from table. // 查表 t2 = sinetable[(unsigned char)(angle2 >> 6)]; // Scale t1 to by the volts variable. t1 = ((long)t1*(long)volts) >> 15; // Scale t1 for the duty cycle range. t1 = ((long)t1*(long)tpwm) >> 15; // Scale t2 time t2 = ((long)t2*(long)volts) >> 15; t2 = ((long)t2*(long)tpwm) >> 15; half_t0 = (tpwm - t1 - t2) >> 1; // Calculate half_t0 null time from period and t1,t2 // 计算half_t0 // Calculate duty cycles for Sector 1 (0 - 59 degrees) // 计算角度在 0 ~ 59° 之间 PDC1 = t1 + t2 + half_t0; //PDC1——PWM占空比寄存器1 PDC2 = t2 + half_t0; //PDC2——PWM占空比寄存器2 PDC3 = half_t0; //PDC3——PWM占空比寄存器3 } else if(angle < VECTOR3) // 60° ~ 119° { angle2 = angle - VECTOR2; // Reference SVM angle to the current secto //angle2 = angle - 60° angle1 = SIXTY_DEG - angle2; // Calculate second angle referenced to sector //angle1 = 60° - angle2 t1 = sinetable[(unsigned char)(angle1 >> 6)]; // Look up values from table. // 查表 t2 = sinetable[(unsigned char)(angle2 >> 6)]; // Scale t1 to by the volts variable. t1 = ((long)t1*(long)volts) >> 15; // Scale t1 for the duty cycle range. t1 = ((long)t1*(long)tpwm) >> 15; // Scale t2 time t2 = ((long)t2*(long)volts) >> 15; t2 = ((long)t2*(long)tpwm) >> 15; half_t0 = (tpwm - t1 - t2) >> 1; // Calculate half_t0 null time from // period and t1,t2 // Calculate duty cycles for Sector 2 (60 - 119 degrees) // 计算角度在 60 ~ 119° 之间 PDC1 = t1 + half_t0; PDC2 = t1 + t2 + half_t0; PDC3 = half_t0; } else if(angle < VECTOR4) // 120° ~ 179° { angle2 = angle - VECTOR3; // Reference SVM angle to the current sector //angle2 = angle - 120° angle1 = SIXTY_DEG - angle2; // Calculate second angle referenced to sector //angle1 = 60° - angle2 t1 = sinetable[(unsigned char)(angle1 >> 6)]; // Look up values from table. // 查表 t2 = sinetable[(unsigned char)(angle2 >> 6)]; // Scale t1 to by the volts variable. t1 = ((long)t1*(long)volts) >> 15; // Scale t1 for the duty cycle range. t1 = ((long)t1*(long)tpwm) >> 15; // Scale t2 time t2 = ((long)t2*(long)volts) >> 15; t2 = ((long)t2*(long)tpwm) >> 15; half_t0 = (tpwm - t1 - t2) >> 1; // Calculate half_t0 null time from // period and t1,t2 // Calculate duty cycles for Sector 3 (120 - 179 degrees) // 计算角度在 120 ~ 179° 之间 PDC1 = half_t0; PDC2 = t1 + t2 + half_t0; PDC3 = t2 + half_t0; } else if(angle < VECTOR5) // 180° ~ 239° { angle2 = angle - VECTOR4; // Reference SVM angle to the current sector //angle2 = angle - 180° angle1 = SIXTY_DEG - angle2; // Calculate second angle referenced to sector //angle1 = 60° - angle2 t1 = sinetable[(unsigned char)(angle1 >> 6)]; // Look up values from table. // 查表 t2 = sinetable[(unsigned char)(angle2 >> 6)]; // Scale t1 to by the volts variable. t1 = ((long)t1*(long)volts) >> 15; // Scale t1 for the duty cycle range. t1 = ((long)t1*(long)tpwm) >> 15; // Scale t2 time t2 = ((long)t2*(long)volts) >> 15; t2 = ((long)t2*(long)tpwm) >> 15; half_t0 = (tpwm - t1 - t2) >> 1; // Calculate half_t0 null time from // period and t1,t2 // Calculate duty cycles for Sector 4 (180 - 239 degrees) // 计算角度在 180 ~ 239° 之间 PDC1 = half_t0; PDC2 = t1 + half_t0; PDC3 = t1 + t2 + half_t0; } else if(angle < VECTOR6) // 240° ~ 299° { angle2 = angle - VECTOR5; // Reference SVM angle to the current sector //angle2 = angle - 240° angle1 = SIXTY_DEG - angle2; // Calculate second angle referenced to sector //angle1 = 60° - angle2 t1 = sinetable[(unsigned char)(angle1 >> 6)]; // Look up values from table. // 查表 t2 = sinetable[(unsigned char)(angle2 >> 6)]; // Scale t1 to by the volts variable. t1 = ((long)t1*(long)volts) >> 15; // Scale t1 for the duty cycle range. t1 = ((long)t1*(long)tpwm) >> 15; // Scale t2 time t2 = ((long)t2*(long)volts) >> 15; t2 = ((long)t2*(long)tpwm) >> 15; half_t0 = (tpwm - t1 - t2) >> 1; // Calculate half_t0 null time from // period and t1,t2 // Calculate duty cycles for Sector 5 (240 - 299 degrees) // 计算角度在 240 ~ 299° 之间 PDC1 = t2 + half_t0; PDC2 = half_t0; PDC3 = t1 + t2 + half_t0; } else // 300° ~ 359° { angle2 = angle - VECTOR6; // Reference SVM angle to the current sector // angle1 = SIXTY_DEG - angle2; // Calculate second angle referenced to sector // t1 = sinetable[(unsigned char)(angle1 >> 6)]; // Look up values from table. // 查表 t2 = sinetable[(unsigned char)(angle2 >> 6)]; // Scale t1 to by the volts variable. t1 = ((long)t1*(long)volts) >> 15; // Scale t1 for the duty cycle range. t1 = ((long)t1*(long)tpwm) >> 15; // Scale t2 time t2 = ((long)t2*(long)volts) >> 15; t2 = ((long)t2*(long)tpwm) >> 15; half_t0 = (tpwm - t1 - t2) >> 1; // Calculate half_t0 null time from // period and t1,t2 // Calculate duty cycles for Sector 6 ( 300 - 359 degrees ) PDC1 = t1 + t2 + half_t0; PDC2 = half_t0; PDC3 = t1 + half_t0; } } // end SVM() [/mw_shl_code]

回复

使用道具 举报

43

主题

326

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2240
金钱
2240
注册时间
2014-10-20
在线时间
376 小时
发表于 2015-7-21 11:48:35 | 显示全部楼层
不知道楼主说的公式法和采样点法具体是指什么,没研究过SPWM,所以也没办法给出建议。
但是我有个疑问:
不知道楼主这个驱动方式的输出波型如何,驱动效率怎样。因为这里的几句代码中不仅用了浮点运算还用到了sin(),如果sin不用查表法的话速度应该会拖下不少,这样可能对控制不利。
建议楼主试试FOC方式
回复

使用道具 举报

11

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
78
金钱
78
注册时间
2015-1-31
在线时间
7 小时
 楼主| 发表于 2015-7-21 14:33:12 | 显示全部楼层
额 表述有点问题 其实就是一种是用sin算出来 一种是直接用数据保存sin个表,直接查表。   额我用sin写了 主要是sin可以直接通过改变NUM这个值直接改变采样点的个数,而查表法就得该表了。。。        SPWM其实就是正弦调制后的PWM    之后正弦波用驱动芯片换向来代替三相桥            磁场定向控制这个还不怎么了解,我之后学习下
回复

使用道具 举报

7

主题

109

帖子

0

精华

初级会员

Rank: 2

积分
195
金钱
195
注册时间
2014-3-13
在线时间
47 小时
发表于 2015-7-21 14:42:05 | 显示全部楼层
这个是MICrochip的官网的SVPWM 算法
回复

使用道具 举报

12

主题

50

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2017-9-6
在线时间
23 小时
发表于 2017-9-7 21:38:15 | 显示全部楼层
楼主还在吗  能不能讲下中断处理函数里面的SPWM程序应该怎么写  谢谢啦
回复

使用道具 举报

12

主题

50

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2017-9-6
在线时间
23 小时
发表于 2017-9-7 21:48:25 | 显示全部楼层
楼主还在吗  我看了下你写的公式  不太懂TIMES这个倍数怎么理解 求指教 谢谢啦
回复

使用道具 举报

6

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
180
金钱
180
注册时间
2012-9-6
在线时间
26 小时
发表于 2017-12-4 22:08:38 | 显示全部楼层
随风灬而逝 发表于 2015-7-21 14:42
这个是MICrochip的官网的SVPWM&nbsp;算法

试了,还是你的方法好
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-9 20:51

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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