SPWM波学习
1.SPWM简介:
SPWM(Sinusoidal Pulse Width Modulation)是一种基于正弦波脉宽调制的控制方法,常用于交流电机控制和逆变器控制等领域。
它是在每半个周期内输出若干个宽窄不同的矩形脉冲波,每一矩形波的面积近似对应正弦波各相应每一等份的正弦波形下的面积可用一个与该面积相等的矩形来代替,于是正弦波形所包围的面积可用这N个等幅(Vd)不等宽的矩形脉冲面积之和来等效,各矩形脉冲的宽度由理论计算得出。
SPWM的基本原理是通过比较一个参考正弦波信号和一个三角波信号的相位,调节输出脉冲的宽度和频率,控制电压的大小和形状。
具体来说,SPWM的实现过程如下:
1)生成参考正弦波信号,它通常是由一个振荡器产生的,频率和幅值可以根据需要调节;
2)生成三角波信号,其频率通常要比参考正弦波信号高,并且振幅为一定值;
3)将参考正弦波信号与三角波信号进行比较,得到一个比较结果;
4)根据比较结果调节输出脉冲的宽度和频率,使其接近参考正弦波信号,从而控制输出电压的大小和形状。
SPWM控制的优点是输出电压质量高、谐波小、效率高,适用于需要高精度控制的场合。常见的应用包括交流电机控制、逆变器控制、电力变换器、UPS、电力电子等领域。
2.SPWM与PWM的异同:
**相同点:**SPWM和PWM都是常用的脉宽调制技术,其基本原理是通过控制输出信号的脉冲宽度和频率来实现对电压和电流的调节。
不同点:
1.调制信号的形式不同:
SPWM的调制信号是正弦波,而PWM的调制信号通常是方波或锯齿波;
2.输出波形的质量不同:
SPWM的调制信号是正弦波,输出波形的质量更高,谐波更少,适用于高精度控制的场合;
PWM的调制信号是方波或锯齿波,输出波形的质量较差,谐波较多,但是控制简单、成本低、效率高;
3.应用场合不同:
由于SPWM适用于高精度控制的场合,常用于交流电机控制、逆变器控制、电力变换器、UPS等领域;
而PWM则广泛应用于调光、电源开关控制、直流电机控制等领域。
3.采样:
1.自然采样法:
通过令需要调制的正弦波与锯齿波载波相交产生交点,根据交点确定pwm脉冲所需要输出的时间宽度(即pwm波的占空比),由此生成SPWM波。
该方法计算量较大,会占用大量微处理器的资源,不推荐.
**2.规则采样法:**有两种采样方法。
1)、固定在三角载波每一周期的正峰值时找到正弦调制波上的对应点,即图中D点,求得电压值Urd。用此电压值对三角波进行采样,得A、B两点,就认为它们是SPWM波形中脉冲的生成时刻,A、B之间就是脉宽时间t2。规则采样I法的计算显然比自然采样法简单,但从图2中可以看出,所得的脉冲宽度将明显地偏小,从而造成不小的控制误差。这是由于采样电压水平线与三角载波的交点都处于正弦调制波的同一侧造成的。
2)、仍在三角载波的固定时刻找到正弦调制波上的采样电压值,但所取的不是三角载波的正峰值,而是其负峰值,得E点,采样电压为Ure。在三角载波上由Urt水平线截得A、B两点,从而确定了脉宽时间t2。这时,由于A、B两点坐落在正弦调制波的两侧,因此减少了脉宽生成误差,所得的SPWM波形也就更准确了。
规则采样法的实质是用阶梯波来代替正弦波,使算法简化。在规则法中,三角波每个周期的采样时刻都是确定的。
4.代码:
1.dsp库:
移植参考:【STM32-DSP库的使用】基于Keil5 + STM32CubeMX + CMSIS-DSP 手动添加、库添加方式_stm32 dsp库 应用-CSDN博客
2.代码:
pwm输出函数
void my_pwm_update(float duty, uint32 pwm_chennel)
{
uint32 PWM_PER_0_5 = 0.5f * PWM_PER;
HRTIM_SlaveSetCompare(HRTIM1, pwm_chennel, HRTIM_COMPAREUNIT_1, PWM_PER_0_5 - duty * 0.5f * PWM_PER);
HRTIM_SlaveSetCompare(HRTIM1, pwm_chennel, HRTIM_COMPAREUNIT_4, PWM_PER_0_5 + duty * 0.5f * PWM_PER);
}
中断服务函数
void HRTIM1_Master_IRQHandler(void)
{
HRTIM_ClearITPendingBit(HRTIM1, HRTIM_TIMERINDEX_MASTER, HRTIM_TIM_FLAG_REP);
/*ADC采样*/
uin = MYBOARD_ADC1*BK1+BA1; //输入电压
uout= MYBOARD_ADC2*BK2+BA2; //输出电压
iin = MYBOARD_ADC3*BK3+BA3; //输入电流
iout= MYBOARD_ADC4*BK4+BA4; //输出电流
AC_SIN.i=iout;
AC_SIN.v=uout;
POWER_MEAS_SINE_ANALYZER_run(&AC_SIN);
if(time_cnt<time_cnt_all)
time_cnt++;
else
{
time_cnt=0;
pwm =IncPIDCal(&voltage_pid,AC_SIN.vRms,set_point_u );
}
sin_out= pwm*1.414f*my_sin(time_cnt*6.28f/time_cnt_all);
pwm_a =IncPIDCal(¤t_pid,iout,sin_out );
my_pwm_update(pwm_a,PWM_UPDATE_CHANNELA); //输出pwm
}