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

📄 9s12forpwm.c

📁 此程序是用9s12单片机控制直流电机的控制程序
💻 C
📖 第 1 页 / 共 2 页
字号:
 /*=========================== =====================

 接通无线接收,程序不执行
   但若是先上电,再接通无线模块,可以执行
   如下:D=1 B=2 A=3 C=4
        
   
 ===================================================*/
#include <hidef.h>      /* common defines and macros */
#include <mc9s12dg128.h>     /* derivative information */


#pragma LINK_INFO DERIVATIVE "mc9s12dg128b"

 /************************************************
  宏定义
 ************************************************/
#define RTIPRESCALER   0x63//24000000/4*2^15=183hz
#define GETCOMWAY 0 //1---getcommand from the rs232
                    //0---getcommand from the wilesskey
                    
#define INPORT PORTA
#define PORTAND 0xf0

#define STOP 0X00
#define FORWARD 0X02
#define BACK 0X03
#define LEFT 0X01
#define RIGHT 0X04
#define SPEEDUP 0X05
#define SLOWDOWN 0X06

#define NOMALSPEED 0XB0



/*==============================================
全局变量定义
========================================*/                     
unsigned char command,commandpre;

unsigned char PWMPer;
unsigned char PWMhalfdty;

unsigned char startflag,startstep;


/****************************************
函数声明
*******************************************/
 // void delay_1ms(void);
 // void delay(unsigned char strval);
  
  void PWMInit(void);
  void PWMInit1(void);
  void PWMInit2(void);
  
  void  stop();
  void softstart();
  void speedup();
  void slowdown();
  void turnR(void);
  void turnL(void);
  
  void SCI_ini(void);
  unsigned char get_char(void);
  void put_char(unsigned char c);
  
  void SET_PLL(void);
  void IOInit(void);
  
  unsigned char get_command(void);
  void com_translate(void);
  
  void RTIConfig(void);
 /************************************************
 初始化系统
 ************************************************/
 ////////////////////////////////////////////////
  void RTIConfig(void)
{
    RTICTL = RTIPRESCALER; /* set RTI prescaler */
    CRGINT = 0x80; /* enable RTI interrupts */
    return;
}
//////////////////////////////////////////////////
void IOInit(void){

    DDRB = 0xff;
    PORTB=0xff;
    DDRA = 0x00;

}
//////////////////////////////////////////////////
void SET_PLL() //通过设置五个寄存器
{CLKSEL=0x00;
 PLLCTL=0xe1; //pll control reg
 SYNR=2;     //时钟合成寄存器 00-63
 REFDV=1;    //时钟分频寄存器 00-15     PLLCLK=2*OSCCLK*(SYNR+1)/(REFDV+1)
              //=48MHZ     BUS CLOCK=0.5*CORE CLOCK=24MHZ 
 PLLCTL=0x60;
 asm NOP;
 asm NOP;
 asm NOP;
 while(0==(CRGFLG&0x08)); //JUDGE THE LOCK BIT, =1 CLOCK STABLE
 CLKSEL=0x80; //SELECT PLL clock
}


//////////////////////////////////////////////////
void PWMInit(void){
			 PWMPRCLK=0x02;
     // PWMPRCLK=0x01;  //pwm预分频时钟寄存器 clockA pwm0\1\4\5 为4 时 即 A=24M/16=1.5M Hz 总线预分频
     // PWMCLK=0x13;    //时钟选择寄存器 1使用Clock SA  0使用Clock A
      PWMCLK=0x00;
      //PWMSCLA=0x01;   //PWM比例因子寄存器 ClockSA=ClockA/(2*PWMSCLA)=150K Hz  period=1/150k=6.66us
      PWMPER0=0x80; //pwm 通道周期寄存器 周期为256
      PWMPER1=0x80;	 //output wave period: channelCloclPeriod * PWMPWEERx 
      PWMPER4=0x80;	 //here output period= 6.66us*255=1.7ms THE MAX period   0.6k-150k
  
      PWMPOL=0x13;    //极性位pwm0\1\4 首先输出高电平 占空比计数器计数完毕后变为低电平
      PWMDTY0=0x00; 		//极性位为1时 PPOLx=1 DutyCycle=[PWMDTYx/PWMPERx]*100%
      PWMDTY1=0x00;
      PWMDTY4=0x00;
      PWME=0x13;	   //允许寄存器 为1时允许 pwm0\1\4

}

