打印

使用pic16f716制作spwm调制器,用于逆变

[复制链接]
2395|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
静寂列车|  楼主 | 2013-9-9 15:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 静寂列车 于 2013-9-9 15:35 编辑

程序感觉没错,看到了SPWM的波形,但是在逆变中观察的负载不是正弦波
48~52hz的,通过电位器可以调节,载波是20kHz,驱动MOSfet,可否直接驱动,在proteus中仿真
#include<pic.h>
#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;
        }
}

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

5

帖子

0

粉丝