|
本帖最后由 tbklgt 于 2009-10-3 15:12 编辑
//------------------------------------------------------------
// spwm信号调制
//------------------------------------------------------------
#include <pic16f7x.h>
#include<pic.h>
//系统配置
__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;}
}
}
} |
|