//------------------------------------------------------------ // 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 |
|
|
|