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

基于STM32的SPWM逆变输出波形问题

本人大学生一枚,最近两天做了一下2020年省赛的B题:单项在线式不间断电源。做PFC电路和升压电路还算比较顺利,但是在做DC-AC逆变的时候着实遇到了一些问题。

这是我搭的逆变电路

电路主体大概是一个使用STM32产生SPWM的波,经过IR2110驱动H桥逆变,再经由LC滤波输出,在这里我使用了双极性调制。共两个电感,每个电感是1.7mH,输出有一个2.2uF的CBB电容。

明明没有什么问题,但是输出的波形很奇怪。

这是逆变电路输出空载的波形,同时功率部分有约13毫安的空载电流

当输出接了约30W纯阻性负载之后,波形又变成了这个样子

这里,H桥的直流母线电压为30V。

我起初怀疑是硬件电路的问题,就先用EG8010临时搭了一个电路,结果发现出来的波形特别完美。

空载时电源输出电流几乎为0;

既然硬件电路没啥问题,那就只能去扒一扒软件了

在SPWM里,我使用的是查表法来产生spwm,暂时用的开环设计。

调制频率是20kHz,基波是50Hz,表格里也应该有400个数,将这400个数导出来放到EXCEL里,生成的图表是这样的

主PWM输出用到了高级定时器1的T1C1、T1C1N、T1C2、T1C2N,

这个是定时器1的配置程序,输出4路PWM,定时器1的arr = 3600., psc = 0。

void TIM1_PWM_Init(u16 arr,u16 psc)
{  
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	TIM_BDTRInitTypeDef	TIM_BDTRInitStructure;
	

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);	//使能定时器1时钟
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA  | RCC_APB2Periph_GPIOB, ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟
 
   //设置该引脚为复用输出功能,输出TIM1  CH1 CH2的PWM脉冲波形	GPIOA.9
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_8; //TIM_CH1 TIM_CH2
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
 
   //初始化TIM1
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
	
	//初始化TIM1 Channel2 PWM模式	 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
	TIM_OCInitStructure.TIM_Pulse = 0;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
	TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;     
	TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;

	TIM_OC2Init(TIM1, &TIM_OCInitStructure);
	TIM_OC2PreloadConfig(TIM1,TIM_OCPreload_Enable);

	TIM_OCInitStructure.TIM_Pulse = 0;

	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
	TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
	
	TIM_OC1Init(TIM1, &TIM_OCInitStructure);
	TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);
	
	TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Disable;
	TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Disable;
	TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
	TIM_BDTRInitStructure.TIM_DeadTime = 5;					//调节死区时间
	TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;               
	TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low;
	TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;
	TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);
 
	TIM_ARRPreloadConfig(TIM1, ENABLE);
	TIM_Cmd(TIM1, ENABLE);  //使能TIM1
	TIM_CtrlPWMOutputs(TIM1, ENABLE);
}

同时,用和定时器1同频率的定时器2来更新定时器1的占空比,下边是定时器2的中断服务函数

//定时器2中断服务程序
void TIM2_IRQHandler(void)   //TIM2中断
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)  //检查TIM2更新中断发生与否
		{
			TIM_ClearITPendingBit(TIM2, TIM_IT_Update);  //清除TIM2更新中断标志
			//更新PWM1和PWM2的占空比
			my_spwm.pwm_1++;
			if(my_spwm.pwm_1 >= my_spwm.num_max)
				my_spwm.pwm_1 = 0;
			TIM1->CCR1 = num_list[my_spwm.pwm_1];
			TIM1->CCR2 = num_list[my_spwm.pwm_1];
		}
}

我还特意用了一下仿真,看了一下其中的一个互补通道

互补肯定是互补,不然表示会炸管的,但是空载有大约13毫安的电流(功率部分)

至此,我已经彻底懵了,不知道怎么办,我又试探着用示波器的FFT测了一下输出,突然被发现在约2kHz的地方发现一处尖峰

这好像是LC的谐振频率,发现了这个问题之后我也不知道该怎么解决,希望各位资深大佬们能给小弟一些建议

全部回复(33)
正序查看
倒序查看
k6666
LV.9
2
2021-08-20 15:11

你的电路设计谐振频率是2KHZ吗

0
回复
k6666
LV.9
3
2021-08-20 15:11

输出的CBB电容参数调整试试了

0
回复
2021-08-20 15:15
@k6666
你的电路设计谐振频率是2KHZ吗

设计的是50Hz纯正弦波输出

0
回复
2021-08-20 15:17

你的输出是闭环还是开环啊?单极性调制还是双极性调制啊?

0
回复
2021-08-20 15:18
@k6666
输出的CBB电容参数调整试试了

在这之前,我也试着去把电容和电感的大小分别增大一倍,但是很奇怪的就是就是一直都这样,波形也没变

0
回复
2021-08-20 15:19
@川理学子
你的输出是闭环还是开环啊?单极性调制还是双极性调制啊?

开环, 双极性调制

0
回复
2021-08-20 15:25
@肥鱼罐头
开环,双极性调制

你可以看看你的驱动波形是什么样的,是不是按照正弦变化的

0
回复
2021-08-20 15:31

最好上传一下电路图,看看原理,这样好分析解决问题的

0
回复
2021-08-20 16:00

你看下占空比配置呢?ST的PWM输出占空比好像是无法直接到0或100,只能写指定值才可以,有个输出占空比范围

0
回复
2021-08-20 16:01
@天府大懒猫
你看下占空比配置呢?ST的PWM输出占空比好像是无法直接到0或100,只能写指定值才可以,有个输出占空比范围

寄存器的值有范围要求限制的

0
回复
2021-08-20 16:09

我2015年,用STM32做过正弦波逆变,这是2KW负载。

程序找不到了,入门非常难,STM32的寄存器复杂且数量众多,STM32本身针对正弦波逆变的H桥控制设置了大量寄存器,功能非常强。

仅仅通过对STM32内部逆变控制寄存器合理设置 ,引入表格,基本不需要程序控制就能产生完善的正弦波形,就和EG8010一样简单。

但是,对这些寄存器的理解和配置特别困难,我花了几个月时间才摸索明白。

你这里调用定时器中断产生占空比,应该是不合适的,一方面,这违反了STM32对正弦波控制的初衷,STM32产生正弦波的H桥控制,是STM32的强项之一,电机控制,正弦波产生等等,功能强大到让人叹为观止。另一方面,定时器中断进入和退出过程,占用的时间特别长,并且由于被其它中断优先占用会变的不稳定。即使你程序中没有设置其它中断,STM32系统中也有自带的滴嗒中断强行插入。

stm32中断的进入和退出时间出乎意料的长,并且不固定,我以前大概做过测试,最长好像需要几us到几十us。并不是我们想像的1us内就能完成中断的进入退出。当然也许我的理解或测试有误。

在stm32定时器中,用了大量篇幅介绍这些针对正弦波H桥逆变控制寄存器的介绍,它是arm最强也是最重要的功能。我最近也要开始做正弦波逆变,也要开始重新研究这些计算器的用法。印象中,仅仅通过对stme32相关寄存器进行合理配置,建立正确的表格,几乎不需要程序任何处理,就能产生完善的三相H桥正弦波逆变控制输出。只要在程序中改变相关寄存器数据,就能改变正弦波的频率,幅值,相位等重要参数,主程序很简单,就是对这些寄存器的配置特别难。

在每种型号stm32的1000多页datesheet文档中,几乎有一半篇幅是用来描述这些定时器内关于逆变控制寄存器时序逻辑功能的,中文资料很少,绝大部分是英文版的,晦涩难懂,要花大量时间才能理解,但如果理解透彻了,绝对能大开眼界,并且对正弦波逆变了如指掌。

2
回复
2021-08-20 16:39
@天府大懒猫
你看下占空比配置呢?ST的PWM输出占空比好像是无法直接到0或100,只能写指定值才可以,有个输出占空比范围

我设置装载值arr是3600

0
回复
2021-08-20 18:38

用EG8010正常说明功率电路和驱动电路都没问题,说明就是STM32产生的spwm波有问题。很可能是自动生成互补的波有问题,spwm波起始值应该等于arr最值的一半,就是正弦波的零点或者说横轴固定在arr中间,然后按正弦规律变化,注意加死区。试试看吧

0
回复
#回复内容已被删除#
15
2021-08-21 11:46

这个大概就是整体的电路图

0
回复
2021-08-21 11:48
@川理学子
你可以看看你的驱动波形是什么样的,是不是按照正弦变化的

用32的仿真看了一下大概是,请问还有什么更好的办法吗?

0
回复
2021-08-21 13:11
@肥鱼罐头
用32的仿真看了一下大概是,请问还有什么更好的办法吗?

最好用示波器实测,如果是按照正弦变化的话那么带载后就是正弦波,不是的话就不是正弦波

0
回复
2021-08-21 13:54
@川理学子
最好用示波器实测,如果是按照正弦变化的话那么带载后就是正弦波,不是的话就不是正弦波

这是用示波器打的STM32的PWM输出,视频不知道怎么发上来

0
回复
mwxpk
LV.4
20
2021-08-28 10:26

主  从  逻辑。

0
回复
ruohan
LV.9
21
2021-09-01 08:05
@肥鱼罐头
[图片]这是用示波器打的STM32的PWM输出,视频不知道怎么发上来

把整个程序发出来,

看看你的正弦表是多少个,一般半周期的码表,或者是1/4周期的码表

0
回复
ruohan
LV.9
22
2021-09-01 09:32
@ruohan
把整个程序发出来,看看你的正弦表是多少个,一般半周期的码表,或者是1/4周期的码表

查表的时候别用TIM2中断,直接用TIM1中断,进中断后更新g比较寄存器的值,

0
回复
ruohan
LV.9
23
2021-09-06 11:35
@肥鱼罐头
[图片]这是用示波器打的STM32的PWM输出,视频不知道怎么发上来

朋友,调好了吗

0
回复
xingyingV
LV.1
24
2021-09-07 10:32

没看到楼主的正弦表,尚有疑惑,此外,大家一般都是向上向下计数,这确实比向上计数好一些,《电力电子变换器PWM技术原理与实践》对这有解答。

0
回复
2021-09-18 18:10
@xingyingV
没看到楼主的正弦表,尚有疑惑,此外,大家一般都是向上向下计数,这确实比向上计数好一些,《电力电子变换器PWM技术原理与实践》对这有解答。

u32[]= {  1800  1824  1849  1873  1898  1923  1947  1972  1996  2020  2045  2069  2093  2118  2142  2166  2190  2213  2237  2261  2284  2308  2331  2354  2377  2400  2423  2446  2468  2490  2512  2534  2556  2578  2599  2620  2641  2662  2683  2703  2724  2744  2763  2783  2802  2821  2840  2859  2877  2895  2913  2931  2948  2965  2982  2998  3014  3030  3046  3061  3076  3091  3105  3119  3133  3146  3160  3172  3185  3197  3209  3220  3231  3242  3253  3263  3273  3282  3291  3300  3308  3316  3324  3331  3338  3345  3351  3357  3362  3367  3372  3376  3380  3384  3387  3390  3393  3395  3396  3398  3399  3399  3399  3399  3399  3398  3397  3395  3393  3390  3388  3384  3381  3377  3372  3368  3363  3357  3351  3345  3339  3332  3325  3317  3309  3301  3292  3283  3273  3264  3254  3243  3232  3221  3210  3198  3186  3173  3161  3147  3134  3120  3106  3092  3077  3062  3047  3031  3015  2999  2983  2966  2949  2932  2914  2897  2879  2860  2842  2823  2804  2785  2765  2745  2725  2705  2685  2664  2643  2622  2601  2580  2558  2536  2514  2492  2470  2447  2425  2402  2379  2356  2333  2310  2286  2263  2239  2215  2192  2168  2144  2120  2095  2071  2047  2022  1998  1974  1949  1925  1900  1875  1851  1826  1802  1778  1753  1729  1704  1679  1655  1630  1606  1582  1557  1533  1509  1484  1460  1436  1412  1388  1365  1341  1318  1294  1271  1248  1225  1202  1179  1156  1134  1112  1089  1067  1046  1024  1003  981  960  939  919  898  878  858  838  819  799  780  761  743  724  706  688  671  654  637  620  603  587  571  556  540  525  511  496  482  468  455  442  429  416  404  392  381  369  359  348  338  328  319  310  301  292  284  277  269  262  256  250  244  238  233  228  224  220  216  213  210  208  205  204  202  201  201  201  201  201  202  203  205  207  209  212  215  219  223  227  232  237  242  248  254  261  268  275  282  290  299  307  316  326  336  346  356  367  378  389  401  413  426  438  451  465  479  493  507  522  537  552  567  583  599  616  632  649  667  684  702  720  738  757  776  795  814  833  853  873  893  914  934  955  976  997  1019  1040  1062  1084  1106  1128  1151  1173  1196  1219  1242  1265  1288  1312  1335  1359  1383  1406  1430  1454  1479  1503  1527  1551  1576  1600  1624  1649  1673  1698  1723 1747  1772  1796};

