• 回复
  • 收藏
  • 点赞
  • 分享
  • 发新帖

单片机做逆变器过零点波形不对,求帮助

单片机用的是PIC16F1936,外接20M晶振。程序如下:

#include

__CONFIG (FOSC_HS&WDTE_OFF&PWRTE_OFF&MCLRE_ON&CP_OFF&BOREN_ON&CLKOUTEN_OFF&WRT_OFF&          PLLEN_OFF&LVP_OFF&BORV_25);

#define uchar unsigned char

#define uint unsigned int

const uchar sin_table[100]={16 , 31 ,47 ,62 ,77 ,92 ,106 ,120 ,134 ,147,159 ,171 ,182 ,193 ,202 ,211 ,219 ,226 ,232 ,238,242 ,246 ,248 ,250 ,250 ,250 ,248 ,246 ,242 ,238,232 ,226 ,219 ,211 ,202 ,193 ,182 ,171 ,159 ,147,134 ,120 ,106 ,92 ,77 ,62 ,47 ,31 ,16 ,0,16 , 31 ,47 ,62 ,77 ,92 ,106 ,120 ,134 ,147,159 ,171 ,182 ,193 ,202 ,211 ,219 ,226 ,232 ,238,242 ,246 ,248 ,250 ,250 ,250 ,248 ,246 ,242 ,238,232 ,226 ,219 ,211 ,202 ,193 ,182 ,171 ,159 ,147,134 ,120 ,106 ,92 ,77 ,62 ,47 ,31 ,16 ,0};

uchar num_INT;

Init_IO();

Init_Timer2_clk();

Init_CCP1();/

*The main function of Sine wave inverter*/

void main()

{num_INT=0;

Init_IO();

Init_Timer2_clk();

Init_CCP1();

TMR2ON=1;

TRISB=0xC3;

while(1);}

Init_Timer2_clk()

{TMR2IF=0; //清定时器2中断标志

TMR2IE=1; //定时器2中断使能位

PEIE=1; //外设中断使能

GIE=0; //全局中断禁止

T2CON=0x18; //预分频比为0,后分频比为2

PR2=0xF9; //周期寄存器设置 249

TMR2=0x00;GIE=1;}

Init_IO()

{P2BSEL=1; //确定P2B位于RC0

CCP2SEL=1; //确定P2A位于RC1

ANSELB=0X03;

TRISB=0x03;}

Init_CCP1() //增强型PWM初始化设置

{CCP2CON=0x8c; //设置增强型PWM工作于半桥模式;PWM设置为高电平有效

CCPTMRS0=0xF3; //设置PWM模式下CCP2以Timer2作为定时器

PWM2CON=0X05; //死区设置为1us

STR2D=0;

STR2C=0;

STR2B=1;

STR2A=1;

CCPR2L=0;}

void interrupt TMR2INT()

{

    if(TMR2IE&TMR2IF)

    {

        TMR2IF=0;

        num_INT++;

            if(num_INT<=50)

                CCPR2L=sin_table[num_INT-1];

            else

                CCPR2L=250-sin_table[num_INT-1];

            if(num_INT==51)

                {

                    RB4=0;

                    NOP();NOP();NOP();NOP();

                    RB2=1;

                }

            if(num_INT==1)

                {

                    RB2=0;

                    NOP();NOP();NOP();NOP();

                    RB4=1;

                }

            if(num_INT==100)

                    num_INT=0;

    }

}

用以上程序进行单片机调试发现输出波形在过零点有问题

过零点的驱动波形如下

用的是后分频为2的中断响应,不知道为什么工频变换比高频变换早不到一个周期,希望在此能得到师傅们的指点,不胜感激

全部回复(13)
正序查看
倒序查看
2014-05-21 15:10
替楼主顶一帖,希望得到老师们的帮助,谢谢!
0
回复
2014-05-21 16:04

分明是工频臂超前了一个周期呀,看看是不是定时器使用了影子寄存器的自动重装载,用这个功能可以避免定时器中断程序设置过程对极小脉宽的影响,看你的波形应该是用了,那么pwm实际输出滞后于中断一个周期

工频臂要在电感电流为0时进行切换,这个具体的时序需要配合输出的lc参数来决定是超前还是滞后,但是因为逆变器的负载非常可能不是纯阻性的,带不同负载的时候过零点还是会出现失真,这方面双极性的就好很多

0
回复
2014-05-22 10:58
@wangshujun
分明是工频臂超前了一个周期呀,看看是不是定时器使用了影子寄存器的自动重装载,用这个功能可以避免定时器中断程序设置过程对极小脉宽的影响,看你的波形应该是用了,那么pwm实际输出滞后于中断一个周期工频臂要在电感电流为0时进行切换,这个具体的时序需要配合输出的lc参数来决定是超前还是滞后,但是因为逆变器的负载非常可能不是纯阻性的,带不同负载的时候过零点还是会出现失真,这方面双极性的就好很多
感谢师傅的回帖,非常感激。再给您看个图

上图是我后分频为4的一个输出,使用的是高电平有效,确实使用了自动重载功能。如果我将上面中断中的程序改为

if(num_INT==50)

{

RB4=0;

NOP();NOP();NOP();NOP();

RB2=1;

}

if(num_INT==100)

{RB2=0

;NOP();NOP();NOP();NOP();

RB4=1;

}

那结果就变成

两图相比,差一个载波周期,所以说,我的工频输出已经在时序上补偿了一个中断的,但结果却差的是一个载波周期,这就让我很不理解,希望师傅给看看,谢谢

0
回复
2014-05-22 13:58
@熊猫酒仙
感谢师傅的回帖,非常感激。再给您看个图[图片]上图是我后分频为4的一个输出,使用的是高电平有效,确实使用了自动重载功能。如果我将上面中断中的程序改为if(num_INT==50){RB4=0;NOP();NOP();NOP();NOP();RB2=1;}if(num_INT==100){RB2=0;NOP();NOP();NOP();NOP();RB4=1;}那结果就变成[图片]两图相比,差一个载波周期,所以说,我的工频输出已经在时序上补偿了一个中断的,但结果却差的是一个载波周期,这就让我很不理解,希望师傅给看看,谢谢

你这个图,似乎4个pwm周期才改变一次占空比的,使用了pwm的重复定时器?每四次改变一次pwm

你正弦表是100个的,重复4次,每周期是400个载频周期,载频是20k,正好是这样

如果运算能力够用的话,不用重复寄存器,软件管理重复就好办了,另外做成200点的半周期正弦表效果会好得多呀,你现在正弦表的前后是重复的,没必要,可以去掉一半的,然后正弦表分辨率扩大4倍正好

你改成这样是差了5个周期了,超前更多了,如果继续使用重复寄存器修改的话会出现要么超前1个,要么之后3个的问题,工频臂切换时间最好能做到按照周期调节比较好。

0
回复
2014-05-22 14:05
@wangshujun
你这个图,似乎4个pwm周期才改变一次占空比的,使用了pwm的重复定时器?每四次改变一次pwm你正弦表是100个的,重复4次,每周期是400个载频周期,载频是20k,正好是这样如果运算能力够用的话,不用重复寄存器,软件管理重复就好办了,另外做成200点的半周期正弦表效果会好得多呀,你现在正弦表的前后是重复的,没必要,可以去掉一半的,然后正弦表分辨率扩大4倍正好你改成这样是差了5个周期了,超前更多了,如果继续使用重复寄存器修改的话会出现要么超前1个,要么之后3个的问题,工频臂切换时间最好能做到按照周期调节比较好。
我不理解的就是为什么会差5个周期,我是四个载波周期进一次中断的,如果说滞后应该滞后4的整数倍,怎么会出现5个呢,麻烦您能不能给我解释的稍微详细点,谢谢

刚看完您的回复,这款单片机的运算能力有限,后面还要做AD和PI调节,所以时候用四个点调节为争取一点时间。您说的不用重复寄存器,用软件管理重复是怎么个意思,没太明白,您能稍微解释下吗?您的QQ多少,方便给我发下嘛

0
回复
2014-05-22 14:16
@熊猫酒仙
我不理解的就是为什么会差5个周期,我是四个载波周期进一次中断的,如果说滞后应该滞后4的整数倍,怎么会出现5个呢,麻烦您能不能给我解释的稍微详细点,谢谢刚看完您的回复,这款单片机的运算能力有限,后面还要做AD和PI调节,所以时候用四个点调节为争取一点时间。您说的不用重复寄存器,用软件管理重复是怎么个意思,没太明白,您能稍微解释下吗?您的QQ多少,方便给我发下嘛

有一个额外的pwm滞后周期是自动重装导致的,你做4次重复必然是这个结果

0
回复
2014-05-22 20:57
@熊猫酒仙
感谢师傅的回帖,非常感激。再给您看个图[图片]上图是我后分频为4的一个输出,使用的是高电平有效,确实使用了自动重载功能。如果我将上面中断中的程序改为if(num_INT==50){RB4=0;NOP();NOP();NOP();NOP();RB2=1;}if(num_INT==100){RB2=0;NOP();NOP();NOP();NOP();RB4=1;}那结果就变成[图片]两图相比,差一个载波周期,所以说,我的工频输出已经在时序上补偿了一个中断的,但结果却差的是一个载波周期,这就让我很不理解,希望师傅给看看,谢谢

第四个图的上面蓝色和紫色的线在零点重合,你的问题就解决了。

加油,你只差一点点了。呵呵

0
回复
2014-05-22 21:04
@熊猫酒仙
我不理解的就是为什么会差5个周期,我是四个载波周期进一次中断的,如果说滞后应该滞后4的整数倍,怎么会出现5个呢,麻烦您能不能给我解释的稍微详细点,谢谢刚看完您的回复,这款单片机的运算能力有限,后面还要做AD和PI调节,所以时候用四个点调节为争取一点时间。您说的不用重复寄存器,用软件管理重复是怎么个意思,没太明白,您能稍微解释下吗?您的QQ多少,方便给我发下嘛

印象中1936时钟可以到32M,都有8MIPS了,做这个应该来得及

另外,你可以改成用2个ECCP做这个,他好像有几个ECCP的。应该很容易实现这个。

 

0
回复
2014-05-22 22:09
@lizlk
印象中1936时钟可以到32M,都有8MIPS了,做这个应该来得及另外,你可以改成用2个ECCP做这个,他好像有几个ECCP的。应该很容易实现这个。 

首先非常感谢张工能来看我的问题,在此深表感谢。

现在问题就卡在这里了,不知道为什么会多出来一个载波周期,试了自己能想到的所有办法,都没能搞定,上面师傅说“有一个额外的PWM滞后周期是自动重装导致的”,这点始终没想通,明天按着张工所说的用两个ECCP去试试,到时候再通报结果。

0
回复
wangshujun
LV.8
11
2014-05-23 08:30
@lizlk
印象中1936时钟可以到32M,都有8MIPS了,做这个应该来得及另外,你可以改成用2个ECCP做这个,他好像有几个ECCP的。应该很容易实现这个。 
用了自动重装的影子寄存器最好用别再用重复寄存器,否则没法调整到正好
0
回复
wangshujun
LV.8
12
2014-05-23 09:43
@lizlk
印象中1936时钟可以到32M,都有8MIPS了,做这个应该来得及另外,你可以改成用2个ECCP做这个,他好像有几个ECCP的。应该很容易实现这个。 
这个片子似乎不算便宜呀,比新塘的m0还贵呢,处理能力差了不是一点半点呀
0
回复
2014-05-23 09:56
@wangshujun
用了自动重装的影子寄存器最好用别再用重复寄存器,否则没法调整到正好

师傅所说的有点不理解,这个程序中用了自动重装的PWM模块,中断响应是进行了后分频设置(设置为4),您所说的重复寄存器是不是指的就是我使用的后分频的功能?

您再看两个图

0
回复
wangshujun
LV.8
14
2014-05-23 10:06
@熊猫酒仙
师傅所说的有点不理解,这个程序中用了自动重装的PWM模块,中断响应是进行了后分频设置(设置为4),您所说的重复寄存器是不是指的就是我使用的后分频的功能?您再看两个图[图片][图片]

应该就是后分频功能,不同厂家的pwm发生器定义不同

做逆变器不建议用这个功能

0
回复