freetech

MC9S08MP16驱动步进电机的程序

0
阅读(4627)

本文介绍了一种HCS08单片机驱动步进电机的程序,能实现正反转。现象是电位器在中间位置时电机不转,逆时针旋转电位器,电机逆时针转一圈;顺时针旋转电位器,电机顺时针转一圈。

先上实物:

image

电机是12V4相8步进电机28BYJ48-BT01,带减速器。驱动芯片用的TI的ULN2003A,单片机是MP9S08MP16CLC。电路原理图如下(J1的6、7、8脚本例中未使用):

MP16Step

下面是完整程序:

#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;
  }
}