一、SPWM是什么?
SPWM的全称是(Sinusoidal PWM),称为正弦脉冲宽度调制是一种非常成熟,使用非常广泛的技术。简单来讲其实就是PWM的占空比按照正弦波的规律进行变化的PWM。
二、SPWM的作用是什么?
SPWM在多个领域中具有广泛的应用:
1、产生交流电
SPWM技术可用于逆变器,将直流电源转化为高质量的交流电源。通过调整脉冲宽度,可生成与正弦波等效的脉冲序列,从而产生理想的交流电波形。
2、电机控制
在电机驱动系统中,SPWM用于精确控制电机的转速和转矩。通过改变脉冲的宽度和频率,可实现电机的平滑调速和精确运行
3、功率变换
SPWM技术还应用于电力电子变换器,如整流器和变频器,以高效地进行电能转换和调节。
4、减少谐波
SPWM技术能够显著降低输出波形中的谐波含量,提高电能质量,对维护电网和用电设备的稳定性至关重要。
5、改善功率因数
SPWM有助于优化系统的功率因数,减少无功功率,提高电能利用率。
6、声音合成
在音频领域,SPWM通过调制技术合成不同频率的声音波形,实现声音的再现。
7、通信系统
在通信领域,SPWM用于信号的调制和解调,提升信号传输的效率和品质。
三、SPWM的原理是什么?
基本原理就是,面积等效,即利用幅值相同,脉冲宽度不一样的PWM波,在一小段时间内的积分等价于正弦波一小段时间的面积。具体可以参看下面一篇文章,对于原理的描述写的还是很清楚的。
SPWM基本原理详解(图文并茂+公式推导+C程序实现)-CSDN博客
具体实现可以参考下面一篇文章
真硬核!从零开始一文教你快速实现数字化SPWM纯正弦波逆变器 (baidu.com)
四、产生正弦波采样宽度
产生SPWM的关键在于获取一系列等价于正弦波的脉冲宽度表;
使用python实现如下:
/*产生正弦波脉冲宽度表*/
"""
Created on Mon Jan 25 15:06:04 2021
单极性
@author: liuxingguo
"""
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)
使用jupyter notebook运行上述程序
输出SPWM数组如下:
小数
[0.012269382343518818, 0.036778589013820015, 0.0611991928417635, 0.08547236245373524, 0.10953962165805997, 0.13334299031927357, 0.15682512403734036,
0.17992945229534474, 0.20260031474280907, 0.22478309528636706, 0.24642435366470614, 0.2674719541908437, 0.28787519135155765, 0.3075849119614181, 0.3265536335771058,
0.3447356588867888, 0.36208718579893473, 0.378566412965397, 0.3941336404845251, 0.408751365541699, 0.42238437275689056, 0.43499981902160484, 0.4465673126208184, 0.45705898644924836,
0.4664495651456836, 0.4747164259835257, 0.481839653370924, 0.4878020868291859, 0.4925893623338585, 0.49618994691893364, 0.4985951664607794, 0.49979922657484005, 0.4997992265748401, 0.49859516646077934,
0.49618994691893376, 0.49258936233385825, 0.4878020868291862, 0.48183965337092344, 0.47471642598352626, 0.4664495651456836, 0.4570589864492461, 0.44656731262082067, 0.43499981902160484, 0.4223843727568883,
0.4087513655417013, 0.3941336404845251, 0.3785664129653992, 0.36208718579893245, 0.34473565888678653, 0.3265536335771092, 0.30758491196141696, 0.28787519135155987, 0.2674719541908414, 0.24642435366470614, 0.2247830952863682,
0.20260031474280907,0.1799294522953436, 0.1568251240373415, 0.13334299031927357, 0.10953962165805997, 0.08547236245373524, 0.06119919284176237, 0.036778589013821146, 0.012269382343518818]
整数
[12, 37, 61, 85, 110, 133, 157, 180, 203, 225, 246, 267, 288, 308, 327, 345, 362, 379, 394, 409, 422, 435, 447, 457, 466, 475,
482, 488, 493, 496, 499, 500, 500, 499, 496, 493, 488, 482, 475, 466, 457, 447, 435, 422, 409, 394, 379, 362, 345, 327, 308, 288,
267, 246, 225, 203, 180, 157, 133, 110, 85, 61, 37, 12]
输出的波形如图:
五、程序编写
1、新家工程以及配置时钟,具体就不一一赘述;
2、使能定时器
1)使能定时供1互补通道;定时器8一样操作即可。
2)使能定时器3,用于更新PWM的脉冲宽度
3、配置定时器参数
主要配置:输出极性、死时间、PWM mode
4、对定时器的分配、周期和死时间进行定义
/* USER CODE BEGIN Private defines */
#define SIN_Freq_25Hz 239
#define SIN_Freq_50Hz 119
#define SIN_Freq_100Hz 59
#define SIN_Freq_200Hz 29
#define SIN_Freq_400Hz 14
#define DEAD_TIME 10
#define TIM1_PRE 3
#define TIM1_ARR 999 //这里更新PWM的频率为40K
#define TIM8_PRE 3
#define TIM8_ARR 999
#define TIM3_PRE SIN_Freq_50Hz
#define TIM3_ARR 624
/* USER CODE END Private defines */
5、复制之前生成的脉冲宽度表
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "tim.h"
/* USER CODE BEGIN 0 */
#define Point_Max 256
uint16_t pluse_cnt=0;
uint8_t Voltage_Level = 2;
uint32_t Sin_Data_32[][32]={
/*32个点,调制深度为0.2 定时器为1000,单极性SPWM ------0 */
{10, 29, 49, 67, 85, 103, 119, 134,
148, 161, 171, 181, 188, 194, 198, 200,
200, 198, 194, 188, 181, 171, 161, 148,
134, 119, 103, 85, 67, 49, 29, 10},
/*32个点,调制深度为0.35 定时器为1000,单极性SPWM ------1 */
{17, 51, 85, 118, 150, 180, 208, 235,
259, 281, 300, 316, 329, 339, 346, 349,
349, 346, 339, 329, 316, 300, 281, 259,
235, 208, 180, 150, 118, 85, 51, 17},
/*32个点,调制深度为0.4 定时器为1000,单极性SPWM ------2 */
{20, 59, 97, 135, 171, 206, 238, 269,
296, 321, 343, 361, 376, 388, 396, 399,
399, 396, 388, 376, 361, 343, 321, 296,
269, 238, 206, 171, 135, 97, 59, 20},
/*32个点,调制深度为0.45 定时器为1000,单极性SPWM ------3 */
{22, 66, 109, 152, 192, 231, 268, 302,
333, 361, 386, 407, 424, 436, 445, 449,
449, 445, 436, 424, 407, 386, 361, 333,
302, 268, 231, 192, 152, 109, 66, 22},
/*32个点,调制深度为0.5 定时器为1000,单极性SPWM------4 */
{25, 73, 121, 168, 214, 257, 298, 336,
370, 401, 429, 452, 471, 485, 494, 499,
499, 494, 485, 471, 452, 429, 401, 370,
336, 298, 257, 214, 168, 121, 73, 25},
/*32个点,调制深度为0.6 定时器为1000,单极性SPWM------5 */
{29, 88, 146, 202, 256, 308, 357, 403,
444, 482, 514, 542, 565, 582, 593, 599,
599, 593, 582, 565, 542, 514, 482, 444,
403, 357, 308, 256, 202, 146, 88, 29},
/*32个点,调制深度为0.85 定时器为1000,单极性SPWM ------6 */
{42, 125, 206, 286, 363, 437, 506, 571,
630, 682, 729, 768, 800, 824, 840, 849,
849, 840, 824, 800, 768, 729, 682, 630,
571, 506, 437, 363, 286, 206, 125, 42},
/*32个点,调制深度为0.9 定时器为1000,单极性SPWM------7 */
{44, 132, 219, 303, 385, 463, 536, 604,
667, 723, 772, 813, 847, 873, 890, 899,
899, 890, 873, 847, 813, 772, 723, 667,
604, 536, 463, 385, 303, 219, 132, 44},
/*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}
};
/* USER CODE END 0 */
6、启动定时器
/* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1); //启动定时器CH1输出
HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_1); //启动定时器CH1N输出
HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_1);
HAL_TIMEx_PWMN_Start(&htim8,TIM_CHANNEL_1);
__HAL_TIM_CLEAR_FLAG(&htim3, TIM_FLAG_UPDATE);
HAL_TIM_Base_Start_IT(&htim3); //启动定时器3
/* USER CODE END 2 */
7、编译下载验证
1)使用示波器查看定时器1CH1和CH1N的波形;
可以看到,CH1和CH1N是互补的,当CH1为高电平时,CH1N为低电平;频率为40KHz;
放大一点看看
2)在CH1的PWM引脚上接一个10uF的电容,就可以看到正弦波的波形了,不过不是很纯正,可以使用两路SPWM驱动H桥,然后加上一个电容和电感,就可以看到纯正的正弦波。
3)看一下CH1和CH1N的脉宽动态变化。
可以看到PWM的脉宽是持续根据脉宽表变化。
工程如下:
(下载次数: 0, 2024-2-4 09:09 上传)