一、什么是SPWM
最简单的理解就是PWM的占空比按照正弦波的规律而改变;详细的介绍,网络一搜一大把,就不赘述了。
二、SPWM的应用场合
用于需要精确控制电压和电流波形的场合,如交流电机调速、变频器、电力变换器以及UPS(不间断电源)等
三、实现原理
基本上是通过在一定时间内,产生的高电平和时间轴形成的面积与正弦波对应的部分面积相等的原理。实际实际可以参考下面一片文章
真硬核!从零开始一文教你快速实现数字化SPWM纯正弦波逆变器
四、代码实现
代码实现原理就是:通过定时3的产生40KHz的载波频率,产生一个溢出事件后就更新定时器互补输出通道的占空比的值,而定时器1输出互补的频率是根据需要更新多少个点,产生多少Hz的频率决定的。这样实时更新按照正弦波变化的占空比的值,最后去驱动H桥可以获得正弦波,但是我这次测评只是产生SPWM,并没有实际驱动H桥,产生SIN波。
1、获取等价于正弦波的脉冲宽度表
使用python工具产生。主要使用面积等效公式。
python代码如下:
"""
单极性
"""
import numpy as np
import matplotlib.pyplot as plt
import math
fig =plt.figure(figsize = (15,15))
ax= fig.add_subplot(1,1,1)
"正弦波分段数"
seg_num =64
"调制深度--调制波幅值与载波幅值的比值 这个调制深度可以调整正弦波的峰值"
n = 0.5
"定时器的计数值最大值"
arr =1000
"占空比序列"
plus=[]
"占空比寄存器序列"
pluse_arr=[]
"半个周期分段的每段的弧度"
x=np.linspace(0,math.pi,seg_num+1)
sin_y = np.sin(x)
for i in range(seg_num):
"正弦波对应的面积,式子是利用积分计算得到的"
sin_area = (np.cos(x[i])-np.cos(x[i+1]))
"占空比=正弦波面积占一个周期内多少"
duty = sin_area*n/x[1]
pwm= x[i]+duty*x[1]
"小数部分的占空比"
plus.append(duty)
"对应计数器arr值的占空比"
pluse_arr.append(round(duty*arr))
rect1 = plt.Rectangle((x[i],0,0), x[1]*duty,1,color ='Green')
ax.add_patch(rect1)
print(plus)
print('\r')
print(pluse_arr)
pic1 =plt.plot(x,sin_y)
运行上述代码输出的占空比变化表如下:
uint32_t pwmVal[32]={
/*32个点,调制深度为0.95 定时器为1000,单极性SPWM------8 */
47, 139, 231, 320, 406, 488, 566, 638,
704, 763, 815, 858, 894, 921, 939, 948,
948, 939, 921, 894, 858, 815, 763, 704,
638, 566, 488, 406, 320, 231, 139, 47
};
波形如下:
2、配置互补输出定时器
3、配置产生定时更新PWM值得定时器
4、编写中断函数
void TMR3_GLOBAL_IRQHandler(void)
{
/* add user code begin TMR3_GLOBAL_IRQ 0 */
if (tmr_flag_get(TMR3,TMR_OVF_FLAG) != RESET) {
tmr_flag_clear(TMR3,TMR_OVF_FLAG);
TMR1->c3dt = pwmVal[pluse_cnt++];
}
/* add user code end TMR3_GLOBAL_IRQ 0 */
/* add user code begin TMR3_GLOBAL_IRQ 1 */
/* add user code end TMR3_GLOBAL_IRQ 1 */
}
5、下载验证
结果如下:
1)互补输出结果
2)定时器变化GIF图
3)加一个电容的波形
加了一个电容波形不是很理想,不太像正弦波,如果使用10uF的钽电容,波形会比较完美。
源码如下:
SPWM.zip
(2.14 MB)
|