搜索
bottom↓
回复: 9

SVPWM零矢量的插入疑问

[复制链接]

出0入0汤圆

发表于 2014-7-16 10:13:10 | 显示全部楼层 |阅读模式
本帖最后由 zddvszw 于 2014-7-16 11:20 编辑

最近在研究SVPWM,不明白T0为什么要除以2 ,以下是代码,有做过的朋友帮我解释下咯,小弟在此感谢了。


#include <p30f6010.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.
// The SVM algorithm determines the 60 degree sector
#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

//---------------------------------------------------------------------

// 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.
#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.

int sinetable[] = {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)
{
// 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.
tpwm = PTPER << 1;

// Limit volts input to avoid overmodulation.
if(volts > VOLTS_LIMIT) volts = VOLTS_LIMIT;

if(angle < VECTOR2)
        {
        angle2 = angle - VECTOR1;                //  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 1  (0 - 59 degrees)
        PDC1 = t1 + t2 + half_t0;
        PDC2 = t2 + half_t0;
        PDC3 = half_t0;
        }

else if(angle < VECTOR3)
        {
        angle2 = angle - VECTOR2;                //  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 2  (60 - 119 degrees)
        PDC1 = t1 + half_t0;
        PDC2 = t1 + t2 + half_t0;
        PDC3 = half_t0;
        }

else if(angle < VECTOR4)
        {
        angle2 = angle - VECTOR3;                //  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 3  (120 - 179 degrees)
        PDC1 = half_t0;
        PDC2 = t1 + t2 + half_t0;
        PDC3 = t2 + half_t0;
        }

else if(angle < VECTOR5)               
        {
        angle2 = angle - VECTOR4;                //  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 4  (180 - 239 degrees)
        PDC1 = half_t0;
        PDC2 = t1 + half_t0;
        PDC3 = t1 + t2 + half_t0;
        }

else if(angle < VECTOR6)
        {
        angle2 = angle - VECTOR5;                //  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 5  (240 - 299 degrees)
        PDC1 = t2 + half_t0;
        PDC2 = half_t0;
        PDC3 = t1 + t2 + half_t0;
        }

else
        {
        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()

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

 楼主| 发表于 2014-7-16 10:23:22 | 显示全部楼层
在线等待高手解答。

出0入0汤圆

发表于 2014-7-16 10:31:56 | 显示全部楼层
中间对称,左边1/2,右边1/2,加起来就是一个完整的了,看看那个输出的PWM图,很容易就看明白了

出0入0汤圆

 楼主| 发表于 2014-7-16 10:47:26 | 显示全部楼层
smartmeter 发表于 2014-7-16 10:31
中间对称,左边1/2,右边1/2,加起来就是一个完整的了,看看那个输出的PWM图,很容易就看明白了 ...

这样的话应该是T0、T1、T2都要除以2吧。

出0入8汤圆

发表于 2014-7-16 10:49:52 | 显示全部楼层
楼主ID要不保了。我看看谁举报。

出0入0汤圆

 楼主| 发表于 2014-7-16 11:01:32 | 显示全部楼层
kebaojun305 发表于 2014-7-16 10:49
楼主ID要不保了。我看看谁举报。

只是交流交流,何必如此。

出0入8汤圆

发表于 2014-7-16 11:08:53 | 显示全部楼层
本帖最后由 kebaojun305 于 2014-7-16 11:19 编辑
zddvszw 发表于 2014-7-16 11:01
只是交流交流,何必如此。


你的大字体 是对手机用户的一种摧残。 《说严重点 手机用户杀了你的心都有。》

出0入0汤圆

 楼主| 发表于 2014-7-16 11:20:47 | 显示全部楼层
kebaojun305 发表于 2014-7-16 11:08
你的大字体 是对手机用户的一种摧残。 《说严重点 手机用户杀了你的心都有。》 ...

已改小。

出0入0汤圆

发表于 2014-7-16 11:40:34 | 显示全部楼层
本帖最后由 M.dd 于 2014-7-16 11:47 编辑

“是的,t0 t1 t2 都除以2”
上边搞错了,t0除以2好像是因为t0有两种(000,111)

出0入0汤圆

 楼主| 发表于 2014-7-21 09:45:44 | 显示全部楼层
M.dd 发表于 2014-7-16 11:40
“是的,t0 t1 t2 都除以2”
上边搞错了,t0除以2好像是因为t0有两种(000,111)
...

是这样子的。搞了几天才搞好,呵呵
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 07:42

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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