可不可以请教一下,在单片机生成spwm波的程序中那个pwm的表是怎么算出来的

可不可以请教一下,在单片机生成spwm波的程序中那个pwm的表是怎么算出来的,第1张

spwm表其实是占空比的表它的公式是这样的:p = d + Asin(2pi x / c)d是直流分量,如果取0,那么spwm会出现正负A是振幅,它决定最大值和最小值pi是314c是要取的点数,x是变量,指出当前取到那个数,它是0~c之间变化的。 欢迎追问

spwm的物理意义:采样反馈信号,可以是高速采样一个正弦周期,进行傅里叶变换,求取该周期的基波有效值。为了简化程序,也可以采用低通滤波器滤波后,进行高速采样,直接计算方均根。

正弦波逆变器,关注的是输出spwm基波的有效值,采用pid控制,应该以输出spwm的基波有效值为反馈量,有效值至少是一个周期才有意义,每个或多个正弦波周期调整一次spmw表的值即可。

等面积法:

该方案实际上就是SPWM法原理的直接阐释,用同样数量的等幅而不等宽的矩形脉冲序列代替正弦波,然后计算各脉冲的宽度和间隔,并把这些数据存于微机中,通过查表的方式生成PWM信号控制开关器件的通断,以达到预期的目的。

由于此方法是以SPWM控制的基本原理为出发点,可以准确地计算出各开关器件的通断时刻,其所得的的波形很接近正弦波,但其存在计算繁琐,数据占用内存大,不能实时控制的缺点。

看来你还不理解定时器的工作原理, 向上计数模式工作时,CNT(定时器计数)从0开始计数时钟源脉冲数,达到ARR时开始下一个0开始计数周期,这就是三角波(频率由时钟源和ARR决定)。

通道工作在比较模式时 ,CCR(比较寄存器)数值和CNT进行比较,比较结果直接回输出在对应通道的引脚上。每个周期结束时更新比较寄存器的数据(参考正玄波数据点按照载波频率采样的交点数值,事先就计算好的),就可以输出相应SPWM了

#include<pich>

#include<pic16f685h>

#include<mathh>

//__CONFIG(0X002A); //配置字,禁止欠压复位BOR,16M外部晶振,上电延时使能,禁止看门狗

__CONFIG(HS&PWRTEN&WDTEN);

//打开看门狗,选择高速晶振,上电延时复位,掉电复位使能,代码保护

float sin_am, sin_l,sin_d;//浮点数,幅值变量,临时变量,临时变量

bit sin_up;//sin函数正负半周标志

void intdelay();

void DELAY();

void init_start();

void CCP_start();

const unsigned char sina_[]={7 ,15 ,22 ,29 ,37 ,44 ,51 ,58 ,65 ,72 ,79 ,86 ,92 ,99 ,106 ,112 ,118

,124 ,130 ,136 ,141 ,147 ,152 ,157 ,162 ,166 ,171 ,175 ,179 ,183 ,186 ,190 ,193 ,196 ,198 ,201 ,203

,205 ,206 ,208 ,209 ,210 ,210 ,211 ,211 ,211 ,210 ,210 ,209 ,208 ,206 ,205 ,203 ,201 ,198 ,196 ,193

,190 ,186 ,183 ,179 ,175 ,171 ,166 ,162 ,157 ,152 ,147 ,141 ,136 ,130 ,124 ,118 ,112 ,106 ,99 ,92

,86 ,79 ,72 ,65 ,58 ,51 ,44 ,37 ,29 ,22 ,15 ,7 ,0

};

const unsigned char sinb_[]={7 ,15 ,22 ,29 ,37 ,44 ,51 ,58 ,65 ,72 ,79 ,86 ,92 ,99 ,106 ,112 ,118

,124 ,130 ,136 ,141 ,147 ,152 ,157 ,162 ,166 ,171 ,175 ,179 ,183 ,186 ,190 ,193 ,196 ,198 ,201 ,203

,205 ,206 ,208 ,209 ,210 ,210 ,211 ,211 ,211 ,210 ,210 ,209 ,208 ,206 ,205 ,203 ,201 ,198 ,196 ,193

,190 ,186 ,183 ,179 ,175 ,171 ,166 ,162 ,157 ,152 ,147 ,141 ,136 ,130 ,124 ,118 ,112 ,106 ,99 ,92

,86 ,79 ,72 ,65 ,58 ,51 ,44 ,37 ,29 ,22 ,15 ,7 ,0

};

