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

📄 tim.c

📁 motorola mc9s12dg128 uCOS的实现
💻 C
字号:
#include "main.h"
//-*----------------------------------------------------*-//
//前一部分实现TIM通道7脉宽测量
//-*----------------------------------------------------*-//
uint  TIM0;		            //用于记录速度信号的第一个上升沿的捕捉值
uint  PWM_TIM_first_tcnt; //当需要溢出计数时,保存TCNT值
uchar PWM_TIM_over_flag=0;//定时器中自由计数器溢出处理标志
ulong Tim_number;					//定时器需要计数的个数
//-******************初始化定时器TIM**********************************************-//
void Init_TIM(void) 
{
  TSCR1_TEN=1;							 //Timer Enable
  TIE|=0x80;                  //允许TIM1、TIM7通道的定时器中断
  //TIE_C1I=1;								 //允许TIM1
  TIOS_IOS1=1;
  TCTL2_OM1=1;
  TSCR2=0x07;                //Timer Clock Selection:Bus Clock / 128
  TSCR2_TOI=1;							 //Timer Overflow Interrupt Enable
  //PACTL=0x08;							//Use PACLK/256 as timer counter clock frequency 
  TSCR1_TFFCA=1;						 //快速清除中断标志允许 
}
//-************************************************************-//
//实现6个数中,去掉最大值,去掉最小值,剩下的4个取平均送出
void average(void) {
uchar max,min;
ulong TIM_average_;
uchar i;
TIM_average_=0;
min=0; //(long)TIM_old_num[m][5]*65536+(long)TIM_old[m][5]
max=5;
 for(i=0;i<6;i++) 
 {
      if(TIM_old_num[max]<TIM_old_num[i])	 {max=i;} 
      else if((TIM_old_num[max]==TIM_old_num[i])&&(TIM_old[max]<TIM_old[i]))
      {max=i;}
      
      if(TIM_old_num[min]>TIM_old_num[i])	 {min=i;}
      else if((TIM_old_num[min]==TIM_old_num[i])&&(TIM_old[min]>TIM_old[i]))
      {min=i;}

 }/**/
    
    
 for(i=0;i<6;i++)
 {
      if(i!=max&&i!=min)       
      {
        TIM_average_+=(ulong)(TIM_old_num[i])*65536+(ulong)TIM_old[i];
      }
 }
    TIM_average_>>=2;
    TIM_average=(uint)TIM_average_;
    TIM_average_num=(char)(TIM_average_>>16);
}
//-************************************************************-//
void TIM_back(void)		 //C为移TIM中的第几行 
{
  char i;
  for(i=5;i>0;i--)												 //实现5位向后都移一位
  {
    TIM_old[i]    =TIM_old[i-1];
    TIM_old_num[i]=TIM_old_num[i-1];    
  }
}
//-************************************************************-//
void speeds(void)     //这个程序一定要用到中断才行
{                      //当计时器从0000->FFFF没有上升沿OR只有一个上升沿

     TIM_back();
     TIM_flag.tim0=0;
     TCTL3_EDG7A=1;
}
void PWM_delay(ulong Tim_num) 
{
  if(Tim_num<65536)		
  {     
	 
     TC1=(int)(Tim_num+TCNT);
     //TIOS_IOS1=1;
     TIE_C1I=1;        //允许TIM通道1中断
     PWM_TIM_over_flag=0;
  }
  else
  {
    PWM_TIM_over_flag=1;
    PWM_TIM_first_tcnt=TCNT;
    Tim_number=Tim_num;
  }
}
//-*----------------------------------------------------*-//
//这一部分实现PWM发送100Hz的高电平时间可调的脉冲
//-*----------------------------------------------------*-//
void Init_PWM(void)
{ 
  PWMPRCLK=0;          //A时钟总线=总线频
  PWMSCLA=120;				 //Clock SA = Clock A / (2 * PWMSCLA)
  PWMSCLB=120;				 //Clock SA = Clock A / (2 * PWMSCLA)

  PWMCLK=0x00;	      //CLOCK A FOR pwm5,clock B for pwm3
  PWMCLK_PCLK1=1;			//选择SB
  
  PWMPER01=1000; 			 //
  //PWMSCLA=pwm_scla;  //CLOCK SA=CLOCK A/(2*PWMSCLA),2分频
  PWMPOL_PPOL1=1;			 //用于发送伺服电机的脉冲,pwm1开始输出为高
  PWMCTL_CON01=1;     //通道0和1连接组成一个16位pwm控制口
   
  PWMPOL_PPOL3=0;			 //用于控制电机的正反转
  PWMPOL_PPOL7=0;      //pwm开始输出为低,因为经过光耦输出为高
  PWMCLK_PCLK3=1;
  PWMCLK_PCLK7=1;			 //选择SA
  PWMPER67=200;
  PWMPER23=200;
  PWMCTL_CON67=1;   //通道6和7,通道2和3连接组成一个16位pwm控制口
  PWMCTL_CON23=1;   //通道2和3连接组成一个16位pwm控制口
 
   
  PWMCAE=0x00;      //左对齐
}
//////////////////////////////////////////
//发送SERVO电机的脉冲,第一个参数是脉冲个数,第二个参数高电平时间 
//////////////////////////////////////////
void Servo_pulse(uint num,uint tim) 			//tim=1表示0.01ms,最大不超过1000,也就是10ms
{
  ulong temp;
  temp=Tim_speed_001*num;
  PWMDTY01=tim;
  PWME_PWME1=1;
  PWM_delay(temp);  
}
//////////////////////////////////////////
//     主驱动电机的前进驱动程序 
//////////////////////////////////////////
void DC_motor_forward(uint duty) 					//duty的范围(0-200)
{
  PWME_PWME3=0;
  DDRP_DDRP3=1;
  PTP_PTP3=1;
  PWMDTY67=duty;  
  PWME_PWME7=1;
}
//////////////////////////////////////////
//     主驱动电机的刹车驱动程序 
//////////////////////////////////////////

