程序感觉没错,看到了SPWM的波形,但是在逆变中观察的负载不是正弦波
48~52hz的,通过电位器可以调节,载波是20kHz,驱动MOSfet,可否直接驱动,在proteus中仿真
#include
#define uchar unsigned char
#define uint unsigned int
__CONFIG(0X3F32);
const uchar sinTab_50[100]={ //正弦波代码数组
0x4B,0x4D,0x4F,0x51,0x53,0x54,0x56,0x58,0x5A,0x5C,
0x5E,0x5F,0x61,0x63,0x65,0x66,0x68,0x6A,0x6B,0x6D,
0x6E,0x70,0x71,0x73,0x74,0x75,0x77,0x78,0x79,0x7A,
0x7C,0x7D,0x7E,0x7F,0x80,0x80,0x81,0x82,0x83,0x83,
0x84,0x85,0x85,0x86,0x86,0x86,0x87,0x87,0x87,0x87,
0x87,0x87,0x87,0x87,0x87,0x86,0x86,0x86,0x85,0x85,
0x84,0x83,0x83,0x82,0x81,0x80,0x80,0x7F,0x7E,0x7D,
0x7C,0x7A,0x79,0x78,0x77,0x75,0x74,0x73,0x71,0x70,
0x6E,0x6D,0x6B,0x6A,0x68,0x66,0x65,0x63,0x61,0x5F,
0x5E,0x5C,0x5A,0x58,0x56,0x54,0x53,0x51,0x4F,0x4D,
};
//0-199 0x4C,
const uchar sinTab_48[104]={ //正弦波代码数组---48Hz
0x4B,0x4D,0x4F,0x50,0x52,0x54,0x56,0x58,0x59,0x5B,
0x5D,0x5F,0x60,0x62,0x64,0x65,0x67,0x68,0x6A,0x6C,
0x6D,0x6F,0x70,0x71,0x73,0x74,0x75,0x77,0x78,0x79,
0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,0x80,0x81,0x82,0x82,
0x83,0x84,0x84,0x85,0x85,0x86,0x86,0x86,0x87,0x87,
0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x86,0x86,0x86,
0x85,0x85,0x84,0x84,0x83,0x82,0x82,0x81,0x80,0x7F,
0x7E,0x7D,0x7C,0x7B,0x7A,0x79,0x78,0x77,0x75,0x74,
0x73,0x71,0x70,0x6F,0x6D,0x6C,0x6A,0x68,0x67,0x65,
0x64,0x62,0x60,0x5F,0x5D,0x5B,0x59,0x58,0x56,0x54,
0x52,0x50,0x4F,0x4D};
//0-104
const uchar sinTab_49[102]={
0x4B,0x4D,0x4F,0x51,0x52,0x54,0x56,0x58,0x5A,0x5B,
0x5D,0x5F,0x61,0x62,0x64,0x66,0x67,0x69,0x6B,0x6C,
0x6E,0x6F,0x71,0x72,0x73,0x75,0x76,0x77,0x79,0x7A,
0x7B,0x7C,0x7D,0x7E,0x7F,0x80,0x81,0x82,0x82,0x83,
0x84,0x84,0x85,0x85,0x86,0x86,0x86,0x87,0x87,0x87,
0x87,0x87,0x87,0x87,0x87,0x87,0x86,0x86,0x86,0x85,
0x85,0x84,0x84,0x83,0x82,0x82,0x81,0x80,0x7F,0x7E,
0x7D,0x7C,0x7B,0x7A,0x79,0x77,0x76,0x75,0x73,0x72,
0x71,0x6F,0x6E,0x6C,0x6B,0x69,0x67,0x66,0x64,0x62,
0x61,0x5F,0x5D,0x5B,0x5A,0x58,0x56,0x54,0x52,0x51,
0x4F,0x4D};
//0-102
const uchar sinTab_51[98]={
0x4B,0x4D,0x4F,0x51,0x53,0x55,0x56,0x58,0x5A,0x5C,
0x5E,0x60,0x62,0x63,0x65,0x67,0x68,0x6A,0x6C,0x6D,
0x6F,0x70,0x72,0x73,0x75,0x76,0x77,0x79,0x7A,0x7B,
0x7C,0x7D,0x7E,0x7F,0x80,0x81,0x82,0x83,0x83,0x84,
0x85,0x85,0x85,0x86,0x86,0x87,0x87,0x87,0x87,0x87,
0x87,0x87,0x87,0x87,0x86,0x86,0x85,0x85,0x85,0x84,
0x83,0x83,0x82,0x81,0x80,0x7F,0x7E,0x7D,0x7C,0x7B,
0x7A,0x79,0x77,0x76,0x75,0x73,0x72,0x70,0x6F,0x6D,
0x6C,0x6A,0x68,0x67,0x65,0x63,0x62,0x60,0x5E,0x5C,
0x5A,0x58,0x56,0x55,0x53,0x51,0x4F,0x4D};
//0-98
const uchar sinTab_52[96]={
0x4B,0x4D,0x4F,0x51,0x53,0x55,0x57,0x59,0x5B,0x5C,
0x5E,0x60,0x62,0x64,0x66,0x67,0x69,0x6B,0x6C,0x6E,
0x70,0x71,0x73,0x74,0x75,0x77,0x78,0x79,0x7B,0x7C,
0x7D,0x7E,0x7F,0x80,0x81,0x82,0x82,0x83,0x84,0x84,
0x85,0x85,0x86,0x86,0x86,0x87,0x87,0x87,0x87,0x87,
0x87,0x87,0x86,0x86,0x86,0x85,0x85,0x84,0x84,0x83,
0x82,0x82,0x81,0x80,0x7F,0x7E,0x7D,0x7C,0x7B,0x79,
0x78,0x77,0x75,0x74,0x73,0x71,0x70,0x6E,0x6C,0x6B,
0x69,0x67,0x66,0x64,0x62,0x60,0x5E,0x5C,0x5B,0x59,
0x57,0x55,0x53,0x51,0x4F,0x4D};
//0-96
/*基波50Hz,载波20KHz,半周期内的采样点数为100,则pwm的周期=1/20ms=50us*/
uchar spwm_hz,hz,result;
void delay(uchar m)
{
uchar x,y;
for(x=m;x>0;x--)
for(y=110;y>0;y--);
}
/*void delay_spwm(uchar m)
{
while(m)
{
m--;
PORTB=0X00;
}
}*/
void init()
{
TRISB=0XFF; //
PR2=149; //SPWM为50uS=150*4*(1/12)
// ECCPAS=0x5f; //设置自动关闭功能,SPWM输出高阻态。
// PWM1CON=0XFF;
CCP1CON=0X7C; //spwm模式选择
CCPR1L=0; //占空比为0
TMR2IF=0;
T2CON=0X04; //不分频,使能TMR2
}
void inter_ADC(void)
{
TRISA=0x01; //选择AN1为电位器输入信号端口
PORTA=0x10;
ADCON0=0x01; // 选择模拟通道AN0,时钟位:Fosc/8,使能ADC
ADCON1=0x04; //AN2(RA2)为数字I/O,AN0、1、3为模拟...RA4
ADIF=0; //清零ADC中断标志
ADIE=1; //允许ADC中断
GIE=1; //GIE:全局开中断,PEIE:开外设中断
PEIE=1;
delay(5);
GODONE=1; //启动AD转换
while(GODONE); //等待AD转换完成
}
void interrupt adc(void)
{
if(ADIF&&ADIE)
{
result=ADRES;
if(result<=50)
hz=48;
else
{
if(result<=100)
hz=49;
else
{
if(result<=150)
hz=50;
else
{
if(result<=200)
hz=51;
else
hz=52;
}
}
}
ADIF=0;
}
}
void spwm()
{
uchar m,i,i_i;
if(TMR2IF)
{
TRISB=0X17; //P1A,P1B,P1C,P1D为输出
TMR2IF=0; //清零TMR2
PR2=149;
if(i==i_i)
{
i=0;
m=!m;
// delay_spwm(2);
}
switch(spwm_hz)
{
case 50:
CCPR1L=sinTab_50[i/2]; //占空比
i_i=200;
break;
case 48:
CCPR1L=sinTab_48[i/2]; //占空比
i_i=208;
break;
case 49:
CCPR1L=sinTab_49[i/2]; //占空比
i_i=204;
break;
case 51:
CCPR1L=sinTab_51[i/2]; //占空比
i_i=196;
break;
case 52:
CCPR1L=sinTab_52[i/2]; //占空比
i_i=192;
break;
}
if(m)
{
CCP1CON=0X7C; //D...A
}
else
{
CCP1CON=0XfC; //B...C
}
i++;
}
}
void main ()
{
init();
inter_ADC();
while(1)
{
spwm();
spwm_hz=hz;
GODONE=1;
}
}