//---------------------------------------------------------------------------------------

//const unsigned char sina_[]={4, 7, 11, 15, 18, 22, 26, 29, 33, 37, 40, 44, 47, 51,

// 55, 58, 62, 65, 69, 72, 76, 79, 82, 86, 89, 92, 96, 99,

// 102, 106, 109, 112, 115, 118, 121, 124, 127, 130,

// 133, 136, 138, 141, 144, 147, 149, 152, 154, 157,

// 159, 162, 164, 166, 169, 171, 173, 175, 177, 179,

// 181, 183, 185, 186, 188, 190, 191, 193, 194, 196,

// 197, 198, 200, 201, 202, 203, 204, 205, 206, 206,

// 207, 208, 208, 209, 209, 210, 210, 210, 211, 211,

// 211, 211, 211, 211, 211, 210, 210, 210, 209, 209,

// 208, 208, 207, 206, 206, 205, 204, 203, 202, 201,

// 200, 198, 197, 196, 194, 193, 191, 190, 188, 186,

// 185, 183, 181, 179, 177, 175, 173, 171, 169, 166,

// 164, 162, 159, 157, 154, 152, 149, 147, 144, 141,

// 138, 136, 133, 130, 127, 124, 121, 118, 115, 112,

// 109, 106, 102, 99, 96, 92, 89, 86, 82, 79, 76, 72, 69, 65, 62, 58,

// 55, 51, 47, 44, 40, 37, 33, 29, 26, 22, 14, 7, 0, 7, 4, 0

//};

//----------------------------------------------------------------------------------

//const unsigned char sinb_[]={4, 7, 11, 15, 18, 22, 26, 29, 33, 37, 40, 44, 47, 51,

// 55, 58, 62, 65, 69, 72, 76, 79, 82, 86, 89, 92, 96, 99,

// 102, 106, 109, 112, 115, 118, 121, 124, 127, 130,

// 133, 136, 138, 141, 144, 147, 149, 152, 154, 157,

// 159, 162, 164, 166, 169, 171, 173, 175, 177, 179,

// 181, 183, 185, 186, 188, 190, 191, 193, 194, 196,

// 197, 198, 200, 201, 202, 203, 204, 205, 206, 206,

// 207, 208, 208, 209, 209, 210, 210, 210, 211, 211,

// 211, 211, 211, 211, 211, 210, 210, 210, 209, 209,

// 208, 208, 207, 206, 206, 205, 204, 203, 202, 201,

// 200, 198, 197, 196, 194, 193, 191, 190, 188, 186,

// 185, 183, 181, 179, 177, 175, 173, 171, 169, 166,

// 164, 162, 159, 157, 154, 152, 149, 147, 144, 141,

// 138, 136, 133, 130, 127, 124, 121, 118, 115, 112,

// 109, 106, 102, 99, 96, 92, 89, 86, 82, 79, 76, 72, 69, 65, 62, 58,

// 55, 51, 47, 44, 40, 37, 33, 29, 26, 22, 14, 7, 0, 7, 4, 0

//};

//--------------------------------------------------------------------------------------

//const unsigned char sinb_[]=

// {219, 215, 211, 207, 204, 200, 196, 192, 188, 184,

// 180, 177, 173, 169, 165, 162, 158, 154, 150, 147,

// 143, 139, 136, 132, 129, 125, 122, 118, 115, 112,

// 108, 105, 102, 98, 95, 92, 89, 86, 83, 80, 77, 74, 71, 68, 65, 63,

// 60, 57, 55, 52, 50, 47, 45, 43, 40, 38, 36, 34, 32, 30, 28, 26, 24, 23, 21,

// 19, 18, 16, 15, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 3, 2, 2,

// 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4,

// 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 19, 21, 23, 24, 26, 28,

// 30, 32, 34, 36, 38, 40, 43, 45, 47, 50, 52, 55, 57, 60, 63, 65, 68, 71,

// 74, 77, 80, 83, 86, 89, 92, 95, 98, 102, 105, 108, 112, 115,

// 118, 122, 125, 129, 132, 136, 139, 143, 147,

// 150, 154, 158, 162, 165, 169, 173, 177, 180,

// 184, 188, 192, 196, 205, 215, 219, 223, 215,

