MC9S08MP16驱动步进电机的程序
0赞本文介绍了一种HCS08单片机驱动步进电机的程序,能实现正反转。现象是电位器在中间位置时电机不转,逆时针旋转电位器,电机逆时针转一圈;顺时针旋转电位器,电机顺时针转一圈。
先上实物:
电机是12V4相8步进电机28BYJ48-BT01,带减速器。驱动芯片用的TI的ULN2003A,单片机是MP9S08MP16CLC。电路原理图如下(J1的6、7、8脚本例中未使用):
下面是完整程序:
#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
struct _motor
{
signed char step;//µ±Ç°²½
unsigned char direction;
unsigned int cycle;//ÿ²½ÖÜÆÚ
unsigned int cnt;//Ҫת¶àÉÙ²½
} motor;
uchar StepTable[8] =
{
0x01,
0x03,
0x02,
0x06,
0x04,
0x0C,
0x08,
0x09
};
void ICS_Init(void){
char TRIM ;
TRIM = NVICSTRM;
if (TRIM == 0xFF)
ICSTRM = 0x80;
else
ICSTRM = TRIM;
ICSC1 = ICSC1_IREFS_MASK;//CLKS10=00 OUTPUT OF FLL is selected , RDIV=0,IREFS=1 INTERNAL REFERENCE clock selected , IRCLKEN=0,IREFSTEN=0
ICSC2 = 0;//BDIV=0 bus clock = Divides selected clock by 1,RANGE=0,HGO=0,LP=0,EREFS=0,ERCLKEN=0,EREFSTEN=0
ICSSC = ICSSC_DRST_DRS0_MASK | ICSSC_IREFST_MASK | ICSSC_DMX32_MASK | ICSSC_FTRIM_MASK;//DRST_DRS10=01 FLL output Mid range 39.85 Mhz FLL factor 1216(1024 when DMX32=0)|DMX32=1 DCO maximum frequency | FTRIM = 1
while((ICSSC & (ICSSC_DRST_DRS1_MASK| ICSSC_DRST_DRS0_MASK)) != ICSSC_DRST_DRS0_MASK)
{
//Wait until the FLL switches to Mid range DCO mode
}
}
void MCU_Init(void)
{
SOPT1 = SOPT1_COPT0_MASK |SOPT1_STOPE_MASK|SOPT1_BKGDPE_MASK |SOPT1_RSTPE_MASK ;//Watchdog enable. Stop Mode Enable. Reset and BKGD enabled
ICS_Init();
}
void GPIO_Init(void)
{
PTADD = 0xFF;
PTBDD = 0xFE;//PTB0×öADC
PTCDD = 0xFF;
PTDDD = 0xFF;
PTEDD = 0xFF;
PTFDD = 0xFF;
}
void FTM1_Init(void)
{
FTM1SC = ( //FTM1SC_PS2_MASK | FTM1SC_PS1_MASK | FTM1SC_PS0_MASK | // FTM clock source is bus clock divided by 1
FTM1SC_CLKSA_MASK |FTM1SC_TOIE_MASK); // 625000 of bus frequency
FTM1MOD = 20000;
}
void ADC_Init()
{
ADCCFG=0x91;//µÍ¹¦ºÄģʽ£¬8λ¾«¶È£¬ADCK=×ÜÏ߯µÂÊ/2
ADCSC2=0x00;//0x00:Èí¼þ´¥·¢£¬±È½Ï¹¦ÄܽûÖ¹
APCTL1=0x0F;//ͨµÀÒý½ÅʹÄÜ£º0x01:AD0;0x02:AD1ÒÀ´ËÀàÍÆ
APCTL2=0x20;
}
unsigned int ReadADC(unsigned char ch)
{
unsigned int val;
ADCSC1=ch;
while(ADCSC1_COCO == 0);
val = ADCR;
return val;
}
void StepBack(unsigned int cnt)
{
motor.direction = 1;
motor.cycle = 20000;
motor.cnt = cnt;
FTM1MOD = motor.cycle;
//motor.step
}
void StepNext(unsigned int cnt)
{
motor.direction = 0;
motor.cycle = 20000;
motor.cnt = cnt;
FTM1MOD = motor.cycle;
//motor.step
}
void main(void) {
unsigned int val;
EnableInterrupts; /* enable interrupts */
/* include your code here */
MCU_Init();
GPIO_Init();
FTM1_Init();
ADC_Init();
for(;;) {
val = ReadADC(0);
if(val<100)
{
StepBack(4100);
while(ReadADC(0)<150)__RESET_WATCHDOG();;
}
else if(val>200)
{
StepNext(4100);
while(ReadADC(0)>150)__RESET_WATCHDOG();;
}
__RESET_WATCHDOG(); /* feeds the dog */
} /* loop forever */
/* please make sure that you never leave main */
}
void interrupt VectorNumber_Vftm1ovf FTM1_ISR(void)
{
FTM1SC_TOF = 0; // Clear Timer overflow flag
if(motor.cnt>0)
{
if(motor.direction == 0)//Õýת
{
PTBD = StepTable[motor.step] << 6;
PTED = StepTable[motor.step] << 3;
motor.step++;
if(motor.step >=8)
{
motor.step = 0;
}
}
else if(motor.direction == 1)//·´×ª
{
PTBD = StepTable[motor.step] << 6;
PTED = StepTable[motor.step] << 3;
motor.step--;
if(motor.step <0)
{
motor.step = 7;
}
}
motor.cnt--;
}
else
{
PTBD = 0;
PTED = 0;
}
}


