分享

PIC16F73做的逆变器程序及原理图

 共同成长888 2015-07-11
 
 
//------------------------------------------------------------ 
//       spwm信号调制 
//------------------------------------------------------------ 
#include 
#include 
//系统配置 
__CONFIG(HS&PWRTEN&BOREN&PROTECT&WDTEN); 
//打开看门狗,选择高速晶振,上电延时复位,掉电复位使能,代码保护 
//------------------------------------------------------------ 
//指示灯宏定义 
#define L1_RED_ON   RB1=1;RB2=0;//L1红灯亮 
#define L1_OFF   RB1=0;RB2=0; 
#define L2_RED_ON   RB4=1;RB3=0;//L2红灯亮 
#define L2_OFF   RB4=0;RB3=0; 
#define L3_RED_ON   RB7=1;RB5=0;//L3红灯亮 
#define L3_OFF   RB7=0;RB5=0; 
#define L1_GREE_ON  RB2=1;RB1=0;//L1绿灯亮 
#define L2_GREE_ON  RB3=1;RB4=0;//L2绿灯亮 
#define L3_GREE_ON  RB5=1;RB7=0;//L3绿灯亮 
//----------------------------------------------------------- 
//模拟输入通道宏定义 
#define AN0 CHS2=0;CHS1=0;CHS0=0; 
#define AN1 CHS2=0;CHS1=0;CHS0=1; 
#define AN2 CHS2=0;CHS1=1;CHS0=0; 
//----------------------------------------------------------- 
//----------------------------------------------------------- 
void adc_init() 

//ad时钟选择 
ADCS1=1;//FOSC/32 
ADCS0=0; 
/*IF CPU IS PIC16F7X7 
VCFG1=0; 
VCFG0=0;//vref=vdd-vss 
*/ 
PCFG0=0; 
PCFG1=0; 
PCFG2=0;//VREF=VDD-VSS 
ADON=1;//打开ad模块 
ADIF=0;//清除ad中断标志 
ADIE=0;//打开ad模块中断 

//----------------------------------------------------------- 
void port_init()//端口初始化 

//端口b设置 
TRISB0=0;TRISB1=0;TRISB2=0;TRISB3=0;TRISB4=0;TRISB5=0; 
TRISB6=1;//输入 
TRISB7=0;//RB端口方向设置 
PORTB=0;//输出0 
RBPU=0;//使能内部弱上拉 
INTE=0;//禁止RB0中断 
RBIF=0; 
RBIE=1;//允许RB端口电平变化中断 
//端口c设置 
TRISC=0X00;//PORTC are outputs 
PORTC=0;//输出为0 
RC1=RC2=0; 
RC3=1;RC4=0; 
//timer0 init 
T0CS=0;//选择内部指令时钟 
T0IF=0; 
//T0IE=1;//在第一次ccp1比较后打开中断使能 
//timer1 
TMR1CS=0;//定时器模式 

//---------------------------------------------------------- 
//---------------------------------------------------------- 
//软件延时子程序*/ 
void       DELAY() 

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

//---------------------------------------------------------- 
void init_start()//开始 

L1_RED_ON;L2_RED_ON;L3_RED_ON; 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
L2_OFF;L3_OFF;L1_OFF; 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
L1_GREE_ON;L2_GREE_ON;L3_GREE_ON; 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
DELAY();DELAY();DELAY();DELAY(); 
L2_OFF;L3_OFF;L1_OFF; 

//---------------------------------------------------------- 
bit k,power;//关机及按键标志 
bank1 unsigned char tm_sum;//系统实际变量 
bank1 unsigned char ad_res_1,ad_res_0,ad_res_2; //ad转换结果寄存器 
bank1 float  sin_am,sin_l,sin_d;//浮点数,幅值变量,临时变量,临时变量 
bit sin_up;//sin函数正负半周标志 
bit tmr_s,tmr_d,crut_ie;//定时标志,定时标志变化标志,电流延时保护允许 
unsigned char crut_tmr;//电流延时时间变量 
unsigned char power_s;//电源动作延时变量 
bit power_ie;//电源允许动作标志 
bit power_up;//初次开机标志 
unsigned char power_up_s;//初次开机延时标志 
bit crut_if;volue_if; 
//-----------AD1通道转换-------------------- 
void ad_0() 

AN0;//选择通道0 
DELAY();//延时,采样电容充电 
ADGO=1;//开器AD 
while(ADGO);//等待ad结束 
ad_res_0=ADRES;//结果转存到变量AD_RES_0 

//-----------AD1通道转换-------------------- 
void ad_1() 

AN1; DELAY(); 
ADGO=1;while(ADGO); 
ad_res_1=ADRES; 
if(ad_res_1>132){sin_am-=0.005;if((ad_res_1-132)>10)sin_am-=0.04; } 
else 
if((ad_res_1<=132)&&(ad_res_1>=130))sin_am+=0; 
else 
if(ad_res_1<130) {sin_am+=0.005;if((130-ad_res_1) >10)sin_am+=0.04;} 
if(sin_am>1.6)sin_am=1.6; 

//------------AD2通道转换------------------- 
void ad_2() 

AN2; DELAY(); 
ADGO=1;while(ADGO); 
ad_res_2=ADRES; 

//------------------------------------------- 
const unsigned char sin_[]={40,50,73,85,100,113,127,141,157,170,180,189,196,200,203, 
204,//正半周 
204,//负半周 
203,200,195,188,179,169,157,144,129,113,96,78,59,39,15};
unsigned char sin_num;//SIN函数表查表变量 
//------------------------------------------------------------------------------- 
void CCP_start() 

CCPR2L=0X0;//设置CCP2,0%的脉宽输出 
CCPR1L=0X0;//设置CCP1,0%的脉宽输出 
TRISC=0X00;//PORTC are outputs 
PR2=0Xff;//设置PWM的工作周期,16Mhz,PWM周期15.562khz 
CCP1M3=1;CCP1M2=1;//CCP1模块PWM模式 
CCP2M3=1;CCP2M2=1;//CCP2模块PWM模式 
sin_up=1;//正负半周SIN函数 
sin_num=0;//脉宽周期调整计数器 
sin_am=0;//sin函数的幅值 
sin_am=0.3000;//sin函数的幅值 
crut_ie=1;//电流慢保护允许 

//-------------中断服务程序------------------------------------ 
void interrupt key_ccp_timer() 

if(TMR2IF&TMR2IE){TMR2IF=0;//定时器2中断服务函数 
  if(sin_num==31){sin_num=0;sin_up=!sin_up;} 
  sin_d=sin_[sin_num]; 
  sin_l=sin_am*sin_d;if(sin_l>=255)sin_l=255;//限幅 
  if(sin_up) 
  {CCPR2L=(unsigned char)sin_l;CCPR1L=0;}//换向 
  else 
      {CCPR1L=(unsigned char)sin_l;CCPR2L=0;}//换向 
  sin_num++; 

CLRWDT();//清除看门狗 
if(RBIF&&RBIE){RBIF=0;if((!RB6)&&power_ie)k=1;}//端口b中断服务函数 
if(TMR1IF&TMR1IE){TMR1IF=0;tm_sum++;if(tm_sum==31){tm_sum=0;tmr_s=!tmr_s;tmr_d=1;}} 
//定时器1中断服务函数 

//************************************************************************************ 
main() 

CLRWDT(); //清除看门狗 
port_init();//端口初始化 
init_start();//开机状态 
adc_init();//ad通道初始化 
//----- 
RC4=0;//继电器关闭 
RC3=1;//关闭脉冲封锁 
//----- 
TMR1CS=0;//同步模式 
T1SYNC=0;//内部指令周期 
TMR1H=0XFD; 
TMR1L=0X10;//定时器1初值 
TMR1IE=1;//定时器1中断使能
//----- 
TRISC=0X00;//端口C输出 
TRISC1=TRISC2=1;//RC1,RC2输入模式 
PEIE=1;//外围模块中断使能 
TMR2IE=1;//打开定时器2中断使能 
GIE=1;//开全局中断 
TMR2ON=1;//打开定时器2 
TOUTPS3=0;TOUTPS2=1;TOUTPS1=0;TOUTPS0=0;//定时器2后分频器5分频 
TMR1ON=1;//打开定时器1 
power_ie=1;//允许开机 
while(1) 

CLRWDT();//清除看门狗 
if(k){ 
  DELAY();DELAY();DELAY();DELAY();DELAY();DELAY();//延时 
  DELAY();DELAY();DELAY();DELAY();DELAY();DELAY();//延时 
if(k&&RB6){k=0;power=!power;}//开关机标志 
if(power)//开机 

power_ie=0;//开关间隔开始计时 
RC3=0;//打开脉冲封锁 
RC4=1;//打开继电器 
L3_RED_ON;//打开L3绿灯 
CCP_start();//开始SPWM 

if(!power)//关机 

power_ie=0;//开关间隔开开始计时 
crut_if=0;//电流保护标志清零 
volue_if=0;//电池电压保护标志清零 
L1_OFF;//关灯 
L2_OFF; 
L3_OFF; 
RC3=1;//关闭脉冲封锁 
CCP2CON=0;CCP1CON=0;//复位CCP模块 
RC2=RC1=0;//置端口固定电平 
L3_OFF;//关闭L3绿灯 
RC4=0;//关闭继电器 


//-----输出电流检测 
if(power_up) 

if(ad_res_0>=204)//电流高于4v,快保护 

crut_if=1;crut_tmr=0;crut_ie=0; 
L2_GREE_ON;RC3=1;RC4=0;L3_GREE_ON; 

if((ad_res_0>=102)&&(ad_res_0<204))//高于2v电流慢保护 

L2_GREE_ON; 
if(tmr_s&&tmr_d&&crut_ie)//时基,时基变化标志,保护允许 

tmr_d=0;crut_tmr++; 
if(crut_tmr==10) 

crut_tmr=0;crut_ie=0;crut_if=1;//保护 
L2_GREE_ON;RC3=1;RC4=0;L3_GREE_ON; 



if(ad_res_0<102){crut_tmr=0;L2_OFF;if(crut_if)L2_GREE_ON;}//电流正常低于2v
//-----电池电压检测
if(ad_res_2>=102){L1_OFF;if(volue_if)L1_GREE_ON;} 
//电池电压大于2v,L1红灯灭 
if((ad_res_2<102)&&(ad_res_2>=91)){L1_GREE_ON;}//电池低于2v大于1.8v 
     if(ad_res_2<92){volue_if=1;L1_GREE_ON;RC3=1;RC4=0;L3_GREE_ON;} //电池低于1.8v 

//-----模拟采集 
if(power)ad_1();//在开机状态下检测反馈电压 
ad_2();//采集电池电压 
ad_0();//采集电流 
if(power_ie==0)//开关机时间间隔 

if(tmr_s&&tmr_d){tmr_d=0;power_s++;} 
if(power_s==10){power_s=0;power_ie=1;} 

if(power_up==0)//上电延时1秒检测电池电压 

if(tmr_s&&tmr_d){tmr_d=0;power_up_s++;} 
if(power_up_s==1){power_up_s=0;power_up=1;} 


}
大致看了一下,小弟弟,做得很不错. 
提出几点看法希望对你有帮助: 
              1,PIC系列的端MCU或者DSP对端口操作要严格注意不能连续改变其同类型的数值 
                 如:RC1=RC2=0,RB1=1;RB2=0;等等. 
                 我们想独立改变其电平中间必须加入NOP延时语句,尤其是在FOSC在12MZH以上系统. 
                 原因是什么,不多讲了,DATASHEET上说得很清楚. 
              2,在ad_0()函数中的,没必要经过这么长的for(i=2000;i>0;i--)延时,这跟你的AD口 
                 输入阻抗有关系,说明书上也有计算公式. 
              3,你的SPWM周波信号取32点,太少了,协波信号太大,同时变压器损耗也大取64个或12                   点比较好. 
              4,16MZH,PR2=OXFF,调制频率为15.56KHZ.但是我这里看不到你定时器T2的初始化 
                 设置,也就是说,你是经过多长时间改变CCP脉宽的?这关系到你一个周波有几个脉冲                 波?而且你的死区是如何控制的?这样看来,你可能忘记了某些东西,还没有帖上来                 噢. 
              5,if((ad_res_1<=132)&&(ad_res_1>=130))sin_am+=0; 
                 这样的电压调节算法,太粗糙了.振荡、超调回时实出现.为什么不鉴见一下我以前 
                 帖的PI算法呢? 
              6,看来你采样的是逆变直流信号,假如做高质量的逆变电源,应该采用交流采样,时实 
                 调节PWM,否则系统不稳定. 
              7,而且也没看到你软件上的的短路保护算法哦. 

这是针对你帖出来的软件大致看了一下,提几点看法,希望对你有帮助. 
硬件电路没有看见,尚不做评价.


;************************************************************** 
#include"p12f629.inc"   
;************************************************************** 
FAN      EQU     GP0 
DIVER    EQU     GP1 
LAMP     EQU     GP2 
WORK     EQU     GP3 
POWER    EQU     GP4 
;************************************************************** 
org   0x0; 
   goto start 
        org     0x05 
;************************************************************** 
start   
        bsf     STATUS,RP0 
call 3ffh 
movwf OSCCAL 
bcf     INTCON,GIE 
MOVLW   0X08 
movwf   trisio 
movlw   0x4f 
movwf   OPTION_REG 
        BCF     STATUS,RP0 
movlw   0x07 
movwf   CMCON 
;************************************************************** 
main 
        CLRWDT 
        BSF     GPIO,POWER 
        BcF     GPIO,FAN 
        CALL    DELAY1s 
        BSF     GPIO,LAMP 
        call    delay10s 
        BSF     GPIO,DIVER 

SCAN    CLRWDT 
        BTFSS   GPIO,work 
        GOTO    SCAN1 
        GOTO    SCAN 

SCAN1   MOVLW   0X1f 
        MOVWF   0X21 
SCAN2   CLRWDT 
        BTFSC   GPIO,work 
        GOTO    SCAN 
        CALL    DELAY1S 
        DECFSZ  0X21 
        GOTO    SCAN2 
        BCF     GPIO,DIVER 
         
        movlw   0x03 
        movwf   0x22 
scan3   call    delay1s 
        decfsz  0x22 
        goto    scan3 
        BCF     GPIO,LAMP 
        CALL    DELAY10S 
        BsF     GPIO,FAN 
        BCF     GPIO,POWER 

;**************************************************************         
delay10s 
    movlw   0x0a 
    movwf   0x20 
L1  call    delay1s 
    decfsz  0x20 
    goto    l1 
    retlw   0x0 

delay1s 
    movlw    0x05   
    movwf    0x26 
L2  clrwdt 
    movlw    0ffh 
    movwf    0x27 
L3  movlw    0ffh 
    movwf    0x28 
L4  decfsz   0x28 
    b        L4 
    decfsz   0x27 
    b        L3 
    decfsz   0x26 
    b        L2 

    retlw    0x0 
;**************************************************************         
END

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多