引自百度知道:
速度测量是工控系统中最基本的需求之一,最常用的是用数字脉冲测量某根轴的转速,再根据机械比、直径换算成线速度。脉冲测速最典型的方法有测频率(M法)和测周期(T法)。
定性分析:
M法是测量单位时间内的脉数换算成频率,因存在测量时间内首尾的半个脉冲问题,可能会有2个脉的误差。速度较低时,因测量时间内的脉冲数变少,误差所占的比例会变大,所以M法宜测量高速。如要降低测量的速度下限,可以提高编码器线数或加大测量的单位时间,使用一次采集的脉冲数尽可能多。
T法是测量两个脉冲之间的时间换算成周期,从而得到频率。因存在半个时间单位的问题,可能会有1个时间单位的误差。速度较高时,测得的周期较小,误差所占的比例变大,所以T法宜测量低速。如要增加速度测量的上限,可以减小编码器的脉冲数,或使用更小更精确的计时单位,使一次测量的时间值尽可能大。
M法、T法各有优劣和适应范围,编码器线数不能无限增加、测量时间也不能太长(得考虑实时性)、计时单位也不能无限小,所以往往候M法、T法都无法胜任全速度范围内的测量。因此产生了M法、T法结合的 M/T 测速法:低速时测周期、高速时测频率。
定量分析:
M/T 法中的“低速”、“高速”如何确定呢?
假定能接受的误差范围为1%、M法测得脉冲数为f, T 法测得时间为 t 。
M法:2/f <= 1% ==> f >= 200
即一次测量的最小脉冲数为 200,设此频率对应的速度为 V1
T法:( 1/(t-1) - 1/t ) / (1/t) <= 1% ==> t >= 101
即一次测量的时间为 101 个单位,设此周期对应的速度为 V2
若计时单位为mS,则 t>= 101mS
这只是理论精度,实际应用还要考虑脉冲信号采集的延迟,软件处理所需花费的时间。
若 V1 < V2,则 M/T 法能满足全范围内的速度测量。一个系统设计之前,就需要详细的计算,使V1<V2或尽可能接近。不能光凭经验估算确定高低速、传动比、编码线数。然而很不幸,很多现有系统中会出现 V1 > V2,就会出现(V2, V1) 这一段速度无论 M 法还是 T 法都无法覆盖的情况,一个缓解的办法就是在(V2,V1)段同时使用 M法和T法测量,然后取平均值,但要解决好M/T测量的同步问题。
下面是XEP100程序,使用了ch0,ch1两个通道
/******************************************************************************* *函 数 名: ECT_Init() *输入参数:无 *输出参数:无 *返 回 值:无 *功能描述:ECT初始化 *说 明: *******************************************************************************/ void ECT_Init(void) { ECT_TSCR1_TFFCA = 1; // 定时器标志位快速清除 ECT_TSCR1_TEN = 1; // 定时器使能位. 1=允许定时器正常工作; 0=使主定时器不起作用(包括计数器) ECT_TIOS_IOS0 = 0; //指定通道0,1为输入捕捉方式 ECT_TIOS_IOS1 = 0; //指定通道0,1为输入捕捉方式 ECT_TCTL4 = 0x0A;//0x05 // 设置通道0,1为捕捉上升沿方式 ECT_DLYCT = 0x00; // 延迟控制功能禁止 ECT_ICOVW = 0x00; // 对应的寄存器允许被覆盖; NOVWx = 1, 对应的寄存器不允许覆盖 ECT_ICSYS = 0x00; // 禁止IC及PAC的保持寄存器 ECT_TIE = 0x03; // 禁止所有通道定时中断 ECT_TSCR2 = 0x07; // 预分频系数pr2-pr0:111,,时钟周期为8us, ECT_TFLG1 = 0xff; // 清除各IC/OC中断标志位 ECT_TFLG2 = 0xff; // 清除自由定时器中断标志位 } /******************************************************************************* *函 数 名: TIMCh0IntISR() *输入参数:无 *输出参数:无 *返 回 值:无 *功能描述:ECT输入捕捉-通道0 *说 明: *******************************************************************************/ uint8_T HML_RPM_Flag=0; uint16_T HML_RPM_Count=0,Last_HML_RPM_Count=0; #pragma CODE_SEG __NEAR_SEG NON_BANKED interrupt void TIMCh0IntISR(void)//耗时最大8us { if(ECT_TFLG1_C0F == 1)//PT0 { ECT_TFLG1_C0F = 1 ; HML_RPM_Flag=1; Last_HML_RPM_Count=HML_RPM_Count; HML_RPM_Count=ECT_TC0; if(HML_RPM_Count>Last_HML_RPM_Count) HML_Output_Shaft_RPM= 125000/(HML_RPM_Count- Last_HML_RPM_Count); else HML_Output_Shaft_RPM= 125000/(HML_RPM_Count+ (65535-Last_HML_RPM_Count)); } } #pragma CODE_SEG DEFAULT /******************************************************************************* *函 数 名: TIMCh1IntISR() *输入参数:无 *输出参数:无 *返 回 值:无 *功能描述:ECT输入捕捉-通道1 *说 明: *******************************************************************************/ uint8_T PTO_RPM_Flag=0; uint16_T Last_PTO_RPM_Count=0,PTO_RPM_Count=0; #pragma CODE_SEG __NEAR_SEG NON_BANKED interrupt void TIMCh1IntISR(void)//耗时最大8us { if(ECT_TFLG1_C1F == 1)//PT1 { ECT_TFLG1_C1F=1 ; PTO_RPM_Flag=1; Last_PTO_RPM_Count=PTO_RPM_Count; PTO_RPM_Count=ECT_TC1; if(PTO_RPM_Count>Last_PTO_RPM_Count) PTO_Shaft_RPM= 125000/(PTO_RPM_Count- Last_PTO_RPM_Count); else PTO_Shaft_RPM= 125000/(PTO_RPM_Count+ (65535-Last_PTO_RPM_Count)); } } #pragma CODE_SEG DEFAULT
ECT输入测速,这个方案采用的是测相邻两个脉冲之间的时间,进而推算出脉冲的频率。
其中,Last_PTO_RPM_Count为上次的定时器计数器值,PTO_RPM_Count为本次定时器计数器值,二者相减可得到相邻两个脉冲之间经过了多少个定时器计数器值,比如该值为1000,然后将该值乘以定时器时钟8us,可得相邻两个脉冲之间的实际时间为8000us,进而可得到每秒有多少个脉冲值,即1秒*1000*1000/8000=125个,由于1000这个值是变化的,因此可简化公式1秒*1000*1000/(8*脉冲差值)=125000/脉冲差值。
为了防止当突然没有脉冲时计算出现错误,将下面一段程序可放入500ms定时器中
void RPM_Overtime2Zero(void) { if(HML_RPM_Flag==0&&HML_Output_Shaft_RPM)//PT0 若标志为0但脉冲值不为0,则清零 { HML_Output_Shaft_RPM=0; HML_RPM_Count=0; } else { //若500ms时间到,则清零,该标志需在500ms内置位,否则将清脉冲值 HML_RPM_Flag=0; } if(PTO_RPM_Flag==0&&PTO_Shaft_RPM) //PT1 { PTO_Shaft_RPM=0; PTO_RPM_Count=0; } else { PTO_RPM_Flag=0; } }