void DC_motor_brake(uint duty,uint tim)	 //duty的范围(0-200)PWM高电平时间
{																				 //tim的范围(0-600)即为(0-6S)
  PWME_PWME7=0;													 //tim=100表示刹车1秒
  DDRP_DDRP7=1;
  PTP_PTP7=1;
  PWMDTY23=duty;  
  PWME_PWME3=1;
  delay(100*tim);
}
//-************************************************************-//
//        下面为定时器中断函数
//-************************************************************-//
#pragma CODE_SEG __NEAR_SEG  NON_BANKED
void interrupt 15 TM7(void) //定时器7通道检测车速信号
{														//连续两个上升沿的中断程序
if(TIM_flag.tim0<7)			//
   {                      
   if(!TIM_flag.t0) 				
     {													
        TIM0=TC7;							
        TIM_flag.t0=1;						
        TIM_flag.tim1=0;
     }
   else             
     {  
        ulong temp=0;
        TIM_flag.t0=0;
        temp=(ulong)(TIM_flag.tim1)*65536+(ulong)TC7-(ulong)TIM0;
        TIM_old[0]=(int)temp;
        TIM_old_num[0]=(char)(temp>>16);
        TCTL3_EDG7A=0;			//禁止PT0的捕捉
        TIM_flag.tim0=0;
        average();
      }
   }
else 
      {
        TIM_old[0]=TC7;		 //清中断标志
        TIM_old[0]=0xFFFF;
        TIM_old_num[0]=7;
        average();
        TIM_flag.t0=0;
        TIM_flag.tim0=0;       
        TCTL3_EDG7A=0;			 //禁止PT0的捕捉
      }
 			if(!TIM_flag.t0)
 			{
 			  put_word(TIM_average);
 			  put_char(TIM_average_num);
 			}
}
//-************************************************************-//
//      这个中断用于记录TCNT的溢出次数        
//-************************************************************-//
void interrupt 16 TM(void)
{
  int m;
  //TIM的7通道用于车速的检测
  if(TIM_flag.t0&&TIM_flag.tim1<7) TIM_flag.tim1++;
  else
  {
    if(TIM_flag.tim0<7) TIM_flag.tim0++;
    else if(TCTL3_EDG7A)  
    {
      TIM_old[0]=0xFFFF;
      TIM_old_num[0]=7;
      average();
      TCTL3_EDG7A=0;
    }		              //此处是为了保证启动捕捉后,
  }			              //TCNT溢出7次后一个上升沿都未出现的情况
  
  /////////TIM的1通道用于定时SERVO脉冲发送个数///////////////////    
  if(PWM_TIM_over_flag) 
  {
    if(PWM_TIM_over_flag==1)
    {
      PWM_TIM_over_flag=2;
      Tim_number=Tim_number+PWM_TIM_first_tcnt-65536;
      if(Tim_number<65536) 
      {
        TC1=TCNT+(uint)Tim_number;
        TIE_C1I=1;	   //允许TIM通道1中断
        PWM_TIM_over_flag=0;
      }
    } 
    else 
    {
       Tim_number=Tim_number-65536;
       if(Tim_number<65536) 
       {
         TC1=TCNT+(uint)Tim_number;
         TIE_C1I=1;	   //允许TIM通道1中断
         PWM_TIM_over_flag=0;
       }
       
    }
  } 
  /////////////////////////////////////////////////
  m=TCNT;             //清TCNT的溢出标志
}
//-*********定时器1中断**************************-//
void interrupt 9  servo_pulse(void) 			//定时器1通道定时时间到
{																					//关断SERVO的脉冲发送
  TC1=1;																	//中断函数
  PWME_PWME1=0;
  TIE_C1I=0;	   //禁止TIM通道1中断
  TIOS_IOS1=0;
}
#pragma CODE_SEG default









⌨️ 快捷键说明

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