用51单片机啊,大致看你电路觉得用计算法不知道性能如何。而且还要调压,精度要求还蛮高,功率还比较大的,个人觉得有难度。仅仅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
}
用定时器定时10ms,中断程序里将两个IO管脚状态取反即可。但两个管脚的原始状态是相反的。
大致 程序如下:
主程序里
TMOD=0X01;
TH0=
TL0=
EA=1;
ET0=1;
PWM1=0;//一个管脚置低
PWM2=1;//另一个管脚置高
TR0=1;
中断程序中:
TH0=
TL0=
PWM1=!PWM1;
PWM2=!PWM2;
你要控制舵机是不是?
你用定时器0做时钟源,(255-计数初值)256频率12=系统频率
我现在没有完整程序 给你部分配置
void pwm1_1(void) //PWM的初始化
{
PCA0MD=0x04; //PCA clock is T0 over
PCA0CPL0=8; //32~8
PCA0CPM0=0x42; //设置左轮为8为PWM输出
PCA0CPH0=8;
PCA0CN=0x40; //允许PCA工作
}
void t01_init(void)//Bound rate:2k
{
TCON=0x50; //0101 0000
TMOD=0x52; //T1,T0:timer
CKCON=0x01; //4
TH0=21; //PCA 50Hz 时钟
TL0=21;
}
我可以提供编程方法,
1、计算好输出的SPWM的频率和周期。
2、依据SPWM周期使用sin函数计算若干点的宽度值;
3、输出信号不断更新计算好的脉冲宽度值输出不同宽度实现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的程序吗
以上就是关于急!!!基于8951单片机产生单相SPWM波的程序怎么写的,我用IR2101驱动的全部的内容,包括:急!!!基于8951单片机产生单相SPWM波的程序怎么写的,我用IR2101驱动的、用单片机输出 spwm 波形、基于at89c51系列单片机的两路互补SPWM波形实现,程序如何编写要求频率50hz等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)