0
回复
2021-09-18 18:10
@肥鱼罐头
u32[]={ 1800 1824 1849 1873 1898 1923 1947 1972 1996 2020 2045 2069 2093 2118 2142 2166 2190 2213 2237 2261 2284 2308 2331 2354 2377 2400 2423 2446 2468 2490 2512 2534 2556 2578 2599 2620 2641 2662 2683 2703 2724 2744 2763 2783 2802 2821 2840 2859 2877 2895 2913 2931 2948 2965 2982 2998 3014 3030 3046 3061 3076 3091 3105 3119 3133 3146 3160 3172 3185 3197 3209 3220 3231 3242 3253 3263 3273 3282 3291 3300 3308 3316 3324 3331 3338 3345 3351 3357 3362 3367 3372 3376 3380 3384 3387 3390 3393 3395 3396 3398 3399 3399 3399 3399 3399 3398 3397 3395 3393 3390 3388 3384 3381 3377 3372 3368 3363 3357 3351 3345 3339 3332 3325 3317 3309 3301 3292 3283 3273 3264 3254 3243 3232 3221 3210 3198 3186 3173 3161 3147 3134 3120 3106 3092 3077 3062 3047 3031 3015 2999 2983 2966 2949 2932 2914 2897 2879 2860 2842 2823 2804 2785 2765 2745 2725 2705 2685 2664 2643 2622 2601 2580 2558 2536 2514 2492 2470 2447 2425 2402 2379 2356 2333 2310 2286 2263 2239 2215 2192 2168 2144 2120 2095 2071 2047 2022 1998 1974 1949 1925 1900 1875 1851 1826 1802 1778 1753 1729 1704 1679 1655 1630 1606 1582 1557 1533 1509 1484 1460 1436 1412 1388 1365 1341 1318 1294 1271 1248 1225 1202 1179 1156 1134 1112 1089 1067 1046 1024 1003 981 960 939 919 898 878 858 838 819 799 780 761 743 724 706 688 671 654 637 620 603 587 571 556 540 525 511 496 482 468 455 442 429 416 404 392 381 369 359 348 338 328 319 310 301 292 284 277 269 262 256 250 244 238 233 228 224 220 216 213 210 208 205 204 202 201 201 201 201 201 202 203 205 207 209 212 215 219 223 227 232 237 242 248 254 261 268 275 282 290 299 307 316 326 336 346 356 367 378 389 401 413 426 438 451 465 479 493 507 522 537 552 567 583 599 616 632 649 667 684 702 720 738 757 776 795 814 833 853 873 893 914 934 955 976 997 1019 1040 1062 1084 1106 1128 1151 1173 1196 1219 1242 1265 1288 1312 1335 1359 1383 1406 1430 1454 1479 1503 1527 1551 1576 1600 1624 1649 1673 1698 17231747 1772 1796};

这个是一个周期的数组,定时器的装载值是3600

0
回复
2021-09-18 18:17

我终于调试成功了,用四针oled总是会出现莫名其妙的问题,只初始化oled不用显示出来的波形正常,一旦显示就会出现之前的情况,后来该用了七针oled之后就能够正常使用,不知道是因为什么原因,请问这个是干扰吗,还是因为四针oled的通讯时间更长

0
回复
2021-09-18 18:20

这是最终的调试结果,在输出终于出来了正弦波,由于原来mos的内阻过大,导致带载发热很大,有时间我会换一下

0
回复
ruohan
LV.9
29
2021-11-11 15:05
@肥鱼罐头
[图片]这是最终的调试结果,在输出终于出来了正弦波,由于原来mos的内阻过大,导致带载发热很大,有时间我会换一下

是什么问题啊,

现在我也遇到该问题

0
回复
2021-11-26 10:43
@ruohan
是什么问题啊,现在我也遇到该问题

就是载波频率不高,适当提高载波频率可以解决问题

0
回复
ruohan
LV.9
31
2021-12-15 08:40
@肥鱼罐头
就是载波频率不高,适当提高载波频率可以解决问题

载波频率已经是20K了,应该可以了吧,

你TM2定时中断配置能看看吗,TM2的装载值也是3600吗,

0
回复