lvjun1013 发表于 2012-2-14 22:09:53

MEGA16 计数器0出现问题,有规律,2分10秒跳变?无刷直流电机,麻烦高手帮忙解决

问题如题,外部8MHZ,如果函数信号发生器或者另外的MEGA16发出来的固定PWM,电机不会出现跳变,但是我显示的速度值还是会出现跳变,所以我就怀疑计数器0这边有问题
部分程序如下:
void Timers_Initial(void)
{
// Timer/Counter0
OCR0 = 0xff;//
TCNT0 = 0x00;
TCCR0 = 0x07; //
   
TCNT1H = 0x00;
TCNT1L = 0x00;
ICR1H = (4000>>8)&0xff;//最大10000,先写高字节,再写低字节
ICR1L = 4000&0xff;
OCR1AH = 0x00;
OCR1AL = 0x00;   
TCCR1A = (1<<COM1A1)|(1<<WGM11);
TCCR1B = (1<<WGM13)|(1<<WGM12)|(1<<CS10);

//T/C2初始化    2ms
ASSR = 0x00;
TCNT2 = 0x00;//
OCR2 = 0x7C;   //
TCCR2 = (1<<WGM21)|(1<<CS22)|(1<<CS20); // CTC 8M/128

TIMSK = 0x80;
}

interrupt void timer2_isr(void)   //2ms
{
static u16 Time2Count=0;

Time2Count++;
Key_Scan();
       
if(Time2Count%50 == 0) //100ms计算一次速度,进行一次PID
{
    gStruMotor.SpeedUpdateFlag = TRUE;// 更新速度标志
    gStruMotor.RealPulse = TCNT0;
    TCNT0 = 0;
    gStruMotor.TimeBuff =gStruMotor.RealPulse;
    gStruMotor.PulseCnt++;
    if(gStruMotor.PulseCnt >= 10)
    {
      gStruMotor.PulseCnt = 0;
    }
}
   
if(Time2Count%250 == 0) //500ms
{   
    gStruLCD.MotorRealSpeedUpdate = TRUE;   更新显示   
    gStruLCD.Flash = ~gStruLCD.Flash;
}       
}

速度更新
void Motor_Event(void)
{
u32 i,temp=0;       
WatchDogFeed();
if(gStruMotor.SpeedUpdateFlag == TRUE)   // 有速度更新
{   
   gStruMotor.SpeedUpdateFlag = FALSE;
   for(i=0;i<10;i++)
   {
       temp += (u32)gStruMotor.TimeBuff;// 10次计数叠加
   }
   gStruMotor.SpeedTemp = (u16)(temp*10);//temp*60*10/10*PHASE_SENSE_SELECT,PHASE_SENSE_SELECT=6(电机一圈6个脉冲)
   if(gStruMotor.Run == TRUE)
   {   
   pwm = Motor_PID(gStruMotor.DesSpeed,gStruMotor.SpeedTemp);
   if(pwm>4000)pwm=4000;
   else if(pwm<=0)pwm=0;
   OCR1AH = pwm>>8;   // 计算得到的PWM值,改变占空比
   OCR1AL = pwm&0xff;   
   }
   temp = gStruMotor.SpeedTemp;
   for(i=9; i>0; i--)
   {
   gStruMotor.SpeedTemp = gStruMotor.SpeedTemp;
   temp += (u32)gStruMotor.SpeedTemp;
   }
   gStruMotor.CurSpeed = (u16)(temp/10); // 10次速度的平均
}
}

machao 发表于 2012-2-16 18:50:17

你的测速方法比较奇怪,T/C0到底如何工作?计数方式吗,与OCR1A有什么关系?

我的书上有采用T/C的输入捕捉功能测周期的例子,只要采用一个T/C 就能完成周期的测量,你可以参考。

标准51架构的MCU,定时器没有捕捉功能,需要采用2个定时器完成频率或周期的测量。而新的单片机,包括许多改进的51架构单片机,其T/C都具备捕捉功能的。要学习使用新的方法。

你的程序属于书生型的,学校版的,实际应用中会出很多的问题。

比如乘10和除10,可能都是多余的。如果只是为了显示,只要人为的把小数点向前提一位显示就可以了。

乘除计算,需要几倍的时间,会与测量部分造成冲突和影响,使得频率或周期测量不准确。

lvjun1013 发表于 2012-2-20 16:36:31

马老师,你好!我采用T0脉冲计数,T1发PWM,电机要求3500内转速都可调。

lan 发表于 2012-8-16 15:41:54

我用的T/c2定时,用T/C1/T/C0/和外部中断计数,为什么会出现跳变
页: [1]
查看完整版本: MEGA16 计数器0出现问题,有规律,2分10秒跳变?无刷直流电机,麻烦高手帮忙解决