📄 tim.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 + -