///////////////////////////////////////////////////////
void PWMInit2(void)
{	  PWMPRCLK=0x00; //24M
    PWMCLK=0x00;
    PWMPOL=0x13;
    PWME=0x13;	    
}
///////////////////////////////////////////////////////
void PWMInit1(void)
{	  PWMPRCLK=0x03; //24M/2/2/2=3M
    PWMCLK=0x00;    //时钟选择寄存器 1使用Clock SA  0使用Clock A
    //PWMSCLA=0x05;   //PWM比例因子寄存器 ClockSA=ClockA/(2*PWMSCLA)=150K Hz  period=1/150k=6.66us
    PWMPOL=0x13;
    PWME=0x13;	    
}
////////////////////////////////////////////////////////
void SCI_ini(void) {
  SCI0CR2=0x0c;
  SCI0BDH=0x00;
  SCI0BDL=0x9C;
 }
 
 


 
 /************************************************
 用户函数区
 ************************************************/
 void delay_1ms()
  {	 unsigned int m,n;
     for(m=0;m<49;m++)
        for(n=0;n<100;n++)
           ;
  }
 //////////////////////////////////////////////////////
 unsigned char get_char(void){
  
  while((SCI0SR1&0x20)==0){
  }
  return(SCI0DRL);
}

 ////////////////////////////////////////////////////
void put_char(unsigned char c){

     while((SCI0SR1&0x80) == 0){}
     SCI0DRL = c;
} 
///////////////////////////////////////////////////////
unsigned char get_command(void)
{	 unsigned char comtemp;
  if(GETCOMWAY)
   {
   	 comtemp=getchar();
     return comtemp;
   }
   
  else
    {		comtemp=INPORT;
        comtemp=comtemp&PORTAND;
        return comtemp;
      
    }
}

///////////////////////////////////////////////////////////
 void com_translate(void)
 {
 
      switch(command)
      {
        case 0x00:
           command=0;
           break;
        case 0x10:
           command=1;	 //d
           break;
        case 0x20:
           command=2;	 //B
           break;
        case 0x40:
           command=3;	 //A
           break;
        case 0x80:			 //C
           command=4;
           break;
        case 0x30:			 //D B
           command=5;
           break;
        case 0xC0:			 //A C
           command=6;
           break;      
        default:
           command=0;
           break;   
      }
 }

 


 /************************************************
 
 ************************************************/

void main(void)
 {
      SET_PLL();   //BUS CLOCK=24MHZ
  	 
   		IOInit();
   		RTIConfig();
   		PWMInit();
      SCI_ini();
      
  EnableInterrupts;
  
  
  
      delay_1ms();
      
      
      put_char(0xff);
      put_char(0xff);
      
      delay_1ms();
      
     // PORTB=0xff;
      
      delay_1ms();
      
     while(1)
     {	
        command=get_command();
        com_translate();
        
        put_char(command);
        
        
        
     
     }
 
}

 /************************************************
 中断服务程序
 ************************************************/
#pragma CODE_SEG __NEAR_SEG  NON_BANKED
/*
* RTIIsr: Interrupt Service routine for the RTI.
* Clear RTI flag

* Reset RTI counter to restart cycle
*
* Parameters: None
*
* Return : None
*/
interrupt 7 void RTIIsr(void) 
{
CRGFLG = 0x80; /* clear RTIF bit */

switch(command)
{ //////////////////////////////////////////////////////////////////
  case STOP:
         PWMDTY0=0;
         PWMDTY1=0;
         PWMDTY4=0;
         
         startflag=0;
         startstep=0;
         break;
  ///////////////////////////////////////////////////////////////////       
  case FORWARD:
          PORTB=PORTB|0X03;
          
          if(commandpre==FORWARD)  //正常启动或前进
          {  if(startflag==0x01)//starting...
                {
                   if(startstep==1)
                   {   PWMPer=PWMPer-2;

⌨️ 快捷键说明

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