?? m8hv04_pwm_hf.c
字號(hào):
#define TestSteps 8000
#define SPIendMark 1
//使用FASTPWM輸出脈沖,脈沖寬度由T1PulseWidth決定
//脈沖寬度=T1PulseWidth * 0.125 us
#define T1PulseWidth 100
//HomeSpeed 定義HOME動(dòng)作時(shí)的轉(zhuǎn)速,>80
#define HomeSpeed 100
//Msteps_home_SP 定義HOME動(dòng)作最大運(yùn)動(dòng)步數(shù),比每圈脈沖數(shù)相等
#define Msteps_home_SP 1000
#include <iom8v.h>
#include <macros.h>
//ISARM pro
#define OUTQN0OFF PORTC|=0x01 //for
#define OUTQN0ON PORTC&=~0x01
#define OUTQN1OFF PORTC|=0x02 //For
#define OUTQN1ON PORTC&=~0x02
#define OUTQN1Pulse PORTC^=0x02
#define OUTQN2OFF PORTC|=0x04 //For
#define OUTQN2ON PORTC&=~0x04
#define OUTQN2Pulse PORTC^=0x04
#define OUTQN3OFF PORTC|=0x08 //For
#define OUTQN3ON PORTC&=~0x08
#define OUTQN3Pulse PORTC^=0x08
// motor 方向
#define OUTmotorDirCW PORTB&=~0x01
//順時(shí)針
#define OUTmotorDirCCW PORTB|=0x01
#define OUTmotorDirPU PORTB^=0x01
// made pulse
#define OUTmotorPulse PORTB^=0x02
#define OUTmotorPulseON PORTB&=~0x02
#define OUTmotorPulseOFF PORTB|=0x02
//INPUT Define
//Home PD2
#define INhomeSen 0x02
#define DInput00 (PIND&0x02)
#define DriverRDY (PIND&0x04)
#define DInput02 (PIND&0x08)
#define DInput03 (PIND&0x10)
#define MCaddress 91
#define Com_MoveDF 81
#define Com_HomeDF 71
#define Com_StopDF 85
//////////////////////////////
unsigned int Timer1Set[200];
unsigned int T1cSet;
///SPI
unsigned char RecTemp=0;
unsigned char SenTemp=5;
unsigned char SPI_Work=0;//spi staus
unsigned char SPI_Index=0;
unsigned char SPI_Index_Max=7;
unsigned char SPI_RecvBuf[8];
unsigned char SPI_TranBuf[8]={91,0,0,0,0,0,0,0};
unsigned char MCC_RecvBuf[8]; //馬達(dá)控制器接收緩沖區(qū)
unsigned char MCC_TranBuf[9]={91,0,0,0,0,0,0,0};//馬達(dá)控制器發(fā)送緩沖區(qū)
//MC control
unsigned char MC_Command=0;
unsigned int Target_POS=0;
unsigned int Old_POS=0;
unsigned int Now_POS=0;
unsigned int Move_Speed;
unsigned int PPsteps=0;
unsigned char MV_Step=0;
unsigned char MC_RDY=0;
unsigned char STATUS;
unsigned char HomeOK; //1:已找到HOME位
unsigned int TC1V0; //T1的值
unsigned int PosNow=0;//當(dāng)前位置
//unsigned int T1cSet; //計(jì)數(shù)初值
unsigned int Home_TC1V0_SP=300; //Home計(jì)數(shù)初值setpoint
unsigned int Msteps_Total;//總運(yùn)動(dòng)步數(shù)setpoint
unsigned int AccSteps; //變速需要的步數(shù)
unsigned char AccSL=10; //變速持續(xù)步數(shù)
unsigned char AccTmax; //變速次數(shù)
unsigned char AccTC; //變速計(jì)數(shù)器
unsigned int Nmin=200; //最低轉(zhuǎn)速
unsigned int Nmax=2000; //最高轉(zhuǎn)速
unsigned char AccN=20; //變轉(zhuǎn)速
unsigned int AccStepEnd; //加速結(jié)束時(shí)步數(shù)
unsigned int DccStepStart; //減速結(jié)束時(shí)步數(shù)
void watchdog_init(void)
{
WDR();
WDTCR=0x0F ;
}
void Delay_1ms(void)
{
unsigned int i;
for (i = 1; i<1140; i++)
;
}
void delayXms(unsigned int n)
{
unsigned int i=0;
while(i<n)
{
Delay_1ms();
i++;
}
}
void port_init(void)
{
// PORTA=0xF0; //PA set to 1
// DDRA=0xF0; //PA0-PA3:ADC PA4-PA6:KL0-KL2(OUT)
//PA7:LCD-E (OUTPUT)
PORTB=0xff; //PB set to 1
DDRB=0x13; //PB0:DIR PB1:PULSE
//PB2:SS PB3:MOSI PB4:MISO PB5:SCK
PORTC=0xFF; //PC set to 1
DDRC=0x0F; //PC0-PC3:Q0-Q3
PORTD=0xFF; //PD set to 1
DDRD=0x00; //PD0:RXD PD1:TXD PD2:DI0 PD3:DI1
//PD4:DI2 PD5:DI3
//OUTDEON;
SFIOR&=~(1<<PUD); //OPEN UP LINK
//MCUCR|=(1<<ISC11); //Down edge int1
//GICR=(1<<INT1); //enable INT1
delayXms(10); //delay 1s
}
void SPI_slaveInit(void)
{
SPI_TranBuf[0]=MCaddress;
SPI_TranBuf[7]=SPIendMark;
SPDR=SPI_TranBuf[0];
SPCR=0xC1;
}
///////////////Timer init
void timer_init(void)
{
/////timer0
//TCCR0=0x00; //stop T1 TCCR0=3; 1/64 TCNT0=125
//TCNT0=125;
//TIMSK|=(1<<TOIE0); //enable T1 INT
////Timer1
TCCR1B=0x00; //stop T1
OCR1AH=0x00; // no A match
OCR1A=T1PulseWidth;
//OCR1BH=0x00; // no B match
OCR1BL=0x00;
TCCR1A=0x00;
//TCCR1A|=(1<<COM1A0);
TCCR1A|=((1<<COM1A1)|(1<<WGM11));
TCCR1B|=((1<<WGM12)|(1<<WGM13));
TIMSK|=(1<<TOIE1); //enable T1 INT
}
#pragma interrupt_handler SPI_stc_isr:11
void SPI_stc_isr(void)
{
unsigned char i,summ;
unsigned int eev;
SPI_RecvBuf[SPI_Index]=SPDR;
SPDR=SPI_TranBuf[SPI_Index+1];
if(SPI_RecvBuf[0]==MCaddress)
{
SPI_Index++;
SPI_Work=1; //spi is working
}
else
{
SPI_Index=0;
SPI_Work=0; //spi stop
}
if(SPI_Index>SPI_Index_Max)
{
SPI_Index=0;
SPI_Work=0; //spi stop
SPDR=SPI_TranBuf[0]; //ready for recive
if(SPI_RecvBuf[1]>70 && MC_RDY==1 &&SPI_RecvBuf[7]==SPIendMark)
{
summ=0;
for(i=1;i<6;i++)
{
summ=summ+SPI_RecvBuf[i];
}
if(summ==SPI_RecvBuf[6])
{
//OUTQN1ON;
SPI_TranBuf[3]=SPI_RecvBuf[2];
SPI_TranBuf[4]=SPI_RecvBuf[3];
Old_POS=Target_POS;
eev=SPI_RecvBuf[2];
eev=(eev<<8)+SPI_RecvBuf[3];
Target_POS=eev;
//Target_POS=100;
eev=SPI_RecvBuf[4];
eev=(eev<<8)+SPI_RecvBuf[5];
Move_Speed=eev;
MC_Command=SPI_RecvBuf[1];
SPI_RecvBuf[1]=0;
//SPDR=SPI_TranBuf[0]; //ready for recive
}
}//if(SPI_RecvBuf[1]>70 ) && MC_RDY==1
}
}//void SPI_stc_isr(void)
unsigned char HomeStop=1;
unsigned char KeepCR=0;
#pragma interrupt_handler timer1_ovf_isr:9
void timer1_ovf_isr(void)
{
ICR1=T1cSet; //ICR1不能過(guò)小
PPsteps++;
OUTQN3Pulse;
if(PPsteps==Msteps_Total)
{
TCCR1B&=0xF8; //Stop T1
MC_RDY=1;
PPsteps=0;
HomeStop=1;
}//if(PPsteps==Msteps_Total)
KeepCR++;
if(!HomeOK)
{
if(!(PIND & INhomeSen))
{
TCCR1B&=0xF8; //Stop T1
HomeStop=1;
}//if(!(PIND & INhomeSen))
}
}//void timer1_ovf_isr(void)
void move_control(void)
{
if(PPsteps<AccStepEnd)
//if(PPsteps<126)
{
if(KeepCR>AccSL)
{
KeepCR=0;
AccTC++;
T1cSet=Timer1Set[AccTC];
}
}//if(PPsteps<AccStepEnd)
else
{
OUTQN2ON;
if(PPsteps>DccStepStart)
// if(PPsteps>875)
{
OUTQN2OFF;
if(KeepCR>AccSL)
{
if(AccTC>0)
AccTC--;
T1cSet=Timer1Set[AccTC];
KeepCR=0;
}//if(KeepCR>AccSL)
}//if(PPsteps>DccStepStart)
}//else
}//void move_control(void)
void SPI_AnswerPOS(unsigned int aPOS)
{
unsigned int eev;
unsigned char edh;
unsigned char edl;
edh=(aPOS>>8);
edl=aPOS;
SPI_TranBuf[3]=edh;
SPI_TranBuf[4]=edl;
}
void MotorStart_Init(void)
{
MC_RDY=0;
SPI_TranBuf[2]=MC_RDY;
MC_Command=0;
PPsteps=0;
SPI_AnswerPOS(Old_POS);
}//void MotorStart_Init(void)
unsigned int CalcT1cSet(unsigned int NSP)
{
return (480000/NSP-1); //1.8度
}
void ACC_calc(void)
{
unsigned char i=0;
unsigned int Nnowc;
unsigned int HalfSteps;
Move_Speed=6000;
if(Move_Speed>Nmax)
Move_Speed=Nmax;
AccTmax=(Move_Speed-Nmin)/AccN; //計(jì)算變速次數(shù)
////設(shè)置TIMER1的植
//for( i=0;i<45;i++)
//Timer1Set[i]=5000;
Nnowc=Nmin;
for(i=0;i<(AccTmax+1);i++)
{
Timer1Set[i]=CalcT1cSet(Nnowc);
//CalcT1cSet(Nnowc);
//Timer1Set[i]=TSS;
Nnowc=Nnowc+AccN;
}// for(i=0 to AccTmax)
//計(jì)算變速所需的步數(shù)
HalfSteps=Msteps_Total/2;
AccStepEnd=(AccTmax+1) * AccSL ;
if(AccStepEnd>HalfSteps) //總步數(shù)太小
{
DccStepStart=HalfSteps+AccSL;
if(Msteps_Total<AccSL*3)
{
DccStepStart=Msteps_Total;
}//if(Msteps_Total<AccSL*3)
AccStepEnd=Msteps_Total-DccStepStart;
}//if(AccSteps>Msteps_Total)
else //步數(shù)足夠多
{
DccStepStart=Msteps_Total-AccStepEnd-AccSL;
}//else
T1cSet=Timer1Set[0];
}//void ACC_calc(void)
void MoveFun(void)
{
unsigned int TarposStep;
//STEPcode=10+PosID;
TarposStep=Target_POS;
if(TarposStep != Old_POS)
{
if(TarposStep>Old_POS)
{
Msteps_Total=TarposStep-Old_POS;//總運(yùn)動(dòng)步數(shù)
OUTmotorDirCCW; //正向
}//if Tar
else
{
Msteps_Total=Old_POS-TarposStep;//總運(yùn)動(dòng)步數(shù)
OUTmotorDirCW;
}
Delay_1ms();
ACC_calc();
//TCNT1=T1cSet; //第一脈沖 在ACC_calc()中付初值
ICR1=T1cSet;
AccTC=0; //Timer1Set[]下標(biāo)計(jì)數(shù)器,move_control()中用
//TCCR1B=0x01; //start T1, 8M 0.125us
TCCR1B|=0x1; //start T1, 8M 0.125us
}//IF
else
MC_RDY=1;
} // void MoveFun(void)
unsigned int DelayCR=0;
void main()
{
//delayXms(500);
port_init(); //IO初始化
timer_init();
T1cSet=1000;
TCNT1=T1cSet;
SPI_slaveInit();
SEI();
delayXms(100);
MV_Step=15;
//MC_Command=81;
Move_Speed=0;
Target_POS=0;
MC_RDY=1;
//SPI_TranBuf[1]=MCaddress;
SPI_TranBuf[2]=MC_RDY;
///////
Old_POS=0;
Target_POS=TestSteps;
while(1)
{
switch(MV_Step)
{
case 10: //home
if(MC_Command==Com_HomeDF)//HOME
{
OUTQN0ON;
HomeOK=0;
MotorStart_Init(); //redy for start move
T1cSet=CalcT1cSet(HomeSpeed);
ICR1=T1cSet;
Msteps_Total=Msteps_home_SP;
MV_Step=60;
HomeStop=0;
TCCR1B|=0x1; //start T1, 8M/8 1us
}//if(MC_Command==Com_HomeDF)
break;
case 60: //home
if(MC_RDY==1)
{
MV_Step=10; //Home finish not OK!
OUTQN0OFF; //關(guān)閉驅(qū)動(dòng)器
HomeStop=0;
break;
}//if(MC_RDY==1)
if(HomeStop==1)
{
delayXms(10);
if(!(PIND & INhomeSen))
{
Target_POS=0;
MC_RDY=1;
PPsteps=0;
HomeOK=1;
MV_Step=15; //Home finish OK
}//if(!(PIND & INhomeSen))
else //research
{
HomeStop=0;
TCCR1B|=0x1;
}
}// if(!(PIND & INhomeSen))
break;
case 15:
//if(MC_Command==Com_MoveDF && HomeOK==1)
{
//OUTQN2ON;
HomeOK=1;///////////
MotorStart_Init(); //redy for start move
OUTQN0ON; //Enable motor driver
MoveFun();
MV_Step=20;
// TCCR1B=0x02; //start T1, 8M/8 1us
}
break;
case 20:
//OUTQN2Pulse;
move_control();
if(MC_RDY==1)
{
SPI_AnswerPOS(Target_POS);
//MV_Step=15;
MV_Step=50;
DelayCR=0;
// OUTQN3ON;
}
break;
case 50://測(cè)試程序
Delay_1ms();
DelayCR++;
if(DelayCR>5000)
{
if(Old_POS>0)
{
Old_POS=0;
Target_POS=TestSteps;
}//if(Old_POS>0)
else
{
Old_POS=TestSteps;
Target_POS=0;
}//else
MV_Step=15;
}//if(DelayCR>10000)
break;
}//switch(MV_Step)
//緊急停止命令,將關(guān)閉驅(qū)動(dòng)器
if(MC_Command==Com_StopDF)
{
OUTQN0OFF; //關(guān)閉驅(qū)動(dòng)器
HomeOK=0;
MV_Step=10;
}
//HOME OK 后收到HOME命令
if(MC_Command==Com_HomeDF)// HOME
{
MV_Step=10;
}
//刷新發(fā)送緩沖區(qū)的數(shù)據(jù)
SPI_TranBuf[2]=MC_RDY;
SPI_TranBuf[6]=PIND; //Get INPUT status
}//while
}//main
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -