⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 新建 文本文档.txt

📁 DSP 产生PWM波控制直流电机
💻 TXT
字号:
#include "SEED-DSK2407.h" 
#include "comm.h"

/*电机驱动码*/
//步进电机,四相四拍
/* 全步反转*/
unsigned int motorstepall[48] ={8,2,4,1,\
         8,2,4,1,\
         8,2,4,1,\
         8,2,4,1,\
         8,2,4,1,\
         8,2,4,1,\
         8,2,4,1,\
         8,2,4,1,\
         8,2,4,1,\
         8,2,4,1,\
         8,2,4,1,\
         8,2,4,1};
/*全步正转*/
unsigned int motorstepalln[48]={8,1,4,2,\
         8,1,4,2,\
         8,1,4,2,\
         8,1,4,2,\
         8,1,4,2,\
         8,1,4,2,\
         8,1,4,2,\
         8,1,4,2,\
         8,1,4,2,\
         8,1,4,2,\
         8,1,4,2,\
         8,1,4,2}; 
//四相八拍                   
/*半步正转*/        
unsigned int motorstephalfn[96] ={8,0xa,2,6,4,5,1,9,\
         8,0xa,2,6,4,5,1,9,\
         8,0xa,2,6,4,5,1,9,\
         8,0xa,2,6,4,5,1,9,\
         8,0xa,2,6,4,5,1,9,\
         8,0xa,2,6,4,5,1,9,\
         8,0xa,2,6,4,5,1,9,\
         8,0xa,2,6,4,5,1,9,\
         8,0xa,2,6,4,5,1,9,\
         8,0xa,2,6,4,5,1,9,\
         8,0xa,2,6,4,5,1,9,\
         8,0xa,2,6,4,5,1,9};
/*半步反转*/
unsigned int motorstephalf[96]={8,9,1,5,4,6,2,0xa,\
         8,9,1,5,4,6,2,0xa,\
         8,9,1,5,4,6,2,0xa,\
         8,9,1,5,4,6,2,0xa,\
         8,9,1,5,4,6,2,0xa,\
         8,9,1,5,4,6,2,0xa,\
         8,9,1,5,4,6,2,0xa,\
         8,9,1,5,4,6,2,0xa,\
         8,9,1,5,4,6,2,0xa,\
         8,9,1,5,4,6,2,0xa,\
         8,9,1,5,4,6,2,0xa,\
         8,9,1,5,4,6,2,0xa};       

#define pwm_value   50
#define pwm_max     500
/*初始化宏定义*/
#define TESTCOMMAND 6 ////电机设置宏定义
unsigned int TestCommand;   
      
unsigned int dcmotor_level = 0; 
unsigned int dcmotor_count = 0;
unsigned int step_point = 0; 
unsigned int step_mode = 0;
unsigned int step_dir   = 0;
unsigned int step_half = 0;
unsigned int step_speed = 0;
unsigned int dcmotor_dir = 0;
unsigned int dcmotor_speed = 0;

unsigned int step_count = 0; 
unsigned int step_clockwise = 0;/* 初始值为0 ,顺时针 */

volatile unsigned int motorset[6] ={0,0,0,40,0,200};


void blink(); 
void timer1_set(unsigned int timer1_period);
void timer2_set(unsigned int timer2_period); 
void dc_motor_clockwise();
void dc_motor_anticlockwise();
void dc_motor_stop(); 
void step_motor(unsigned int step);
void step_motor_stop();
/*void sci_set(); */

void sys_reset(void);
void timer_init();