// 219, 223

//};

unsigned char sin_num;//SIN函数表查表变量

//===================================================================================

void main()

{

// CLRWDT();//清除看门狗

TRISB=0X00; //RB4RB5RB6RB7为输出

TRISC=0XCB; //11011001设置RC0RC1RC3RC4RC6RC7为输入,其它为输出

PORTB=0X00;

PORTC=0X00;

//--------------------------------------

OPTION=0X42; //使能PORTA上拉,RA2下降沿触发中断(上升:0X47),内部时钟,预分频器分配给TIMER0,分频比为1:8

sin_up=0; //正负半周SIN函数

sin_num=0; //脉宽周期调整计数器

PDC1=1; //死区延时05US

INTCON=0XE0; //11100000:GIE开总中断,timer0使能,

TMR2IE=1;

CCP1CON=0X8C; //10001100;

CCPR1L=0X00;

PR2=0XDF; //设置PWM的工作周期,16Mhz,PWM周期18khz

T2CON=0x04; // 00100100打开TMR2,且使其后分频为比1:5,预分频比为1

GIE=1; //开全局中断

while(1)

{

CLRWDT(); //清除看门狗

PDC1=1;

T2CON=0x04; // 00100100打开TMR2,且使其后分频为比1:5,预分频比为1,

TMR2IE=1; //打开定时器2中断使能

CCP1CON=0X8C; //10001100;

PR2=0XDF; //设置PWM的工作周期,16Mhz,PWM周期18khz

// DELAY();

}

}

//----------------------------------------------------------

//软件延时子程序/

void DELAY()

{

unsigned int i;

for(i=2000;i>0;i--);

}

//-------------中断服务程序------------------------------------

void interrupt int1(void)

{

if(TMR2IF&&TMR2IE)

{

TMR2IF=0;

CLRWDT();

if(sin_num==88){sin_num=0;sin_up=!sin_up;}

if((sin_up==0)&&(sin_num==0)) //低频正半周

{

CCPR1L=0;

CCP1CON=0;

RC4=RC5=0;

RB7=0;

RB6=!RB6;

}

if((sin_up==1)&&(sin_num==0)) //低频负半周

{

CCPR1L=0;

CCP1CON=0;

RC4=RC5=0;

RB6=0;

RB7=!RB7;

}

if(sin_up==0)

{

CCP1CON=0X8C;

CCPR1L=sinb_[sin_num]; //高频正半周

sin_num++;

}

if(sin_up==1)

{

CCP1CON=0X8C;

CCPR1L=sina_[sin_num]; //高频负半周

sin_num++;

}

}

}

linjinfeng_job@163com 能发给一份SPWM的程序吗

用51单片机啊,大致看你电路觉得用计算法不知道性能如何。而且还要调压,精度要求还蛮高,功率还比较大的,个人觉得有难度。仅仅spwm的话倒好说,倒是后面有些难度。如果单片机计算性能达不到,大不了不用软件调制。如果是毕业设计,建议跟你导师谈谈用什么方案可行。

Class Account{

private int id;

private double balance;

private double annuallnterestRate;

private Date dateCreated;

public Account(){

thisid = 0;

thisbalance = 0;

thisannuallnterestRate = 0;

thisdateCreated = new Date();

}

public Account(int id, double balance){

thisid = id;

thisbalance = balance;

thisdateCreated = new Date();

}

public int getId(){

return thisid;

}

public void setId(int id){

thisid = id;

}

void

delay(uchar

i)

{

uint

x,y;

for(x=i;x>0;x--)

for(y=100;y>0;y--);

}

void

main()

{

uchar

pwm

=

1,h

=

20;

while(1)

{

RC3

=1;

delay(pwm);

RC3

=

0;

delay(h

-

pwm);

}

}

改变pwm的值(1-19),

就可以改变输出高电平的宽度,还有其它的办法,这是最简单的,软件延时

以上就是关于可不可以请教一下,在单片机生成spwm波的程序中那个pwm的表是怎么算出来的全部的内容,包括:可不可以请教一下,在单片机生成spwm波的程序中那个pwm的表是怎么算出来的、spwm控制策略的物理意义、想知道STM32用调制法产生SPWM波程序是不是符合我下面猜测的呢等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9804756.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-02
下一篇 2023-05-02

发表评论

登录后才能评论

评论列表(0条)

保存