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次速度的平均
}
} 你的测速方法比较奇怪,T/C0到底如何工作?计数方式吗,与OCR1A有什么关系?
我的书上有采用T/C的输入捕捉功能测周期的例子,只要采用一个T/C 就能完成周期的测量,你可以参考。
标准51架构的MCU,定时器没有捕捉功能,需要采用2个定时器完成频率或周期的测量。而新的单片机,包括许多改进的51架构单片机,其T/C都具备捕捉功能的。要学习使用新的方法。
你的程序属于书生型的,学校版的,实际应用中会出很多的问题。
比如乘10和除10,可能都是多余的。如果只是为了显示,只要人为的把小数点向前提一位显示就可以了。
乘除计算,需要几倍的时间,会与测量部分造成冲突和影响,使得频率或周期测量不准确。 马老师,你好!我采用T0脉冲计数,T1发PWM,电机要求3500内转速都可调。 我用的T/c2定时,用T/C1/T/C0/和外部中断计数,为什么会出现跳变
页:
[1]