?? motor.c
字號:
#include "DSP28_Device.h"
#include "comm.h"
#include "mcbsp.h"
#include "gui_string.h"
#include "motor.h"
#define DATATYPE 0 /* 0代表edit菜單;1代表選項菜單*/
unsigned int i,j;
unsigned int send_flag;
/***************************************************/
interrupt void mrinta_isr(void);
interrupt void t1pint_isr(void);
interrupt void t2pint_isr(void);
interrupt void cap_isr(void);
interrupt void pdpinta_isr(void);
void delay(unsigned int m);
void pidcontrol(int u,int y);//調(diào)節(jié)電流
void pidcontrol1(int u,int y);//調(diào)節(jié)速度
unsigned int t1prd=117;//定時器1的周期
unsigned int t2prd=117;//定時器2的標志
unsigned int dir=1;//電機轉(zhuǎn)動方向
unsigned int start=0;//電機啟動停止標志
unsigned int setflag=0;//表示是否進行速度設(shè)定
unsigned int sudusendflag=0,xssdbz=0;//速度上傳標志和速度顯示的計數(shù)
unsigned int sdxsjs=0;
unsigned int dccurent,u,v,w,speedad;//直流母線電流
unsigned int dcvoltage;//直流母線電壓
Uint32 Sumdcv=0;
unsigned int dcvcount=0,Averagedcv=0;//母線電壓平均值初始化
unsigned int capstastus;//定義cap口的電平
Uint32 Time,T2cnt,Speed=0,count=0;
unsigned Pole=2;//極對數(shù)
Uint32 Sum=0,Average=0;
unsigned int l=0,nn=0;
//速度到pwm的初始值
unsigned int pwm=10;//pwm的占空比初值
float kp=0.1,ki=0.1,kd=0.0;
int Speedset=1500;
int ek=0,ek1=0,ek2=0;
int du;
float duk;
int t2=0;
unsigned int test[2000],test1[5000],test2[2000];
int sss=0;
/***************************************************/
/*******************************************************/
#define menu_num 5 /*通過num來控制輸出文字的個數(shù),通過gui_string.sam控制內(nèi)容。*/
unsigned int Test;
/////////////////////////////////////////////////////////////////////////
unsigned int Edit_result;
unsigned int i,k;
/////////////////////////////////////////////////////////////////////////
unsigned int mcbspx[FRAMLENGTH];
unsigned int mcbspr[FRAMLENGTH];
unsigned int mcbsp_s;
PmcbspForDec psend;
PmcbspForDec preceive;
/************************************************/
void main(void)
{
#if DATATYPE==0
Test =FRAME_DATASEND; //0x1 數(shù)據(jù)傳送幀
#endif
#if DATATYPE==1
Test =FRAME_DATAEND; // 0x3 數(shù)據(jù)傳送結(jié)束幀
#endif
/*初始化系統(tǒng)*/
InitSysCtrl();
/*關(guān)中斷*/
DINT;
IER = 0x0000;
IFR = 0x0000;
/*初始化PIE*/
InitPieCtrl();
/*初始化PIE矢量表*/
InitPieVectTable();
/*初始化GPIO*/
Gpioinit();
/*初始化AD*/
InitAdc();
/*初始化PWM*/
Init_eva_pwm();
/*初始化CAP*/
Capinit();
/*初始化MCBSP外設(shè)*/
InitMcbsp();
EALLOW; // This is needed to write to EALLOW protected register
PieVectTable.CAPINT1=&cap_isr;
PieVectTable.CAPINT2=&cap_isr;
PieVectTable.CAPINT3=&cap_isr;
PieVectTable.T1PINT=&t1pint_isr;
PieVectTable.T2PINT=&t2pint_isr;
PieVectTable.PDPINTA=&pdpinta_isr;
PieVectTable.MRINTA= &mrinta_isr;
EDIS; // This is needed to disable write to EALL
PieCtrl.PIEIER2.bit.INTx4=1;//T1pint中斷
PieCtrl.PIEIER3.bit.INTx1=1;//T2pint中斷
PieCtrl.PIEIER3.bit.INTx5=1;//Cap1中斷
PieCtrl.PIEIER3.bit.INTx6=1;//Cap2中斷
PieCtrl.PIEIER3.bit.INTx7=1;//Cap3中斷
PieCtrl.PIEIER1.bit.INTx1=1;//pdpinta中斷
PieCtrl.PIEIER6.bit.INTx5 = 1;//McBSP接受中斷
/* 設(shè)置IER寄存器 */
IER |= M_INT1;
IER |= M_INT2; // t1pint enable
IER |= M_INT3; // capture enable
IER |= M_INT6;
// Enable global Interrupts and higher priority real-time debug events:
//startmotor();
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
psend=(PmcbspForDec)(&mcbspx[0]);
// Step 6. IDLE loop. Just sit and loop forever (optional):
while(1)
{
switch(Test)
{
case FRAME_DATASEND:
psend->Length=FRAMLENGTH;
psend->Type=FRAME_DATASEND; //0x1 數(shù)據(jù)傳送
psend->Mutul=FRAME_SING;
psend->Data[0]=MOTOR_START; //0xAA30 電機實驗開始
mcbsp_tx((unsigned int *)psend);
Test=0;
break;
case FRAME_DATAEND:
psend->Length=FRAMLENGTH;
psend->Type=FRAME_DATAEND; //0x3 數(shù)據(jù)傳送
psend->Mutul=FRAME_SING;
psend->Data[0]=MOTOR_OVER; //0xAA32 電機實驗結(jié)束
mcbsp_tx((unsigned int *)psend);
Test=0;
break;
default:
break;
}
mcbsp_rx(&mcbspr[0]);
if((mcbsp_s == 0xffff)||(mcbsp_s == 3)){
/*通知主機程序通訊出錯,準備重發(fā)*/
psend->Length = FRAMLENGTH;
psend->Type = FRAME_CMD;
psend->Data[0] = CHECK_ERR;
psend->Mutul = FRAME_SING;
mcbsp_tx((unsigned int *) psend);
}
if(mcbsp_s == 0)
{
preceive=(PmcbspForDec)(&mcbspr[0]);
if(mcbspr[3]==0xaa38)
{
switch(mcbspr[4])
{
case 0xaa35:
{
start=1;
xssdbz=1;
startmotor();break;//啟動電機
}
case 0xaa34:
{
start=0;
xssdbz=1;
stopmotor();//停止電機
setflag=0;
break;
}
case 0xaa36:
{
if(start==1)
{
dir=!dir;//換向
stopmotor();
delay(1000);
startmotor();
xssdbz=1;
}
break;
}
default:break;
}
}
if(mcbspr[3]==0xaa37)//pid參數(shù)設(shè)定
{
xssdbz=1;
Speedset=mcbspr[4];
kp=(float)mcbspr[5]/1000;
ki=(float)mcbspr[6]/1000;
kd=(float)mcbspr[7]/1000;
if(start==1)
setflag=1;//表示開始設(shè)定速度,pid
else
setflag=0;
}
}
if((sudusendflag==1)&&(xssdbz==1))//每隔2s上傳一次速度
{
sudusendflag=0;
psend->Length = FRAMLENGTH;
psend->Type = FRAME_DATASEND;
psend->Data[0] = 0xaa20;
if(start==0)//電機停止狀態(tài)下速度為0
Speed=0x0;
psend->Data[1] =Speed;
psend->Mutul = FRAME_SING;
mcbsp_tx((unsigned int *) psend);
}
}
}
interrupt void t2pint_isr(void)
{
count++;
EvaRegs.EVAIFRB.bit.T2PINT=1;//清除中斷標志
EvaRegs.EVAIMRB.bit.T2PINT=1;//中斷允許
PieCtrl.PIEACK.bit.ACK3=1;//向cpu申請中斷
}
interrupt void cap_isr(void)
{
/*****以下用來檢測傳感器的輸出電平,用來換向****/
Uint32 kk=t2prd;
EALLOW;
GpioMuxRegs.GPAMUX.bit.CAP1Q1_GPIOA8=0;//設(shè)定cap1~3為gpio
GpioMuxRegs.GPAMUX.bit.CAP2Q2_GPIOA9=0;
GpioMuxRegs.GPAMUX.bit.CAP3QI1_GPIOA10=0;
GpioMuxRegs.GPADIR.bit.GPIOA8=0;//設(shè)定cap1~3為輸入
GpioMuxRegs.GPADIR.bit.GPIOA9=0;
GpioMuxRegs.GPADIR.bit.GPIOA10=0;
capstastus=(GpioDataRegs.GPADAT.all&0x0700)>>8;
if(dir==1)
{
switch(capstastus)//ir2136 的hin和lin是反向的
{
case 1: EvaRegs.ACTR.all=0x7fd;break;//h3 fall
case 2: EvaRegs.ACTR.all=0xfd7;break;//h1 fall
case 3: EvaRegs.ACTR.all=0x7df;break;//h2 rise
case 4: EvaRegs.ACTR.all=0xd7f;break;//h2 fall
case 5: EvaRegs.ACTR.all=0xf7d;break;//h1 rise
case 6: EvaRegs.ACTR.all=0xdf7;break;//h3 rise
}
}
else
{
switch(capstastus)//ir2136 的hin和lin是反向的
{
case 5: EvaRegs.ACTR.all=0xfd7;break;//h1 rise
case 1: EvaRegs.ACTR.all=0xd7f;break;//h3 fall
case 3: EvaRegs.ACTR.all=0xdf7;break;//h2 rise
case 2: EvaRegs.ACTR.all=0xf7d;break;//h1 fall
case 6: EvaRegs.ACTR.all=0x7fd;break;//h3 rise
case 4: EvaRegs.ACTR.all=0x7df;break;//h2 fall
}
}
/*以下用來計算轉(zhuǎn)速*/
T2cnt=EvaRegs.T2CNT;//讀取定時器2的值
Time=kk*count+ T2cnt;//獲得運轉(zhuǎn)1相所需時間
Sum+=Time;
l++;
if(l==12)//每轉(zhuǎn)12/6/pole計算一下轉(zhuǎn)速
{
Average=Sum/12;
Speed=kk*20000*60/(Average*6*Pole);//計算轉(zhuǎn)速
Sum=0;
l=0;
test[nn]=Speed;//測試用,存儲速度值
nn++;
if(nn==2000)
{
nn=0;
}
}
count=0;
EvaRegs.T2CON.all = 0x1400;//關(guān)閉定時器2
EvaRegs.T2CNT = 0x0000;
EvaRegs.T2CON.all = 0x1440;//啟動定時器2
/*************************/
GpioMuxRegs.GPAMUX.bit.CAP1Q1_GPIOA8=1;//重新設(shè)定cap1~3為gpio
GpioMuxRegs.GPAMUX.bit.CAP2Q2_GPIOA9=1;
GpioMuxRegs.GPAMUX.bit.CAP3QI1_GPIOA10=1;
EvaRegs.EVAIFRC.all = 7 ; // 清捕捉中斷
EvaRegs.CAPFIFO.all = 0x01500; // 清空捕捉堆棧
PieCtrl.PIEACK.bit.ACK3=1;//cap1中斷向cpu申請中斷
}
interrupt void t1pint_isr(void)
{
dcvoltage=(AdcRegs.RESULT0)>>4;
dccurent=(AdcRegs.RESULT3)>>4;
w=(AdcRegs.RESULT1)>>4;
u=(AdcRegs.RESULT2)>>4;
speedad=(AdcRegs.RESULT4)>>4;
v=(AdcRegs.RESULT5)>>4;
sdxsjs++;
if(sdxsjs==40000)
{
sudusendflag=1;//速度上傳標志置位
sdxsjs=0;
GpioDataRegs.GPADAT.bit.GPIOA13 =!GpioDataRegs.GPADAT.bit.GPIOA13;//程序運行顯示
}//速度上傳得計時
//母線電壓檢測,過壓保護,
//注:電機在啟動或者轉(zhuǎn)動方向改變時,可能母線電壓有脈動
//采用多次求平均值
Sumdcv+=dcvoltage;
dcvcount++;
if(dcvcount==500)
{
Averagedcv=Sumdcv/500;//求平均母線電壓
Sumdcv=0;
dcvcount=0;
}
if(Averagedcv>=3000)
{
stopmotor();
GpioDataRegs.GPADAT.bit.GPIOA11 =1;//過壓顯示
}
else
{
GpioDataRegs.GPADAT.bit.GPIOA11 =0;
test1[t2]=dcvoltage;
test2[t2]=dccurent;
////速度調(diào)節(jié)
t2++;
if(t2==5000)
{
if(setflag==1)
{
pidcontrol(Speedset,Speed);//50ms
}
t2=0;
}
}
/******************************/
AdcRegs.ADC_ST_FLAG.bit.INT_SEQ1_CLR=1; //清除狀態(tài)字
AdcRegs.ADCTRL2.bit.RST_SEQ1=1;//復(fù)位seq1
EvaRegs.EVAIFRA.bit.T1PINT=1;//清除中斷標志
EvaRegs.EVAIMRA.bit.T1PINT=1;//中斷允許
PieCtrl.PIEACK.bit.ACK2=1;//向cpu申請中斷
}
interrupt void pdpinta_isr(void)
{
EvaRegs.EVAIFRA.bit.PDPINTA=1;//清除PDPINTA中斷標志
PieCtrl.PIEACK.bit.ACK1=1;//向cpu申請中斷
stopmotor();
GpioDataRegs.GPADAT.bit.GPIOA12 =1;//故障顯示
EvaRegs.COMCONA.bit.FCOMPOE=1;//重新使能比較輸出
}
/**************************************/
interrupt void mrinta_isr(void) // McBSP-A
{
PieCtrl.PIEACK.bit.ACK6 = 1;
if(Mcbsp_RxRdy() == 1)
{
RevBuffer[datarevlength] = McbspRegs.DRR1.all;
datarevlength++;
}
EINT;
}
//pid控制
void pidcontrol(int u,int y)
{
ek=u-y;
duk=kp*(ek-ek1)+ki*ek+kd*(ek+ek2-ek1*2);
du=(int)duk;
if(duk>1) duk=1;
if(duk<-1) duk=-1;
pwm-=du;
if(pwm<4)
{
pwm=4;
}
if(pwm>70)
{
pwm=70;
}
EvaRegs.CMPR1=pwm;
EvaRegs.CMPR2=pwm;
EvaRegs.CMPR3=pwm;
ek2=ek1;
ek1=ek;
}
void delay(unsigned int m)
{
unsigned int i,j;
for(i=0;i<m;i++)
{
for(j=0;j<1500;j++)
{}
}
}
/***********************************************************************/
// No more
/***********************************************************************/
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -