www.pudn.com > DCL.rar > DCL.c
/* PIC16F73
----------------
-|1 RB7 28|- (加热)
IGBT Temperature -|2 RA0 RB6 27|- (弱加热)
Voltage -|3 RA1 RB5 26|- (保温)
REAL Temperature -|4 RA2 RB4 25|- (关机)
Current -|5 RA3 RB3 24|- Beep
-|6 RA4 RB2 23|-
-|7 RA5 RB1 22|- Test Plus
-|8 RB0 21|- (中断)
-|9 20|-
-|10 19|-
-|11 RC0 RC7 18|-
PWM Output -|12 RC1 RC6 17|-
Capture/Fan -|13 RC2 RC5 16|-
-|14 RC3 RC4 15|-
----------------
*/
//包括的头文件
#include
#include
//定义
#define uchar unsigned char
#define uint unsigned int
#define bPLUS RB1 //发试探脉冲的管脚
#define bBEEP RB3
#define bSDATA RC7 //SER
#define bSDCLK RC5 //SRCLK
#define bSCLK RC6 //RCLK
#define Turnoff_PWM_Output() {CCP2CON &= 0x0F0; T2CON &= 0x0FB;} //停止PWM的输出
#define Low_PWM_Output() { RC1 = 0; bPLUS = 0;} //并把PWM管脚拉低
#define High_Test_Output() {bPLUS = 1;} //把测试脉冲管脚电平拉高
#define Open_Fan() { RC4 = 1;} //打开风扇
#define Turnoff_Fan() { RC4 = 0;} //关闭风扇
#define DEFus 252
#define DEF20us 225
#define DEF10ms 61
#define PLUSCOUNT 3
#define TRUE 1
#define FALSE 0
#define MAXPLUSNUM 12
#define MINIREAD 15
#define IPOINTS 5
#define TMR1LOW 0X78
#define TMR1HIGH 0X0ec
#define T3RESTTIME 3 //300W时,工作3秒,休息5秒
#define T3WORKTIME 2
#define T6WORKTIME 4 //600W时,工作6秒,休息2秒
#define T6RESTTIME 1
#define gate_Voltage 0X88 //电压AD转化通道选择
#define gate_Current 0X98 //电流AD转化通道选择
#define gate_Pan_Warm 0X90 //锅底温度AD转化通道选择
#define gate_IGBT_Warm 0X80 //IGBT温度AD转化通道选择
#define gate_Key 0X0a0 //按键AD转化通道选择
#define switchTURNOFF 0x10
#define switchKEEPWARM 0x20
#define switchWEAKWARM 0x40
#define switchCOOKING 0x80
#define switchSHIELD 0x0F0
#define PWM_period 0x0a0 //PWM的周期
void Send_Test_Plus(void); //发脉冲宽度为6us的试探脉冲
void Send_IGBT_Plus(unsigned int PWM_hi); //发IGBT的驱动脉冲,是PWM的正脉冲宽度
void Check_Machine_Wave(void); //发出试探脉冲后,检测机器返回的振荡波
void interrupt INT_Service_Prog(void); //中断服务程序
void PIC_Timer(uchar uKind,uchar uNum); //定时程序
void Mcu_init(void); //单片机初始话程序
void Power_control(uchar iPower); //功率档位控制,间隙工作,连续工作
void DISPLAY1(uchar shu1, uchar shu2); //显示子程序
void Display(void); //显示档位,错误代码
void Judge_Switch_State(void); //中断后,对开关状态进行判断
void Read_Switch_State(void); //读开关状态,如与档位不一样,立即中断
void Power_adjust(void); //功率控制,与工作档位有关,连续工作,间隙工作
void work_condition_check(void); //对工作条件进行检测,主要是电压,温度传感器
void Voltage_check(void); //在电磁炉工作的情况下,测试电压,查表得出电流,以横功率
uchar ad_out(uchar uchannel); //AD转化子程序,参数是各AD通道的选择
//定义标志位
bit gTimerOver; //定时器Tmr0定时是否结束,1:Yes,0:No
bit gWorkNow; //间隙工作模式下,是否在工作,1:Yes,0:No
bit bDCLoff; //电磁炉关机标志,用于关机后1MIN延时,然后等待
bit bDCLon; //用在打开加热档的一个标志
bit bSwitch; //用在读开关状态的标志,发现开关状态与工作档位不一样,置标志,延时5MS,在读一次
bit bKeyChange; //多个循环标志,若开关状态改变,产生中断,置标志,这样,主程序中的某些循环条件就不满足了
bit bNopan; //无锅标志,在发试探脉冲后,检测到无锅
bit bLVoltage; //检测到电压太低标志
bit bHVoltage0; //检测到电压太高标志0
bit bHVoltage1; //检测到电压太高标志1
bit bHpan_tem; //检测到锅底温度太高的标志
bit bHigbt_tem; //检测到IGBT温度太高的标志
bit bL_Current; //检测到电流太小的标志,是无锅状态
bit bH_Current; //检测到电流太大的标志,是电路故障
bit bProtect0; //用在条件的子程序中,如果在条件检测时,发生有错误,置标志
bit bProtect1; //在检测电流过程中,电流过大或过小,置标志
bit bErro; //只要有一个错误发生,就关机,去不断检测条件
uchar gDoCircle; //是否持续工作
uchar gTimerDur; //定义20us延时,还是10ms延时
uchar gTimerNum; //定义延时的时间因子
uchar gPlusNum; //定义在取试探脉冲时,多少个就可以满足要求
uchar gPlusNo; //用于数组的下标
uchar gRevPlus; //表示发出试探脉冲后,机器返回的脉冲个数
uchar gOldSwitch; //开关原来的状态
uchar gNowSwitch; //开关现在的状态
uchar iPower; //功率档的标志,1关机,8加热,4弱加热,2保温
uchar uWorkTime; //间隙工作时,工作的时间
uchar uRestTime; //间隙工作时,休息的时间
uchar bCirCndit; //在条件检测过程中,每次只检测哪一个的标志
uchar x,a; //横功率控制,查表用的下标
uchar d01ms,d10ms,d100ms,d01s,d60s,d01h; //中断的时间单元
uchar t1s,w,t750ms,t10ms,t1ms,t120ms,t2s,t3s,t01s; //程序控制中需用的时间
uint PWM_hi; //PWM的占空比
uint gCPLZ[PLUSCOUNT]; //此数组用于记录捕获到的信号的时间量
union tUNION //定义了一个联合体
{
uint iX;
uchar uY[2];
}gCAPU;
//调试中,显示用
//0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f
const unsigned char table[20]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0X07,0x7F,
0x6F,0x77,0x7C,0x58,0x5E,0x79,0x71,0x7f,0xbf,0x89,0xff};
const unsigned char current_table[22]={0x52,0x4F,0x4B,0x49,0x46,0x44,0x41,0x3F,
0x3D,0x3A,0x38,0x3F,0x3D,0x3A,0x38,0x36,0x34,0x32,0x30,
0x2E,0x2C,0x2A};
//程序开始了...
void main(void)
{
uchar uAD;
uint iRecordVoltage,u,u1,uHi1,ss1;
uchar uNum;
uchar uAD2,uAD0,uADy;
uchar j,p,t,i;
uint uUad ;
Mcu_init();
bBEEP=1; //蜂鸣器长叫一声。时间2秒
t3s = 0;
while(t3s<2);
bBEEP=0;
INTF = 1; // 强行中断,读开关状态,与00比较
gOldSwitch = 0x00; //开关的初始状态为0
while(1)
{
if(bKeyChange == 1) //开关状态改变
{
bKeyChange = 0 ;
Turnoff_PWM_Output(); //关闭PWM的输出
Low_PWM_Output(); //PWM管脚拉低
for(j=256;j>0;j--); //延时一会
Judge_Switch_State(); //判开关的状态
gWorkNow=0; //确保在切换开关后,能马上工作起来
t1s=20; //间隙工作时,马上工作的条件
}
if(RB2==0) //显示
{ Display(); }
if(bDCLoff == 1) //关机动作,风扇再工作一分钟
{
Turnoff_PWM_Output(); //关闭PWM的输出
Low_PWM_Output(); //PWM管脚拉低
t2s=0; //延时一分钟
while((bKeyChange == 0)&&(t2s<90))
{ Read_Switch_State(); } //要不断的去读开关状态
Turnoff_Fan(); //关闭风扇
while(bKeyChange == 0) //已关机,风扇已工作了,等待开机
{
Read_Switch_State(); //要不断的去读开关状态
if(RB2==1) //显示
{ Display(); }
}
}
if(iPower==1)
{ Turnoff_Fan(); } //关闭风扇
else
{ Open_Fan(); } //打开风扇
while(bKeyChange == 0) //功率控制
{
if(RB2==0)
{ Display(); }
Read_Switch_State(); //读开关状态
work_condition_check(); //条件检测
if((bProtect0==1)||(bProtect1==1)||(bNopan==1)) //发生错误,置标志,推出循环
{ bErro=1; break; }
else
bErro=0;
Power_control(iPower); //工作状态控制
if((iPower==8)||(gWorkNow == 1)) //横功率控制
{
if(t01s>9) //工作后,延时等待在检测
{ t01s=10;
Voltage_check(); //检测电压
Power_adjust(); //检测电流,查表调整PWM
}
}
}
if(bErro==1) //发生错误,进行处理
{
Turnoff_PWM_Output(); //关闭PWM的输出
Low_PWM_Output(); //PWM输出低电平
while(1)
{
if(RB2==0) //显示
{ Display(); }
bBEEP =1; //蜂鸣器报警
bProtect1=0;
Read_Switch_State(); //读开关状态
if(bKeyChange == 1) //开关状态改变,退出
{ bErro =0;
bBEEP =0;
break;
}
if(bH_Current==1) //对电流太大进行处理
{ bH_Current=0;
t2s=0;
while(t2s<2); //延时2秒,退出处理程序,再去检查
bBEEP =0; //关蜂鸣器,取消错误标志
bErro =0;
gWorkNow=0; //确保在工作条件满足后,能马上工作起来
t1s=20;
bDCLon=0;
PWM_hi=0x0c0;
break;
}
if((bL_Current==1)||(bNopan==1)) //对无锅进行处理
{ t2s=0;
while(t2s<1);
Check_Machine_Wave(); //发试探脉冲,检测返回个数
if(gRevPlus >= MAXPLUSNUM) //如果测试到的脉冲数大于预先设定的脉冲数
bNopan=1; //则认为无锅
else
bNopan=0;
}
if(bProtect0==1) //对温度传感器或电压错误进行处理
{ work_condition_check(); }
if((bProtect0==0)&&(bNopan==0)) //条件正常,退出
{ bErro =0;
bBEEP =0;
gWorkNow=0; //确保在工作条件满足后,能马上工作起来
t1s=20;
bDCLon=0;
PWM_hi=0x0c0;
break;
}
}
}
}
}
//开关状态改变
void Judge_Switch_State(void)
{
gOldSwitch = gNowSwitch; //承认开关状态改变,更新开关状态
bSwitch = 0 ; //清在读开关状态过程中,发现开关状态与档位不一样时,置的标志
if((gNowSwitch & switchTURNOFF) == switchTURNOFF) //是关机状态
iPower = 1 ; //定义开关状态单元
else if((gNowSwitch & switchCOOKING) == switchCOOKING) //是保温状态
{ iPower = 2 ; //定义开关状态单元
uWorkTime = T3WORKTIME; //给工作,休息时间赋初值
uRestTime = T3RESTTIME;
}
else if((gNowSwitch & switchWEAKWARM) == switchWEAKWARM) //是弱加热状态
{ iPower = 4 ; //定义开关状态单元
uWorkTime = T6WORKTIME; //给工作,休息时间赋初值
uRestTime = T6RESTTIME;
}
else if ((gNowSwitch & switchKEEPWARM) == switchKEEPWARM) //是加热状态
{ iPower = 8;
bDCLon = 0; //定义开关状态单元,置开始加热标志
}
else
{ asm("nop"); } //出错
PWM_hi=0x0c0;
if(iPower ==1) //若是关机,置关机标志
bDCLoff = 1;
else
bDCLoff = 0;
}
//主要用于判断工作条件是否满足
//X用于恒功率查表,判断电流用
void work_condition_check(void)
{ uchar u,pan_temp,igbt_temp;
uchar U_max,U_min,Cpan_max,Cigbt_max;
if(bErro==1) //此处为保护的一些参数设定
{ U_min=0x93; U_max=0x0ba; //出错后的参数
Cpan_max=0x40; Cigbt_max=0x6a;
}
else
{ U_min=0x8d; U_max=0x0c1; //出错前的参数
Cpan_max=0x60; Cigbt_max=0x82;
}
if(bCirCndit==0)
{ bCirCndit = 1;
u = ad_out(gate_Voltage);
if(uU_max)
bHVoltage0=1; //电压过高保护
else
bHVoltage0=0;
}
else if(bCirCndit==1)
{ bCirCndit = 2;
pan_temp = ad_out(gate_Pan_Warm);
if((pan_temp > Cpan_max)||(pan_temp==0))
bHpan_tem=1; //锅低温度过高保护
else
bHpan_tem=0;
if(pan_temp<0x09)
a=0;
else if(pan_temp<0x2b)
a=1;
else if(pan_temp<0x3a)
a=2;
else if(pan_temp<0x50)
a=3;
else
a=4;
}
else if(bCirCndit==2)
{ bCirCndit=3 ;
igbt_temp = ad_out(gate_IGBT_Warm);
if(igbt_temp>Cigbt_max)
bHigbt_tem=1; //IGBT温度过高保护
else
bHigbt_tem=0;
}
else if(bCirCndit==3)
{ bCirCndit=0;
if(RC3==0)
bHVoltage1=1;
else
bHVoltage1=0;
}
else
{ bCirCndit = 0; }
if((bLVoltage==1)||(bHVoltage0==1)||(bHpan_tem==1)||(bHigbt_tem==1)||(bHVoltage1==1))
bProtect0=1; //只要发生一个错误,就置错误标志
else
bProtect0=0;
}
void Voltage_check(void)
{ uchar u;
u = ad_out(gate_Voltage);
if (u<0x98) x=1; //主要为功率控制查表用
else if (u< 0x9c) x=2;
else if (u<0x0a0) x=3;
else if (u<0x0a4) x=4;
else if (u<0x0a8) x=5;
else if (u<0x0ac) x=6;
else if (u<0x0b0) x=7;
else if (u<0x0b4) x=8;
else if (u<0x0b8) x=9;
else x=10;
}
//功率调整
//主要通过电流AD转换和已设定的值进行比较的
void Power_adjust(void)
{ uchar i,y,z,Current_AD0,Current_AD1;
uint uHi1,ss1;
i = ad_out(gate_Current);
if(i<0x08) //电流过低,属于无锅,需保护
bL_Current=1 ;
else
bL_Current=0;
if(i>0x8f) //电流过高,需保护
bH_Current=1 ;
else
bH_Current=0;
if ((bL_Current==1)||(bH_Current==1))
bProtect1=1; //电流过大或过小,都需保护,置标志
else
bProtect1=0;
if(iPower==8) //给查电流表赋偏移量
y=0;
else
y=11;
z=x-a; //计算下标
if(z<1 ) z=1;
if(z>10) z=10;
z=y+z;
Current_AD0 = current_table[z-1]; //电流AD转化的下限值
Current_AD1 = current_table[z]; //电流AD转化的上限值
if(i> 2);
ss1=uHi1 & 0x0003;
CCP2CON |= ((ss1 <<4) & 0x0030); //CCP2CON<5:4>=0;
}
else if(i > Current_AD1) //电流太大
{ PWM_hi--; //减小占空比
uHi1 = PWM_hi; //修改PWM的占空比
ss1=uHi1 & 0x03fc;
CCPR2L = (ss1 >> 2);
ss1=uHi1 & 0x0003;
CCP2CON |= ((ss1 <<4) & 0x0030); //CCP2CON<5:4>=0;
}
else
{ asm("nop"); }
}
//读开关状态,确保工作状态
void Read_Switch_State(void)
{ uchar uSwOne,uSwTwo;
uSwTwo = iPower<<4 ;
if(bSwitch == 0)
{ uSwOne = PORTB & switchSHIELD; //读开关的值
if( uSwOne != uSwTwo) //判断是否与原来的值相等
{ t10ms = 0 ;
bSwitch = 1 ;
}
}
else
{ if( t10ms>1 )
{ uSwOne = PORTB & switchSHIELD; //读开关的值
if(uSwOne != uSwTwo) //前后两次的值是否相等
{ INTF = 1; } //触发中断
}
}
}
//功率控制
//主要是连续工作,间隙工作,错误状态要关机
void Power_control(uchar iPower)
{ uint Pwm_h;
if(iPower ==1)
{
if (bDCLoff==0)
{
Turnoff_PWM_Output(); //关闭PWM的输出
Low_PWM_Output(); //PWM输出低电平
bDCLoff = 1;
}
else
{ asm("nop"); }
}
else if(iPower ==8)
{
if (bDCLon==0)
{
Check_Machine_Wave();
if(gRevPlus >= MAXPLUSNUM) //如果测试到的脉冲数大于预先设定的脉冲数
bNopan=1; //则认为无锅
else
{ Pwm_h = PWM_hi;
Send_IGBT_Plus(Pwm_h);
t120ms=0; //延时一段时间100ms
while(t120ms<11);
High_Test_Output();
bDCLon = 1;
bNopan = 0;
t01s=0; //用于电流检测
}
}
else
{ asm("nop"); }
}
else if((iPower ==2)||(iPower ==4))
{
if(gWorkNow == 1)
{ //目前正在工作
if( t1s > uWorkTime )
{ //工作的定时时间到了
gWorkNow = 0; //开始休息啦
t1s = 0 ;
Turnoff_PWM_Output(); //关闭PWM的输出
Low_PWM_Output(); //PWM输出低电平
}
else
{ asm("nop"); }
}
else //目前正在休息
{
if( t1s > uRestTime )
{ //休息的定时时间到了
gWorkNow = 1; //开始工作了
t1s = 0;
Check_Machine_Wave();
if(gRevPlus >= MAXPLUSNUM) //如果测试到的脉冲数大于预先设定的脉冲数
bNopan=1; //则认为无锅
else
{ Pwm_h = PWM_hi;
Send_IGBT_Plus(Pwm_h);
t120ms=0; //延时一段时间10ms
while(t120ms<11);
High_Test_Output();
bNopan = 0;
t01s=0; //用于电流检测
}
}
else
{
asm("nop"); //继续休息
}
}
}
else
{
Turnoff_PWM_Output(); //关闭PWM的输出
Low_PWM_Output(); //PWM输出低电平
}
}
void Display(void)
{ uchar uADy0,uAD1;
if( bErro == 0)
{ if(iPower==1) //显示功率档位用
uAD1=0;
else if(iPower==8) //加热档
uAD1=1;
else if(iPower==4) //弱加热档
uAD1=2;
else if(iPower==2) //保温档
uAD1=3;
else
uAD1=4; //档位错误,或没接开关
}
else
{ if(bHVoltage0==1) //电压太高
uAD1=0x0c;
else if(bLVoltage==1) //电压太低
uAD1=0x0b;
else if((bL_Current==1)||(bNopan==1)) //无锅
uAD1=0x0a;
else if(bHigbt_tem==1) //IGBT温度太高
uAD1=9;
else if(bHpan_tem==1) //锅底温度太高
uAD1=8;
else if(bHVoltage1==1) //电压太高
uAD1=7;
else if(bH_Current==1) //电流太大,电路有问题
uAD1=6;
else
uAD1=5; //控制出现异常情况
}
DISPLAY1(uADy0,uAD1);
}
//当MCU发出试探脉冲后,检查返回的脉冲个数及频率
//TMR1是Capture和定时复合用的
//在使用Capture之前,现保存TMR1的设置值
void Check_Machine_Wave(void)
{
uchar uTMRL;
uchar uTMRH;
uchar uCON;
//保存TMR1的设置值
uCON = T1CON;
TMR1ON = 0;
TMR1IF = 0;
TMR1IE = 0;
uTMRL = TMR1L;
uTMRH = TMR1H;
RC2 = 0;
asm("nop");
//CCP1,RC2
//设置RC2为输入管脚
TRISC |= 0x04; //"00000100"
//延时25ms
PIC_Timer(3,2);
while(gTimerOver != 1);
gPlusNum = PLUSCOUNT; //需要采取的上升沿个数
gPlusNo = 0x00; //清零
gRevPlus = 0x00; //收到的脉冲数清零
CCP1CON = 0x00;
T1CON = 0x00; //1:1
TMR1L = 0;
TMR1H = 0;
//设置CCP1CON
CCP1IF = 0;
CCP1IE = 1;
CCP1CON = 0x05;
TMR1ON = 1;
//发试探脉冲
Send_Test_Plus();
//定时160us
PIC_Timer(2,8);
//当收到的脉冲数等于MAXPLUSNUM时,同时或者定时时间到,退出循环
while((gTimerOver == 0) && (gRevPlus < MAXPLUSNUM));
//不是定时时间到而退出循环的,关闭定时器
if(gTimerOver == 0)
{
T0IE = 0;
}
//关闭捕捉功能
CCP1CON = 0x00;
CCP1IE = 0;
TMR1ON = 0;
//恢复TMR1的值设置
TMR1IF = 0;
TMR1IE = 1;
TMR1L = uTMRL;
TMR1H = uTMRH;
T1CON = uCON;
TRISC &= 0x0fb; //11111011
asm("nop");
RC2=1;
}
#pragma interrupt_level 1
void interrupt INT_Service_Prog(void)
{
uint uDelay;
uchar uSwOne;
uchar uSwTwo;
if(T0IF == 1) //是tmr0中断
{
T0IF = 0; //清楚中断标志
--gTimerNum; //定时个数减一
if(gTimerNum == 0) //延时时间是否到,
{
gTimerOver = 1; //是,置标志位
T0IE = 0; //关闭定时器中断
}
else
TMR0 = gTimerDur; //否,继续置定时器时间常数
}
if(CCP1IF == 1) //是capture中断
{
CCP1IF = 0; //清除中断标志
if(gPlusNum != 0) //需要capture的次数是否到了
{ //没有,记录相关的数据
gCAPU.uY[0] = CCPR1L; //CCPR1L;
gCAPU.uY[1] = CCPR1H; //CCPR1H;
gCPLZ[gPlusNo] = gCAPU.iX;
gPlusNo++;
gPlusNum--;
}
gRevPlus++; //收到的脉冲数加1
PIC_Timer(2,8); //定时器重新开始定时160us
}
else if(TMR1IF == 1) //是tmr1中断
{
TMR1IF = 0;
TMR1L = TMR1LOW;
TMR1H = TMR1HIGH;
d01ms++;
t1ms++;
if (d01ms>=10)
{ d01ms=0; d10ms++;
t750ms++; t10ms++;
t120ms++;
if(d10ms>=10)
{ d10ms=0 ; d100ms++;
t01s++;
if (d100ms>=10)
{ d100ms=0;d01s++;
t1s++; t2s++; t3s++;
if (d01s>=60)
{ d01s=0; d60s++;
if( d60s>=60)
{ d60s=0; d01h++;
}
}
}
}
}
}
else if(INTF == 1) //开关状态发生改变
{
INTF = 0; //清除中断标志
uSwOne = PORTB & switchSHIELD; //读开关的值
if( uSwOne != gOldSwitch) //判断是否与原来的值相等
{
for(uDelay=0;uDelay<300;uDelay++); //不相等,等待一段时间后,重新读取
uSwTwo = PORTB & switchSHIELD;
if(uSwOne == uSwTwo) //前后两次的值是否相等
{
gNowSwitch = uSwOne; //如相等,则认为开关状态已经发生变化
gDoCircle = FALSE; //设定重新循环的标志
bKeyChange = TRUE ; //*加热状态改变
}
}
}
}
//uKind = 1,以8us为基准
//uKind = 2,以20us为基准
//否则以10ms为基准
#pragma interrupt_level 1
void PIC_Timer(uchar uKind,uchar uNum)
{
T0IF = 0;
T0IE = 1;
//如定时60us,3×20us,为3次
gTimerNum = uNum;
//定时时间到,开始为"0",结束为"1"
gTimerOver = 0;
//不是发试探脉冲定时
// gIsPlus = FALSE;
if(uKind == 1)
{
OPTION &= 0x0F8;
gTimerDur = DEFus;
}
else if(uKind == 2)
{
OPTION &= 0x0F8;
gTimerDur = DEF20us;
}
else
{
OPTION |= 0x07;
gTimerDur = DEF10ms;
}
//TMR0的初始值
TMR0 = gTimerDur;
}
//此函数发试探脉冲
//试探脉冲的宽度是6us
void Send_Test_Plus(void)
{ uchar i;
bPLUS = 0;
for(i=6;i>0;i--);
bPLUS = 1;
for(i=2;i>0;i--);
bPLUS = 0;
for(i=6;i>0;i--);
}
void Send_IGBT_Plus(unsigned int PWM_hi)
{
unsigned int uHi,ss;
PR2 = PWM_period;
uHi = PWM_hi;
ss=uHi & 0x03fc;
CCPR2L = (ss >> 2);
ss=uHi & 0x0003;
CCP2CON |= ((ss <<4) & 0x0030); //CCP2CON<5:4>=0;
T2CON = 0x01; // 1/4 frequency
CCP2CON |= 0x0C; //PWM mode
T2CON |= 0x04; //打开TMR2
}
uchar ad_out(uchar uchannel)
{ int iT;
ADCON0=uchannel;
ADCON0 |=0X01;
for(iT=0; iT<60; iT++) ;
ADCON0 |= 0X04;
asm("NOP");
asm("NOP");
while((ADCON0&0X04)==0X04) ;
asm("NOP");
asm("NOP");
ADCON0 &=0X0FE;
return(ADRES);
}
void DISPLAY1(uchar shu1, uchar shu2)
{ char ucdata,ucI,ucshi,ucge;
ucshi=shu2;
ucge =shu2;
bSDATA = 0;
bSDCLK = 0;
bSCLK = 0;
ucdata=table[ucge];
for(ucI=0;ucI<8;ucI++)
{ if (ucdata & 0x80)
bSDATA=1;
else
bSDATA=0;
asm("NOP");
asm("NOP");
bSDCLK=1;
asm("NOP");
asm("NOP");
bSDCLK=0;
ucdata &= 0x07f;
ucdata <<= 1;
}
ucdata=table[ucshi];
for(ucI=0;ucI<8;ucI++)
{ if (ucdata & 0x80)
bSDATA=1;
else
bSDATA=0;
asm("NOP");
asm("NOP");
bSDCLK=1;
asm("NOP");
asm("NOP");
bSDCLK=0;
ucdata &= 0x7f;
ucdata <<=1;
}
bSCLK=0;
asm("NOP");
asm("NOP");
bSCLK=1;
}
void Mcu_init(void)
{ ADCON1 = 0x00; //Vref+=VDD,Vref-=VSS,所有的都是A/D口
//87X,10位精度;7X,8位精度
//RA0:IGBT temperature:pin-2
//RA1:Voltage :pin-3
//RA2:Coil temperature:pin-4
//RA3:Current :pin-5
TRISA = 0x0DF; //A口全部为输入,用作A/D
TRISC = 0X08;
TRISB = 0x0F5; //RB0,RB4,RB5,RB6,RB7 input,others output
Low_PWM_Output(); //IGBT的驱动脉冲,不工作时为低电平
//测试脉冲为低电平,以防止意外
T1CON=0X00;
PIR1=0X00;
INTCON=0X00;
TMR1L = TMR1LOW;
TMR1H = TMR1HIGH;
TMR1IE=1;
INTCON = 0x00;
OPTION = 0x0C0; //RB0/INT上升沿触发, 并禁止弱上拉
INTE = 1; //允许外部中断(开关)
PEIE = 1; //允许其他外设中断
GIE = 1; //允许全局中断
TMR1ON=1;
}