文档库 最新最全的文档下载
当前位置:文档库 › 测速

测速

测速可以分3种:测频法、测周法和测频侧周混合法。这里我只介绍测频法,因为已经用了一个定时器,可以在这个定时器基础上设定时间,程序中T0_count就是时间变量。若要用侧周法,会有一个误差,主要来自定时器的误差。
时间定了后接下来要测脉冲数,可以用计数器或者外部中断,采用计数器比较方便。程序:
if(T0_count>=125)
{
TR1 =0; //关闭计数器
T0_count =0;
int_h =TH1; //T1计数缓冲单元
int_l =TL1;
TH1 =0; //清计数器
TL1 =0;
T1_count =0;
TR1 =1; //开启计数器
}

// Time1中断服务函数
// 对T1溢出产生中断的次数进行计数
// 计满65535,产生一次溢出中断

void timer1() interrupt 3
{
//因为电机转速实际测量中电机转速并不超过65536的计数,所以不会进入中断。不然可以//用一个变量来计数
}

显然转速=(int_h*256+ int_l)/ 125*PWM脉冲周期。
这里有一个误差需要修正,因为进入定时中断需要进行进行压栈等工作所以会有一定误差。摘取进入定时器中断的反汇编程序:
78: void timer0() interrupt 1
79: {
80:
C:0x0250 C0E0 PUSH ACC(0xE0)
C:0x0252 C0D0 PUSH PSW(0xD0)
81: if(temp)
C:0x0254 30.000A JNB temp(0x20.0),C:0261
82: {
83: TH0=time_h_0;
C:0x0257 85088C MOV TH0(0x8C),time_h_0(0x08)
84: TL0=time_l_0;
C:0x025A 850A8A MOV TL0(0x8A),time_l_0(0x0A)
85: temp=0;
C:0x025D C200 CLR temp(0x20.0)
86:}
87: else
C:0x025F 800A SJMP C:026B
88: {
89: TH0=time_h_1;
C:0x0261 85098C MOV TH0(0x8C),time_h_1(0x09)
90: TL0=time_l_1;
C:0x0264 850B8A MOV TL0(0x8A),time_l_1(0x0B)
91: temp=1;
C:0x0267 D200 SETB temp(0x20.0)
92: T0_count++ ;
C:0x0269 050C INC T0_count(0x0C)
93:}
显然在进入中断后首先要进行ACC和PSW压栈,这里需要4个机器周期。接着要判断是否temp==1,用到JNB指令需要2个机器周期。另外还有两个MOV指令。把这些时间算进去后,精度就会比较高。估计在4000hz情况下测到的是4006hz左右,这里的误差可能是中断响应需要一定时间,可以通过加上7、8个机器周期来修正。最后能得到4000hz以内误差只在1hz。

相关文档