void main()
{   
    unsigned int i=0;
    unsigned int j=0; 
    #if TESTCOMMAND==1
    TestCommand =MTRCONFIG;//电机设置0xAA3C
#endif
#if TESTCOMMAND==2
TestCommand =DCMTRRUN;//直流电机运行0xAA28
#endif
#if TESTCOMMAND==3
TestCommand =DCMTRRVS;//直流电机反向0xAA3B
#endif
#if TESTCOMMAND==4
TestCommand =DCMTRBRK;//直流电机刹车0xAA39
#endif
#if TESTCOMMAND==5
TestCommand =DCMTRSLWDWN;//直流电机缓停 0xAA3A
#endif
#if TESTCOMMAND==6
TestCommand =STPMTRRUN;//步进电机运行0xAA25
#endif
#if TESTCOMMAND==7
TestCommand =STPMTRRVS;//步进电机反向0xAA26
#endif
#if TESTCOMMAND==8
TestCommand =STPMTRHALT;//步进电机停止0xAA24
#endif
#if TESTCOMMAND==9
TestCommand =SYSRESET;//系统复位
#endif


    DINT; //禁止可屏蔽中断
    /*wait-state*/ 
    WSGR      = 0xdb; //不懂
    /* forbid watchdog*/
    *WDCR     = 0x68;
    *SCSR1    = 0x02c; //系统控制和状态寄存器1(p41),使能SPI.EVA,EVB模块时钟 
    *IFR      = 0x3f; //中断标志寄存器,写1清除中断标志位
    *IMR      = 0x00; //中断屏蔽寄存器,写0屏蔽中断

    /*WHEN THE MOTOR PROGRAM RUN ,TURN ON THE LED2*/
    *MCRC     &= 0xBFFF; //IO复用输出控制寄存器C,MCC.14=0,IOPF6
    *PFDATDIR |=0x4040; //端口F数据和方向控制寄存器,IOPF6设置为输出,且引脚为高电平
    
    timer_init(); 
    timer1_set(0x1F);
    timer2_set(0xFFFF); 
    EINT;//使能可屏蔽中断
   
/*drive the LED blink*/
for(;;)
{   
        switch(TestCommand)
     {
     
     case STPMTRHALT: /*0XAA24*/
           *IMR &= 0xFB; //屏蔽int3中断
           step_count=0;
           step_motor_stop();
           break; 
     case STPMTRRUN:   /*0XAA25*/
           *IMR |= 0x04;使能int3中断           
           break;     
     case STPMTRRVS:   /*0XAA26*/
           if(step_dir==STEP_CLOCKWISE)
           { 
             /* step_motor_stop();*/
              step_point=0; 
              step_count=0;
           step_dir=STEP_ANTICLOCK; 
           } 
           else
           { 
             /* step_motor_stop(); */
              step_point=0; 
              step_count=0;
           step_dir=STEP_CLOCKWISE; 
           } 
           break;    
     case DCMTRRUN:    /*0XAA28*/
           *IMR |= 0x02;//使能int2中断           
           break;     
     case DCMTRBRK:    /*0XAA39*/
           *IMR &= 0xFD;//屏蔽int2中断
           dc_motor_stop();
           break;     
     case DCMTRSLWDWN: /*0XAA3A*/
           *IMR &= 0xFD;//屏蔽int2中断
           dc_motor_stop();
           break; 
     case DCMTRRVS:    /*0XAA3B*/
          /* *IMR |= 0x02;*/
           if(dcmotor_dir==CLOCKWISE)
           {
           dcmotor_dir=ANTICLOCKWISE; 
           }
           else
           {
           dcmotor_dir=CLOCKWISE; 
           }
           break; 
     case MTRCONFIG:   /*0XAA3C*/

    step_mode     = motorset[0];
     step_dir      = motorset[1];
     step_half     = motorset[2];
     step_speed    = motorset[3];
     dcmotor_dir   = motorset[4];
     dcmotor_speed = motorset[5]; 
     dcmotor_count = 0;
     dcmotor_level = 0;
     step_count=0;
     step_point=0;
/*     *IMR |= 0x02; */
           break;
     case MOTOREND:
           *IMR &= 0xF9;
           dc_motor_stop();
           step_motor_stop();
           break; 
     case SYSRESET:
           *IMR &= 0xF9; 
           timer_init();
           dc_motor_stop();
           step_motor_stop();
           sys_reset();
           break;                                         
                                 
     default:
           break;      
     }
       
}

}

/*TIMER1 INTERRUPT,DC MOTOR CONTROL   */
interrupt void c_int2(void)
{   
    DINT;       
if((*PIVR & 0x27) == 0x27)
{
  
  
   if(dcmotor_level == 0)
     { 
          dcmotor_count++;
          //timer1_set(0x1F);
     // 电机方向判断
        if(dcmotor_dir==CLOCKWISE)
         {
              dc_motor_clockwise();
         }
     if(dcmotor_dir==ANTICLOCKWISE)
     {
        dc_motor_anticlockwise();
     }               
     // 电平变低 
   if(dcmotor_count==dcmotor_speed)
   { 
    dcmotor_level = 1;
   }  
} 
if(dcmotor_level == 1)
{ 
     if(dcmotor_count<500)
     {
     dcmotor_count++;
     //timer1_set(0x1F);
     dc_motor_stop();
     } 
   if(dcmotor_count==pwm_max)
   { 
    dcmotor_level = 0;
    dcmotor_count = 0;
   }  
      
     } 
     *EVAIFRA = 0x0080;
}

*IFR &= 0x0002;
*IMR |= 0x01;
EINT;
}

/*TIMER2 INTERRUPT,STEP MOTOR CONTROL*/
interrupt void c_int3(void)
{
if((*PIVR & 0x2b) == 0x2b)
{
   *EVAIFRB = 0x0001;
}
if(step_mode==ROTATE)
{ 
   step_count++;
   if(step_count==step_speed)
   {   
     /* 全步正转*/
    if(step_dir==STEP_CLOCKWISE && step_half==FULLSTEP) 
     {
     step_motor(motorstepalln[step_point]);
     step_point++;
     if(step_point==48)
     {
      step_point=0;
     }
    } 
    /* 全步反转 */
    if(step_dir==STEP_ANTICLOCK && step_half==FULLSTEP) 
     {
     step_motor(motorstepall[step_point]);
     step_point++;
     if(step_point==48)
     {
      step_point=0;
     }
    }
    /* 半步反转 */
    if(step_dir==STEP_ANTICLOCK && step_half==HALFSTEP) 
     {
     step_motor(motorstephalfn[step_point]);
     step_point++;
     if(step_point==96)
     {
      step_point=0;
     }
    }
    /*   半步正转 */
    if(step_dir==STEP_CLOCKWISE && step_half==HALFSTEP) 
     {
     step_motor(motorstephalf[step_point]);
     step_point++;
     if(step_point==96)
     {
      step_point=0;
     }
    }  
    step_count=0;
      }
}
if(step_mode==LOCATE)
{
step_count++;
   if(step_count==step_speed)
   {   
     /* 全步正转*/
    if(step_dir==STEP_CLOCKWISE && step_half==FULLSTEP) 
     {
     step_motor(motorstepall[step_point]);
     step_point++;
     if(step_point==step_speed)
     {
      step_point=0; 
      *IMR &= 0xFB;
      step_motor_stop();
     }
    } 
    /* 全步反转 */
    if(step_dir==STEP_ANTICLOCK && step_half==FULLSTEP) 
     {
     step_motor(motorstepalln[step_point]);
     step_point++;
     if(step_point==step_speed)
     {
      step_point=0;
      *IMR &= 0xFB;
      step_motor_stop();
     }
    }
     /* 半步反转 */
    if(step_dir==STEP_ANTICLOCK && step_half==HALFSTEP) 
     {
     step_motor(motorstephalfn[step_point]);
     step_point++;
     if(step_point==step_speed)
     {
      step_point=0;
      *IMR &= 0xFB;
      step_motor_stop();
     }
    }
    /*   半步正转 */
    if(step_dir==STEP_CLOCKWISE && step_half==HALFSTEP) 
     {
     step_motor(motorstephalf[step_point]);
     step_point++;
     if(step_point==step_speed)
     {
      step_point=0;
      *IMR &= 0xFB;
      step_motor_stop();
     }
    }  
    step_count=0;
   }      
}    
*IFR &= 0x0004;
EINT; 
}        


/*sci set*/
/*void sci_set()
{    
*MCRA    |= 0x03;
*SCICCR   = 0x07; /*loopback mode:0x17 ;normal:0x07 1 stop bit,odd parity,8 char bits*/
/* *SCICTL1 = 0x03;
*SCICTL2 = 0x02;
*SCIHBAUD = 0x01;
*SCILBAUD = 0x03; /*Baud Rate=19200 b/s (40 MHz SYSCLK)*/
/* *SCICTL1 = 0x23;
*IMR     |= 0x01;
} */           

void timer_init()
{
*IMR &= 0xF9; //使能INT2,INT3中断
*GPTCONA = 0x0000; //初始化全局通用定时器控制寄存器A
     *EVAIMRA = 0x0000; // 初始化EVA中断屏蔽寄存器A
     *EVAIMRB = 0x0000;// 初始化EVA中断屏蔽寄存器B
     *EVAIFRA = 0x0080;// 初始化EVA中断标志寄存器A,复位通用定时器1的周期中断标志
*EVAIFRB = 0x0001;// 初始化EVA中断标志寄存器B,复位通用定时器2的周期中断标志
   
     *T1CNT   = 0; //初始化定时器计数寄存器1
*T1CON   = 0; //初始化定时器控制寄存器1
*T2CNT   = 0;
*T2CON   = 0;              

}
/*timer1 set */
void timer1_set(unsigned int timer1_period)
{
*GPTCONA = 0x0000; 
*T1CNT   = 0;
*T1CON   = 0x1740; // free,soft 00,仿真挂起时立即停止
        // tmode1,tmode0 10 ,连续增计数模式
        // tps2-tps0,111 ,输入时钟定标器,x/128
        // tenable 1,允许定时器操作
        // tclks1,tclks0 00,内部时钟
        //tcld1,tcld0 00 ,计数器的值为0时重载
        // tecmpr,0 禁止定时器比较操作

*T1PR    = timer1_period; //定时器1的周期寄存器
*T1CMPR = 0x3fff; 
*EVAIFRA = 0x0080;
*EVAIMRA = 0x0080;
/* *IMR    |= 0x0002; */ 
} 
/*timer2 set */
void timer2_set(unsigned int timer2_period)
{
*GPTCONA = 0x0000; 
*T2CNT   = 0;
*T2CON   = 0x1040; 
*T2PR    = timer2_period; 
*T2CMPR = 0x3fff; 
*EVAIFRB = 0x0001;
*EVAIMRB = 0x0001;
/* *IMR    |= 0x0004;*/ 
}         

/*dc_motor clockwise turn*/
/*这里的直流电机没有实用pwm,只是使用了I/O复用输出IOPB5,IOPB4两个口,来驱动此直流电机*/
void dc_motor_clockwise()
{
*MCRA        &= 0xCFFF; /*I0PB4,IOPB5*/ 
*PBDATDIR    |= 0x3020; //IOPB5,IOPB4输出,IOPB5高电平
*PBDATDIR    &= 0xFFEF; //   IOPB4低电平
}            
/*dc_motor anticlockwise turn*/
void dc_motor_anticlockwise()
{
*MCRA        &= 0xCFFF;   /*I0PB4,IOPB5*/ 
*PBDATDIR    |= 0x3010; //IOPB5,IOPB4输出,IOPB4高电平
*PBDATDIR    &= 0xFFDF; //   IOPB5低电平
}
/*dc_motor stop*/
void dc_motor_stop()
{
*MCRA        &= 0xCFFF; 
*PBDATDIR    &= 0xFFCF; //IOPB5,IOPB4为高电平,导通截止,所以电机停止转动
}                  

/*step_motor run*/
//在这里电机也没有实用pwm,
//而是使用IOPB1,IOPB0,IOPA7,IOPA6四个io口,轮流输出高电平,产生磁场,从而使电机转动
void step_motor(unsigned int step)
{
switch(step)
{
   case 8:
    *MCRA        &= 0xFC3F;// IOPB1,IOPB0,IOPA7,IOPA6
    *PADATDIR    |= 0xC000;// IOPA7,IOPA6输出
    *PADATDIR    &= 0xFF3F;// IOPA7,IOPA6低电平
    *PBDATDIR    |= 0x0302;// IOPB1,IOPB0输出,IOPB1高电平   
    *PBDATDIR    &= 0xFFFE; // IOPB0低电平
    break;
   case 4:
    *MCRA        &= 0xFC3F;// IOPB1,IOPB0,IOPA7,IOPA6
    *PADATDIR    |= 0xC000;// IOPA7,IOPA6输出
    *PADATDIR    &= 0xFF3F;// IOPA7,IOPA6低电平
    *PBDATDIR    |= 0x0301;// IOPB1,IOPB0输出,IOPB0高电平   
    *PBDATDIR    &= 0xFFFD;// IOPB1低电平
    break;
   case 2:
    *MCRA        &= 0xFC3F;// IOPB1,IOPB0,IOPA7,IOPA6
    *PADATDIR    |= 0xC080;// IOPA7,IOPA6输出,IOPA7为高电平
    *PADATDIR    &= 0xFFBF;// IOPA6为低电平   
    *PBDATDIR    |= 0x0300;// IOPB1,IOPB0输出
    *PBDATDIR    &= 0xFFFC;// IOPB1,IOPB0低电平
    break;
   case 1:
    *MCRA        &= 0xFC3F;// IOPB1,IOPB0,IOPA7,IOPA6
    *PADATDIR    |= 0xC040;// IOPA7,IOPA6输出,IOPA6为高电平
    *PADATDIR    &= 0xFF7F;// IOPA7为低电平    
    *PBDATDIR    |= 0x0300;// IOPB1,IOPB0输出
    *PBDATDIR    &= 0xFFFC;// IOPB1,IOPB0低电平
    break; 
   default:
      break;      
}
  
} 
/*step motor stop*/
void step_motor_stop()
{
*MCRA        &= 0xFC3F;// IOPB1,IOPB0,IOPA7,IOPA6
*PADATDIR    |= 0xC000;// IOPA7,IOPA6输出
*PADATDIR    &= 0xFF3F;//IOPA7,IOPA6低电平   
*PBDATDIR    |= 0x0300;// IOPB1,IOPB0输出
*PBDATDIR    &= 0xFFFC;// IOPB1,IOPB0低电平 
}
/*LED BLINK DELAY*/
void DELAY()
{
unsigned int j = 0;
int i = 0;
for(i = 0; i <0xff;i++)
{
   for(j = 0;j<0x3ff;j++)
   {
    asm("NOP");
   } 
}
}


void sys_reset(void)
{
WSGR = 0; 
*WDCR = 0x08;
for(;;){};
/*
asm(" B 768H "); */
}     

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -