×
嵌入式 > 技术百科 > 详情

SPWM波在单片机上的实现与调节(基于MSP430F5529)

发布时间:2020-06-17 发布时间:
|

SPWM波的定义和生成方法在这里就不多说了,本文主要说SPWM波在单片机上的实现,以及如何调节滤出后的正弦波的频率及幅度。 


先弄清楚SPWM在单片机上如何产生,比如你要输出100HZ的SPWM正弦波,每个周期100个点,则定时器B的中断频率为100*100=10K,用于载波(定时器A)的PWM频率应>=10K(这里我建议载波为1M,因为定时器的配合问题会有+-1的误差,所以载波尽量的大则滤出的正弦波的波形越好)。 


通过软件,你先得到100个点的正弦波采样值,你可以用定时器A来产生1MHZ的PWM,然后用定时器B,做定时器中断,10KHZ的频率,每次中断,就把一个采样值赋值给定时器A的输出通道:CCRx。然后不停的循环,每中断一百次,就输出1个波。不停的循环就不停的输出,那么PWM输出端,经过滤波后(外部滤波电路要找相关电路去设计),就是100HZ的正弦波了。 


调节频率要通过定时器B,公式:正弦波频率*每个周期的点数=定时器B中断频率 

调节幅度要依据载波中最大与最小占空比之差也即是调制深度,这个没有公式…….. 

剩下的就要参考我给出的程序作出自己的理解吧,靠你们了,骚年们! 


程序示例:


函数

/*----------------------------------------------------------------------------------------------

 * 功能:产生单路SPWM波

 * 输入:无

 * 输出:P1.4

 * 注意:定时器也为TA1.1;载波频率为126.26K;;默认正弦频率为100HZ,幅度未知

 */

void SPWM_1Way_Init(void)

{

    P1SEL |=BIT4;

    P1DIR |=BIT4;

    //P1DS |=BIT4; //全力驱动

    P1OUT &=~BIT4;

    spwm_i=0;

    TA0CCR0 =198;//载波126.26KHZ

    TA0CCR3 =Lab1[spwm_i];

    TA0CCTL3 =OUTMOD_7;

    TA0CTL =TASSEL_2+MC_1+TACLR;//选择时钟为SMCLK,UP模式


    P2SEL |=BIT0;

    P2DIR |=BIT0;

    P2OUT &=~BIT0;

    TA1CCR0 =2499;//25000000/(100*100)=2500:100Hz,100个点:10KHZ(时间不太准我做了些补偿)

    TA1CTL =TASSEL_2+MC_1+TACLR;//选择时钟为SMCLK,UP模式

    TA1CTL  |= TAIE;//开启中断


    __enable_interrupt();//开启总中断

}

void SPWM_1Way_Set_Freq(unsigned int freq)

{

    unsigned long freq_num;

    freq_num=250000/(freq)-1;

    TA1CCR0 =freq_num;

}

/*

 * 功能:输出两路SPWM波,相位可调

 * 输入:无

 * 输出:P1.4,P1.5

 * 注意:定时器也为TA1.1;载波频率为126.26K;;默认正弦频率为100HZ,幅度未知

 */

void SPWM_2Way_Init(void)

{

    P1SEL |=BIT4+BIT5;

    P1DIR |=BIT4+BIT5;

    //P1DS |=BIT4+BIT5; //全力驱动

    P1OUT &=~BIT4+BIT5;

    spwm_i=0;

    spwm_j=50;//控制相位

    TA0CCR0 =198;//载波126.26KHZ

    TA0CCR3 =Lab1[spwm_i];

    TA0CCR4 =Lab1[spwm_j];

    TA0CCTL3 =OUTMOD_7;

    TA0CCTL4 =OUTMOD_7;

    TA0CTL =TASSEL_2+MC_1+TACLR;//选择时钟为SMCLK,UP模式


    P2SEL |=BIT0;

    P2DIR |=BIT0;

    P2OUT &=~BIT0;

    TA1CCR0 =2499;//25000000/(100*100)=2500:100Hz,100个点:10KHZ

    TA1CTL =TASSEL_2+MC_1+TACLR;//选择时钟为SMCLK,UP模式

    TA1CTL  |= TAIE;//开启中断


    __enable_interrupt();//开启总中断

}

void SPWM_2Way_Set_Freq(unsigned int freq)

{

    unsigned long freq_num;

    freq_num=250000/(freq)-1;

    TA1CCR0 =freq_num;

}

/*

 * 功能:中断函数,改变SPWM中占空比寄存器的值

 * 输入:无

 * 输出:无

 * 注意:为0时双路输出,为1时单路输出

 */

#if 0

#pragma vector=TIMER1_A1_VECTOR

__interrupt void TimerA1(void)

{

        TA0CCR3 =Lab1[spwm_i++];

        if(spwm_i==100)spwm_i=0;

    TA1IV=0;    //GPIO的单独中断会自动清零,可TIMER的不会,所以要软件清零;!!

}

#else

#pragma vector=TIMER1_A1_VECTOR

__interrupt void TimerA1(void)

{

    TA0CCR3 =Lab1[spwm_i++];

    if(spwm_i==100)spwm_i=0;

    TA0CCR4 =Lab1[spwm_j++];

    if(spwm_j==100)spwm_j=0;

    TA1IV=0;    //GPIO的单独中断会自动清零,可TIMER的不会,所以要软件清零;!!

}

#endif


头文件PWM.h

/*

 * PWM.h

 *

 *  Created on: 2016-8-22

 *      Author: Flyskyr

 */


#ifndef PWM_H_

#define PWM_H_


extern unsigned int spwm_i,spwm_j;

extern unsigned int Lab_base[];

extern float Lab1[];


extern void SPWM_1Way_Init(void);

extern void SPWM_1Way_Set_Freq(unsigned int freq);

extern void SPWM_2Way_Init(void);

extern void SPWM_2Way_Set_Freq(unsigned int freq);


#endif /* PWM_H_ */


头文件include.h

/*

 * include.h

 *

 *  Created on: 2016-8-18

 *      Author: Flyskyr

 */


#include

#include"PWM.h"


unsigned int spwm_i,spwm_j;

unsigned int Lab_base[]={99,105,111,117,123,129,135,141,146,152,157,162,166,171,175,179,182,185,188,191,193,194,196,197,197,198,197,197,196,194,193,191,188,185,182,179,175,171,166,162,157,152,146,141,135,129,123,117,111,105,99,92,86,80,74,68,62,56,51,45,40,35,31,26,22,18,15,12,9,6,4,3,1,0,0,0,0,0,1,3,4,6,9,12,15,18,22,26,31,35,40,45,51,56,62,68,74,80,86,92

};

float Lab1[]={99,105,111,117,123,129,135,141,146,152,157,162,166,171,175,179,182,185,188,191,193,194,196,197,197,198,197,197,196,194,193,191,188,185,182,179,175,171,166,162,157,152,146,141,135,129,123,117,111,105,99,92,86,80,74,68,62,56,51,45,40,35,31,26,22,18,15,12,9,6,4,3,1,0,0,0,0,0,1,3,4,6,9,12,15,18,22,26,31,35,40,45,51,56,62,68,74,80,86,92

};//这个float数组我是用来调节调制深度的,改变这里的值就可以改变输出的幅度了

 


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
起重变频调速系统中制动电阻功率的计算