直流无刷电机控制PIC程序全部整合.docx
《直流无刷电机控制PIC程序全部整合.docx》由会员分享,可在线阅读,更多相关《直流无刷电机控制PIC程序全部整合.docx(21页珍藏版)》请在冰点文库上搜索。
直流无刷电机控制PIC程序全部整合
//2008.4.24--14点00分
#include
#include
#include
intcharge_delay,jm,lkk,trial,run_num,protect_num;
charm,n,k,s,L,tri;
charhall_num;//循环次数
charhall_number;//1+3+2+10+8+9=33(一个循环和),hallless_protect()
intpwm_hi;intpwm_cycle;
intpwm_lo;
intpwm_real;
intad_result;
bitghy,run_flag;
bitflag_autohand;//voiddelay(delay_num)
intdelay_num;
intj;
for(j=delay_num;j>1;j--)
//pwm占空比上限
//pwm周期
//pwm占空比下限,由A/D结果确定
//pwm
//A/D转
占空比实际
换结果
//运行标志---0,未运行,停止开始为自动
asm("nop");
unionadres
inty1;
unsignedcharadre[2];}adresult;
voidpara_chushihua()
protect_num=0;trial=0b10110000;tri=0x00;
lkk=10;hall_num=0x00;hall_number=0x00;run_flag=0;flag_autohand=1;pwm_cycle=240;
//pwm_hi=pwm_cycle-5;
pwm_hi=pwm_cycle-1;
//运行标志---0,未运行,停止
//开始为自动
//pwm周期
//pwm占空比上限
//pwm占空比上限
pwm_real=pwm_cycle;
限
pwm_lo=0x0A;
//实际pwm占空比为pwm周期上
//设定下限
voidnointerupt_chushihua()
voidIo_chushihua()
//ADCON1=0x8e;
齐1
ADCON1=0x86;
TRISA=0x09;
保护)--输出,0--不保护,1--保护;
//RA1PSW1
//RA2
//RA3
//RA4
//RA0/AN0--VOLTAGE电压采样,右对
//设定RA0--RA6设定为I/O口;//RA0---PROTECT保护(电流保护和过温
,继电器,输出,0,电源接通
0--->>
1
0--->>
指示灯,输出按键,加,输入指示灯,输出
//RA5RSW1,继电器,输出0,软启充电
PORTA=PORTA&0x09;//RA1=0,输出低电平,PSW1,继
电器断
//RA2=0,
//RA4=0,
//RA5=0,
输出低电平,指示灯灭
输出低电平,指示灯灭输出低电平,RSW1,继电器
示灯灭
//RB端口内部弱上拉电路禁止
//RB7=1,空输入
//RB6=1HA,输入
//RB5=1HB,输入
//RB4=1HC,输入
//RB3=1
//RB2=1
//RB1=1
//RB0=0ST/STOP
PORTB=PORTB&0xfe;//RB0=0,
出
RBPU=0;
TRISB=0xfe;
输入停,输入,按钮启,输入,按钮自/手选择,输入,,输出,输出低电平,
开关
控制GAL禁止GAL输
TRISC=0x02;
输出
//RC7---A1+,PWMA1+,
//RC6---A1,输出//RC5---B1+,输出//RC4---B1,输出//RC3---C1+,输出
//RC2---CCP1(PWM),输出,死区//RC1减,输入,按钮
//RC0---C1,输出
0
0
0
0
0
0
1
0
PORTC=0x06;}
voidprotect()
GIE=0;pwm_real=pwm_hi;CCPR1L=pwm_real;CCPR1H=0x00;CCP1CON=0x0c;PR2=pwm_cycle;
TRISC=TRISC&0xfb;
//过流和过温保护
//关全局中断
//PWM_realPWM
//设置PWM输出为最大
//
//CCP1选择为PWM工作方式
//设置PWM的周期
//设置RC2---PWM输出
实时值
//分频系数=OxOO
//启用TMR2
//
//RBO=O,输出低电平,禁
//延时
T2CON=OxOO;
TMR2ON=1;
PORTC=OxOO;
PORTB=PORTB&Oxfe;
止GAL输出
while
(1)
PORTA八=ObOOO1O1OO;
delay(15000);
voidprotect_run()
GIE=O;pwm_real=pwm_hi;CCPR1L=pwm_real;
CCPR1H=OxOO;
CCP1CON=OxOc;
PR2=pwm_cycle;
TRISC=TRISC&Oxfb;
T2CON=OxOO;
TMR2ON=1;
PORTC=OxOO;
PORTB=PORTB&Oxfe;
止GAL输出
while
(1)
//过流和过温保护
//关全局中断
//PWM_realPWM实时值
//设置PWM输出为最大
//
//CCP1选择为PWM工作方式
//设置PWM的周期
//设置RC2---PWM输出
//分频系数=OxOO
//启用TMR2
//
//RBO=O,输出低电平,禁
//RA4闪动
//RA2闪动
delay(15000);
//延时
//PORTA八=ObOOO1OOOO;
PORTA八=ObOOOOO1OO;
voidPWM_chushihua()
//
//
CCPR1L=0xa0;
CCPR1H=0x00;run_num=0;pwm_real=pwm_hi;CCPR1L=pwm_real;CCPR1H=0x00;CCP1CON=0x0c;PR2=pwm_cycle;TRISC=TRISC&0xfb;T2CON=0x00;TMR2ON=1;
//PWM_realPWM实时值
//设置PWM输出为最大
//
//CCP1选择为PWM工作方式
//设置PWM的周期
//设置RC2---PWM输出
//分频系数=OxOO
//启用TMR2
voidopen_loopf()
//开环运行50次,启动
k=0b00011000;
s=PORTC&0b00000110;
//HA,HB,HC,
//1O1,B-C+
//
//延时
PORTC=k|s;delay(8000);
k=0b10010000;s=PORTC&0b00000110;
PORTC=k|s;
delay(8000);
//4
//HA,HB,HC,
//100,
//
//延时
A+B-
k=0b10000001;s=PORTC&0b00000110;
PORTC=k|s;
delay(8000);
//6
//HA,HB,HC,
//110,//
//延时
C-A+
k=0b00100001;
s=PORTC&0b00000110;
PORTC=k|s;
delay(8000);
//2
//HA,HB,HC,
//010,
//
//延时
B+C-
k=0b01100000;
s=PORTC&0b00000110;
PORTC=k|s;
delay(8000);
//3
//HA,HB,HC,
//011,
//
//延时
A-B+
k=0b01001000;s=PORTC&0b00000110;
PORTC=k|s;
delay(8000);
//1
//HA,HB,HC,//0////延时
01,
C+A-
voidinterruptRB4_int()
charth;run_num++;if(run_num>10){run_num=10;}m=PORTB;
//101,B-C+
//001,C+A-
//RB7-HA,RB5-HB,RB4-HC
m&=0xB0;
m八=0x90;//A二/A,B二B,C二/C
n=m>>4;
//1
//1//
0
1
//
switch(n)
case1:
k=0b01001000;break;
//HA,HB,HC,
//00
1,
C+A-
//
case3:
k=0b01100000;break;
//0
1
1,
A-B+
//
case2:
k=0b00100001;break;
//0
1
0,
B+C-
//
case10:
k=0b10000001;break;
//1
1
0,
C-A+
//
case8:
k=0b10010000;break;
//1
0
0,
A+B-
//
case9:
k=0b00011000;break;
//1
0
1,
B-C+
//其它(000,111),0x00,
1
1
//输出为无效
case1:
k=0b00011000;break;case3:
k=0b01001000;break;
//0
1
1,
A-B+
//0
1
0,
B+C-
//1
1
0,
C-A+
//1
0
0,
A+B-
//其它(000,111),0x00,输
//取RC1,RC2状态//输出PORTC//RB7=0//RB5=0//RB4=0
//每20次测试一次
//tri=n;
//if//RB7=0
//tri=n;
//if//RB5=0
//tri=n;//if//RB4=0
((tri&=0b00001000)==0)
((tri&=0b00000010)==0)
((tri&=0b00000001)==0)
{trial&=0b00110000;}
{trial&=0b10010000;}
{trial&=0b10100000;}
//if(lkk>2){lkk--;}
else
//每20次测试一次
case2:
k=0b01100000;break;case10:
k=0b00100001;break;case8:
k=0b10000001;break;case9:
k=0b10010000;break;default:
k=0b00000000;
出为无效
s=PORTC&0b00000110;
PORTC=k|s;
if(RB7==0){trial&=0b00110000;}if(RB5==0){trial&=0b10010000;}if(RB4==0){trial&=0b10100000;}
if(lkk>1){lkk--;}
while(trial!
=0b00000000)
实时值
GIE=0;
pwm_real=pwm_hi;
//关全局中断
//PWM_realPWM
作方式
平,禁止
CCPR1L=pwm_real;
CCPR1H=0x00;
CCP1CON=0x0c;
PR2=pwm_cycle;
TRISC=TRISC&0xfb;
T2CON=0x00;
TMR2ON=1;
PORTC=0x00;
PORTB=PORTB&0xfe;
GAL输出
while
(1)
//设置PWM输出为最大
//
//CCP1选择为PWM工
//设置PWM的周期
//设置RC2---PWM输出
//分频系数=0x00
//启用TMR2
//
//RB0=0,输出低电
//RA4闪动
PORTA八=ObOOO1OOOO;
for(jm=15000;jm>1;jm--)
asm("nop");
}}
trial=0b10110000;
lkk=10;
RBIF=0;
voidmax_min_compare()
if(pwm_real>pwm_hi)pwm_real=pwm_hi;if(pwm_realmain(void)
//参数初始化
//禁止中断初始化
//I/O初始化
//PWM初始化
//RA1-PSW1发送低电平,
para_chushihua();nointerupt_chushihua();Io_chushihua();PWM_chushihua();RA1=0;
接通电源
RA5=0;
主电路充电延时
RA2=0;
RA4=0;
delay(100);
RB0=0;
禁止GAL输出
delay(100);
RA1=1;
接通电源
//RA5-RSW1发送低电平,
//RA2,指示灯灭
//RA4,指示灯灭
//主电路充电延时
//ST/(-STOP)发送低电平,
//RA1-PSW1发送高电平,
for(charge_delay=0;charge_delay<50;charge_delay++)
delay(15000);
RA5=1;
主电路充电延时
delay(100);
PP:
asm("nop");
RBIF=0;
标志设定
RBIE=0;
定
GIE=0;
RA2=0;
RA4=0;
run_flag=0;
设置
while(run_flag==0)
//
//RA5-RSW1发送高电平,
//主电路充电延时
//
//禁止RB4-7中断,清RBIF
//禁止RB4-7中断,RBIE设
//关全局中断
//RA2,指示灯灭
//RA4,指示灯灭
//运行标志---由RB2按钮
//
主程序
if(RB2==0)run_flag=1;
//RB2启动键,低电平有效
//运行标志---由RB2按钮设
delay(100);
//延时
//
intope;intopenloopn;
PRO—1-
开放GAL=输出delay(IOO);RA4=1;
pwm_real=180;
pwm_real=230;
//
/次/
delay(500);
ope=10;
ope=3;
//设定开环运行次数为12次
//
//ST/(-STOP)发送高电平,
//延时
//延时
//设定开环运行次数为20
//设定开环运行次数为20
for(openloopn=0;openloopn<=ope;openloopn++)
//0
00000000000000000
CCPR1L=pwm_real;
值130
open_loopf();
//000000000000000000delay(6000);RBIF=0;
定
RBIE=1;
GIE=1;
RA2=1;
pwm_real=pwm_hi;
//设置开环下PWM输出
//开环运行20次,启动//
//延时
//RB4-7中断,RBIF标志设
//RB4-7中断,RBIE设定
//开全局中断
//
//
ghl:
asm("nop");
//
if((pwm_real<110)&&(run_num<10))
pwm_real<140,但是run_num<10,表明未动,则
{//protect_run();
//如果
protect_run();
while(RA0==1)
delay(150);
protect_num++;
if(protect_num>30)//过温和过流保护软件滤波){protect();}
//RA0=1,过流和过温保护
//
//调用延时程序
//
如果30次保护,则认为是真正保护
protect_num=0;
//过流和过温保护
//
//
//自/手标志设定,标志设
//RB1=1---AUTO;自动
if(RB1==1)flag_autohand=1;
定
elseflag_autohand=0;
//RB1=0---HAND;手动
//
if(flag_autohand==1)
{111111*********111
if(pwm_real>pwm_lo)pwm_real-=1;//elsepwm_real=pwm_lo;
自动
//111111*********11111
else
==0)
//加(低有效),则
if(pwm_realif(RC1==0)
//减(低有效),则
if(pwm_real>pwm_lo)pwm_real-=1;elsepwm_real=pwm_lo;
}
max_min_compare();
CCPR1L=pwm_real;delay(4500);while(RA0==1)护输入,高电平保护
protect();
//设置PWM输出
//调用延时子程序
//RA0过流和过温保
//
//过流和过温保护
//
while(RB3==0)
run_flag=0;
设置
//RB3停机键,低电平有效
//运行标志---由RB3按钮
if(run_flag==0)
//停机,则跳转至
for(;pwm_realdelay(2000);
CCPR1L=pwm_real;
"至上置否PwM输出为最大
RB0=0;
禁止GAL输出para_chushihua();nointerupt_chushihua();PWM_chushihua();run_num=0;gotoPP;
//ST/(-STOP)发送低电平,//参数初始化
//禁止中断初始化
//PWM初始化
else
//
run_num=0;
gotoghl;