【电赛电力电子方向】使用STM32实现SPWM波输出

文章目录

  • 摘要
  • 调制分类
  • 双极性调制
  • 单极性调制
  • 单极性倍频
  • STM32上实现spwm调制
  • 正弦波的获取
  • 查表法(空间换时间)
  • 定时器中断运算
  • 实践
  • CUBEMX配置
  • 代码
  • 摘要

    在电机控制,PWM整流器,逆变器中都需要单片机输出SPWM波去控制.

    图0

    调制分类

    对于单相整流,逆变器有双极性调制,单极性调制,单极性倍频调制。

    双极性调制


    图1
    直接将整个正弦波放在三角波里做比较。

    图2
    全桥输出波形(占空比按正弦幅值变化).这个波经过LC滤波后就变成正弦波了。

    图3
    matlab里搭出的双极性调制,后面写代码也是参考这个。
    0.7是调制度。前面输进去的正弦波是从-1到0再到1的正弦波。将其抬高1,整个波形就只有正的,然后再除2就成了图1中的正弦波(归一化让正弦波在0到1内)。与三角波比较后输出调制波。

    单极性调制


    图4

    图5
    与双极性不同,单极性调制的输出是有正有负的。可以看到,这个波要比双极性调制更接近正弦波,所以谐波含量更少。

    图6
    按这种方式调制,那么全桥两边都是一会为高频开关一会为低频开关。而我们也可以只让一边做高频侧,另一边做低频侧(负责波形的正负)。

    单极性倍频

    。。。。。。待续

    可以把调制简单的理解成,将正弦波与三角波混合。后面经过滤波器就能去除三角波得到正弦波。那么三角波(载波)其实不一定就是上面那种等腰三角形,你用只有一半的波也是可以的。

    图7
    后面加滤波器就能把这个半个的三角波滤去。

    图8

    STM32上实现spwm调制

    可以看出,调制的核心是利用高频载波(三角波)与低频基波(正弦波)作比较得出。那么在stm上怎么实现这个过程?或者说在STM32里三角波和正弦波分别是什么,从哪里来?
    stm32的pwm输出功能(中心对称计数)可以用下图形象的描述。
    PWM生成过程
    图9
    三角波是定时器计数值按时间的变化,方波是输出的PWM波。
    可以看出改变CCR就可以改变脉冲宽度。即CCR/CNT=占空比。(当然在另一个PWM模式里就与这里的相反了)

    图10
    (实际的三角波频率要比正弦波大很多,看不清楚,这里减小了三角波的频率为了看清比较过程。)
    联系上面两张图,其实就是在每次到达CCR做比较来改变脉冲宽度。那么当CCR值按正弦变化不就实现了SPWM调制了嘛。

    正弦波的获取

    好了,我们现在知道了。定时器的计数值就是三角波。正弦波就是按正弦变化的CCR值。
    比如我们要一个50HZ的正弦波,三角波频率20KHZ。可以知道一个正弦波里包含400个三角波,而一个三角波要与正弦波比较两次,所以我们需要800个CCR值。当然,我们不追求精度,可以让一个三角波的两次比较值都一样,也就是400个CCR值。甚至可以两次三角波的比较CCR都一样,这样就只需要200个CCR了,当然这么做会损失一些精度。最好的情况当然是三角波频率足够高,比较值也足够多。
    常见的CCR获取方式有下面的两种。

    查表法(空间换时间)

    早期的单片机由于运算性能不行,所以是先把这些CCR值存储在ROM里(RAM也行)做正弦波码表。然后这个码表可以在一些软件里生成。也可以自己提前算好。
    有了码表,我们只需要每次计数器计到CCR触发中断时把CCR值更新就行了。

    定时器中断运算

    使用码表是因为运算性能不够,而stm32运算性能足够(使用dsp库,用C库的函数还是算起来有些慢的),可以自己去算正弦值。大致思路就是开一个定时器,每次进定时器中断的时间相同,累加就能得到时间.然后在定时器中断里计算sin(wt)
    具体操作如下:

    1. 定义角频率
    spwm_struct.w = 2*pi*50;						//50HZ正弦波
    
    1. 确定每次进入定时器中断的时间间隔
    spwm_struct.T = 0.00005;						//20K的定时器中断,每次进入间隔50us
    
    1. 更新正弦值
    spwm_struct.uref = arm_sin_f32(spwm_struct.WT);
    
    1. 在定时器中断里更新角度(相位)
    spwm_struct.WT += spwm_struct.w + spwm_struct.T;
    if(spwm_struct.WT >= 2 * pi) spwm_struct.WT = 0;			//WT在0到2pi变化 
    
    1. 更新CCR
      以双极性调制为例,参考图三 CCR=(spwm_struct.uref + 1)*mod_dep/2 * CNT
      mod_dep是调制度.

    实践

    单片机:STM32F446RCT6
    栅极驱动:IR2104。
    一个2104高端接G1,低端接G2 另一个高端接G3,低端接G4
    调制方式:双极性,定时器中断计算正弦波(查表实现的文章很多,这里就不展示了)
    大致思路:用高级定时器输出PWM给一个2104去控制G1,G2(PWM信号与G1信号一样,2104会互补输出G2的信号)。G1和G3的信号又是互补的。所以生成互补PWM给另一个2104。

    CUBEMX配置



    定时器其他配置默认。
    至于其他配置(下载,时钟等),就不展示了。

    代码

    定时器中断

    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    {
    		
    	
    	if(htim->Instance==TIM1)
    	{
    		if(moter_ctr_flag==0)
    		{
    			spwm_struct.jibo = spwm_struct.mod_dep*arm_cos_f32(spwm_struct.wt);//更新正弦波数据
    			bipolar_modulation(spwm_struct.jibo, tim_cnt, &spwm_struct);
    			TIM1->CCR1 = spwm_struct.ch1_ccr;
    			
    			spwm_struct.wt += spwm_struct.w * PWM_T;//更新相角wt
    			if(spwm_struct.wt>=2*pi)	spwm_struct.wt=0;//计满2π后归零,防止溢出
    		}
    	}
    
    }
    

    双极性调制

    /**
     * @brief 双极性调制
     * 
     * @param insignal 输入基波 (-1到1变化)
     * @param cnt 当时定时器cnt值
     * @return unsigned int 
     */
    void bipolar_modulation(float insignal, unsigned short cnt, spwm_t *ccr)
    {
        
        insignal = (insignal+1) / 2;
        ccr->ch1_ccr = insignal * (cnt - 1);
    }
    

    主函数while1前放的初始化

    void spwm_init()
    {
    	/*参数初始化*/
    	spwm_struct.w = 2*pi*50;		//2*pi*f
    	spwm_struct.wt = 0;
    	spwm_struct.fre = 50;
    	spwm_struct.uref = 1;
    	spwm_struct.rqd_flag = 1;
    	spwm_struct.mod_dep = 0.5;		//调制度
    	/*2104使能*/
    	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET);
    	/*PWM输出开启*/
    	HAL_TIM_Base_Start_IT(&htim1);
    	HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
    	HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);
    	
    }
    

    spwm结构体

    typedef struct
    {
    	float w;					//角频率
    	float fre;					//频率
    	float wt;					//相角
    	float mod_dep;				//调制度
        short ch1_ccr;				//ccr1
        short ch2_ccr;		
    	float jibo;
    }spwm_t;
    

    作者:白嫩的六角龙鱼

    物联沃分享整理
    物联沃-IOTWORD物联网 » 【电赛电力电子方向】使用STM32实现SPWM波输出

    发表评论