#include <pic.h> //改編PIC控制 //電動(dòng)車雙閉環(huán)程序,采用雙閉環(huán)方式控制電機(jī),以得到最好的zh轉(zhuǎn)速性能,并且可以
//限制電機(jī)的最大電流。本應(yīng)用程序用到兩個(gè)CCP部件,其中CCP1用于PWM輸出,以控
//制電機(jī)電壓;CCP2用于觸發(fā)AD,定時(shí)器TMR2、TMR1,INT中斷,RB口電平變化中斷,
//看門狗以及6個(gè)通用I/O口
#define AND 0xe0 //狀態(tài)采集5,6,7位
#define CURA 0X0a //電流環(huán)比例和積分系數(shù)之和
#define CURB 0X09 //電流環(huán)比例系數(shù)
#define THL 0X6400 //電流環(huán)最大輸出
#define FULLDUTY 0X0FF //占空比為1時(shí)的高電平時(shí)間
#define SPEA 0X1d //轉(zhuǎn)速環(huán)比例和積分系數(shù)之和
#define SPEB 0X1c //轉(zhuǎn)速環(huán)比例系數(shù)
#define GCURHILO 0X0330 //轉(zhuǎn)速環(huán)最大輸出
#define GCURH 0X33 //最大給定電流
#define GSPEH 0X67 //最大轉(zhuǎn)速給定
#define TSON 0X38 //手柄開啟電壓1.1 V,TSON*2為剎車后手柄開啟電壓,即
//2.2 V
#define VOLON 0X4c //低電壓保護(hù)重開電壓3.0 V即33 V
#define VOLOFF 0X49 //低電壓保護(hù)關(guān)斷電壓2.86 V即31.5 V
volatile unsigned char DELAYH,DELAYL,oldstate,speed,
speedcount,tsh,count_ts,count_vol,gcur,currenth,
voltage; //寄存器定義
static bit sp1,spe,ts,volflag,spepid,lowpower,
off,shutdown,curpid; //標(biāo)志位定義
static volatile unsigned char new[10]={0xaf,0xbe,0xff,0x7e,0xcf,
0xff,0xd7,0x77,0xff,0xff}; //狀態(tài)寄存器表
//------------PIC16F877初始化子程序------------
void INIT877()
{
PORTC=0X0FF; //關(guān)斷所有MOSFET
TRISC=0X02; //設(shè)置C口輸出
PIE1=0X00; //中斷寄存器初始化,關(guān)斷所有中斷
TRISA=0XCF; //設(shè)置RA4,RA5 輸出
TRISB=0XEF; //RB 口高三位輸入,采集電機(jī)三相的霍爾信號(hào)
PORTC=new[(PORTB&AND)>>5]; //采集第一次霍爾信號(hào),并輸出相應(yīng)的信號(hào),導(dǎo)通
//兩個(gè)MOS管
T2CON=0X01; //TMR2 4分頻
CCPR1L=0X0FF; //初始時(shí)PWM輸出全高
CCP1CON=0X0FF; //CCP1設(shè)置為PWM方式
CCP2CON=0X0B; //CCP2設(shè)置為特殊方式,以觸發(fā)AD
ADCON0=0X81; //AD時(shí)鐘為32分頻,且AD使能,選擇AN0通道采集手
//柄電壓
TMR2=0X00; //TMR2寄存器初始化
TMR1H=0X00; //TMR1寄存器初始化
TMR1L=0X00;
T1CON=0X00; //TMR1為1分頻
CCPR2H=0X08;
CCPR2L=0X00; //電流采樣周期設(shè)置為TAD=512 μs
PR2=0XC7; //PWM頻率設(shè)置為5 kHz
ADCON1=0X02; //AD結(jié)果左移
OPTION=0XFB; //INT上升沿觸發(fā)
TMR2ON=1; //PWM開始工作
INTCON=0XD8; //中斷設(shè)置GIE=1,PEIE=1,RBIE=1
ADIE=1; //AD中斷使能
speedcount=0x00; //轉(zhuǎn)速計(jì)數(shù)寄存器
speed=0x7f; //轉(zhuǎn)速保持寄存器
spe=1; //低速標(biāo)志位
sp1=1; //低速標(biāo)志位
oldstate=0x0ff; //初始狀態(tài)設(shè)置,區(qū)別于其他狀態(tài)
count_ts=0x08; //電流采樣8次,采集1次手柄
count_vol=0x00; //采樣256次手柄,采集1次電池電壓
ts=1; //可以采集手柄值的標(biāo)志位
ADGO=1; //AD采樣使能
TMR1ON=1; //CCP2部件開始工作
}
//------------延時(shí)子程序---------------
#pragma interrupt_level 1
void DELAY1(x)
char x;
{
DELAYH=x; //延時(shí)參數(shù)設(shè)置
#asm
DELAY2 MOVLW 0X06
MOVWF _DELAYL
DELAY1 DECFSZ _DELAYL
GOTO DELAY1
DECFSZ _DELAYH
GOTO DELAY2
#endasm
}
//-----------狀態(tài)采集子程序----------------------
void sample()
{
char state1,state2,state3,x;
do {
x=1;
state1=(PORTB&AND); //霍爾信號(hào)采集
DELAY1(x);
state2=(PORTB&AND);
}while(state1-state2); //當(dāng)三次采樣結(jié)果不相同時(shí)繼續(xù)采集狀態(tài)
if(state1-oldstate!=0) //看本次采樣結(jié)果是否與上次相同,不同
//則執(zhí)行
{oldstate=state1; //將本次狀態(tài)設(shè)置為舊狀態(tài)
state1=(oldstate>>5);
PORTC=new[state1]; //C口輸出相應(yīng)的信號(hào)觸發(fā)兩個(gè)MOS管
if(sp1==1){spe=1;sp1=0;}
else { //如果轉(zhuǎn)速很低,則spe置1
spe=0;sp1=0;
speedcount<<=1;
state3=(TMR1H>>2); //否則,spe=0,計(jì)轉(zhuǎn)速
speed=speedcount+state3; //speed寄存器為每256 μs加1
}
speedcount=0;
}
} |