1流程图清中断标志位清定时器1读取A/D转换值计算输出电压偏差表指针到最大返回表头表指针加1正半波?正负半波信号置0查正弦表计算PWM占空比更新PWM占空比中断返回正负半波信号置1图1CCP1中断服务子程序算法实现程序//------------------------------------------------------------//SPWM信号调制//------------------------------------------------------------#includepic16f7x.h#includepic.h//系统配置__CONFIG(HS&PWRTEN&BOREN&PROTECT&WDTEN);//打开看门狗,选择高速晶振,上电延时复位,掉电复位使能,代码保护//-------------------------------------------------2//-----------AD1通道转换--------------------voidad_0(){AN0;//选择通道0DELAY();//延时,采样电容充电ADGO=1;//开启ADwhile(ADGO);//等待AD结束ad_res_0=ADRES;//结果转存到变量AD_RES_0}//-----------AD1通道转换--------------------voidad_1(){AN1;DELAY();ADGO=1;while(ADGO);ad_res_1=ADRES;if(ad_res_1132){sin_am-=0.005;if((ad_res_1-132)10)sin_am-=0.04;}elseif((ad_res_1=132)&&(ad_res_1=130))sin_am+=0;elseif(ad_res_1130){sin_am+=0.005;if((130-ad_res_1)10)sin_am+=0.04;}if(sin_am1.6)sin_am=1.6;}//------------AD2通道转换-------------------voidad_2(){AN2;DELAY();ADGO=1;while(ADGO);ad_res_2=ADRES;3}constunsignedcharsin_[]={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//负半周};unsignedcharsin_num;//sin函数表查表变量//-------------------------------------------------voidCCP_start(){CCPR2L=0X0;//设置CCP2,0%的脉宽输出CCPR1L=0X0;//设置CCP1,0%的脉宽输出TRISC=0X00;//PORTCareoutputsPR2=0Xff;//设置PWM的工作周期,16MHz,PWM周期15.562kHzCCP1M3=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;//电流慢保护允许}//-------------中断服务程序---------------------voidinterruptkey_ccp_timer()//定时器1中断服务函数{if(TMR2IF&TMR2IE){TMR2IF=0;//定时器2中断服务函数if(sin_num==31){sin_num=0;sin_up=!sin_up;}sin_d=sin_[sin_num];4sin_l=sin_am*sin_d;if(sin_l=255)sin_l=255;//限幅if(sin_up){CCPR2L=(unsignedchar)sin_l;CCPR1L=0;}//换向else{CCPR1L=(unsignedchar)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;}}}//--------------------------------------------------//主程序main(){CLRWDT();//清除看门狗port_init();//端口初始化init_start();//开机状态adc_init();//ad通道初始化//---------------------------------------------------RC4=0;//继电器关闭RC3=1;//关闭脉冲封锁//---------------------------------------------------TMR1CS=0;//同步模式5T1SYNC=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;//打开定时器2TOUTPS3=0;TOUTPS2=1;TOUTPS1=0;TOUTPS0=0;//定时器2后分频器5分频TMR1ON=1;//打开定时器1power_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;//打开继电器CCP_start();//开始SPWM}6if(!power)//关机{power_ie=0;//开关间隔开开始计时crut_if=0;//电流保护标志清零volue_if=0;//电池电压保护标志清零RC3=1;//关闭脉冲封锁CCP2CON=0;CCP1CON=0;//复位CCP模块RC2=RC1=0;//置端口固定电平RC4=0;//关闭继电器}}//------输出电流检测------if(power_up){if(ad_res_0=204)//电流高于4v,快保护{crut_if=1;crut_tmr=0;crut_ie=0;}if((ad_res_0=102)&&(ad_res_0204))//高于2v电流慢保护{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;//保护}}7}if(ad_res_0102)//电流正常低于2v{crut_tmr=0;L2_OFF;if(crut_if);}//------电池电压检测------if(ad_res_2=102){L1_OFF;if(volue_if);}//电池电压大于2v,if((ad_res_2102)&&(ad_res_2=91))//电池低于2v大于1.8vif(ad_res_292)//电池低于1.8v{volue_if=1;}}//-----模拟采集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;}}}}