我可以提供编程方法,
1、计算好输出的SPWM的频率和周期。
2、依据SPWM周期使用sin函数计算若干点的宽度值;
3、输出信号不断更新计算好的脉冲宽度值输出不同宽度实现SPWM信号输出。
spwm表其实是占空比的表它的公式是这样的:p = d + Asin(2pi x / c)d是直流分量,如果取0,那么spwm会出现正负A是振幅,它决定最大值和最小值pi是314c是要取的点数,x是变量,指出当前取到那个数,它是0~c之间变化的。 欢迎追问
#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的程序吗
stc12c5608ad单片机有硬件PWM功能,只要在主程序里按正弦规律改变输出脉冲的占空比即可,可将正弦波分成50个时间段,每个时间段是20ms/500=400us,用定时器定时400us改变一次CCAP1L的值(该值除以256即是占空比)即可,CCAP1L的值可以在程序中用三角函数计算,也可以事先计算好存入数组中.
//
void PWM_init (void){//PWM初始化函数
CMOD=0x02; //设置PCA定时器,计数频率为晶振频率/2 当为12Mhz时,PWM输出频率约234Khz
CL=0x00;
CH=0x00;
CCAPM1=0x42; //PWM1设置PCA工作方式为PWM方式(0100 0010)
CCAP1L=0x00; //设置PWM1初始值与CCAP0H相同
CCAP1H=0x00; // PWM1初始时为0
CR=1; //启动PCA定时器
}
//void PWM1_set (uchar a)//PWM1占空比设置函数
{
CCAP1L=a; //设置值直接写入CCAP1L
CCAP1H=a; //设置值直接写入CCAP1H
}
以上就是关于如何用STC12C5A60S2单片机直接发生SPWM波的程序,最好能调输出方波的频率全部的内容,包括:如何用STC12C5A60S2单片机直接发生SPWM波的程序,最好能调输出方波的频率、可不可以请教一下,在单片机生成spwm波的程序中那个pwm的表是怎么算出来的、PIC发SPWM控制IR2110的原理跟程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)