吴俊 冯国胜 王点点
(石家庄铁道大学)
传统电子测速法的M法和T 法在实际应用当中,测量范围、精度有限[1],这往往是由于DSP 计数器溢出[2]和DSP 执行程序需要一定的时间所导致的,其中T 法在测量低频脉冲、M法在测量高频脉冲时,测量结果不准确的情况更加频繁。目前传统的改善方法是通过复杂的软硬件配置来实现准确测速。文章主要使用CodeWarrior 下更加高效的PE 编程工具,采用新的编程方法将 M 法和 T 法应用到数字信号处理器MC56F8346 的测速中,提高了传统T 法、M法的测量范围和精度。
MC56F8346 是一款数字信号处理器,它的结构中包含数个定时模块,每个定时模块由4 组相同的16 位定时/计数器组成,其单个定时/计数器结构,如图1所示。定时/计数器有2 种基本的工作模式:1)记录内部和外部事件数,该模式应用在M法上;2)记录每个外部事件之间所经历的内部时钟周期数,也就是得到外部事件的时间间隔,该模式应用在T 法上[3]。文章中,使用信号发生器产生一定频率的方波信号来模拟编码器产生的转速信号,将此信号输入至MC56F8346 引脚处,分别使用count(计数)模块和capture(捕获)模块对方波信号计数。最终通过计算求得输入信号的周期和频率。使用M 法时,要先配置count 模块,在计数过程中,当输入高频方波信号时,计数器会多次溢出;文章引入变量over(变量名),计数器每溢出1 次,变量就会加1。使用T 法时,要先配置capture 模块,当输入低频方波信号时,计数器可能会多次溢出;同样引入变量over,记录溢出次数。
图1 定时/计数器结构框图
定时/计数寄存器(TMRCNTR)是16 位寄存器。其中,计数捕获寄存器(TMRCAP)是16 位寄存器,该寄存器存储从计数器捕获的值;定时重装载寄存器(TMRLOAD)是16 位寄存器,用来装载计数器的值;定时控制寄存器(TMRCTRL)是16 位寄存器,其中的位15~13是计数模式控制位(CM);计数状态/控制寄存器(TMRSCR)是16 位寄存器,位13 是计数器溢出标志位(TOF),位12 是计数器溢出中断使能位(TOFIE),位11是输入边沿标志位(IEF),位10 是输入边沿中断使能位 (IEFIE),位 7,6 是输入捕获模式位(CAPTURE MODE);定时比较寄存器 1(TMRCMP1)是 16 位寄存器,该寄存器存储的数值与计数器数值进行比较;定时重装载寄存器1(TMRCMPLD1)是16 位寄存器,该寄存器存放定时比较寄存器中的比较值;计数比较状态/控制寄存器(TMRCOMSCR)是16 位寄存器,位6 是计数比较寄存器1 中断使能位(TCF1EN),当TCF1EN 与TCF1 同时置1 时,产生计数比较中断,位4 是计数比较寄存器1 标志位(TCF1),当比较寄存器比较成功后,TCF1 置 1。
CodeWarrior 下的PE 编程工具是某公司开发的一款快速初始化工具,可以更加简单、高效地完成项目任务。PE 支持该公司几乎所有的嵌入式芯片,该工具会直接生成函数框架,编程人员在其中写代码即可,为编程人员提供了高效的工作环境。使用PE 编程流程,如图2所示。
图2 使用PE 编程流程图
T法测周期,即通过记录输入脉冲信号2 个连续上升沿之间所经历的内部时钟周期数,经计算就会得到输入脉冲信号周期。使用PE 工具编程时首先选择Capture Components(捕获元件),并对其进行设置[4]。之后,PE 生成相对应的Cap1_Init(void)初始化程序,初始化程序主要完成的工作有:
1)设置定时控制寄存器(TMRCTRL)。这里将位8,7(副计数脉冲源控制位)置为01,确定外部脉冲信号的输入引脚为1。
2)设置计数状态/控制寄存器(TMRSCR)。这里将位 12(TOFIE)、位 10(IEFIE)置 1,这样就会使能计数器溢出中断、输入边沿中断。
3)清空定时/计数寄存器(TMRCNTR)、计数捕获寄存器(TMRCAP)、定时重装载寄存器(TMRLOAD)。
4)设置前分频。这里将PCS 位设置为1 100,即IP总线时钟为16 分频。
5)设置定时控制寄存器(TMRCTRL)CM 位,选择计数器的控制模式。这里设置为001,即在主计数脉冲上升沿计数。
6)设置计数状态/控制寄存器(TMRSCR)Capture-Mode 位。这里设置为01,选择上升沿装载。
当底层程序初始化后,16 位定时/计数寄存器(TMRCNTR)就开始对系统时钟循环计数。当定时/计数器达到满值65 535(216-1)时,计数状态/控制寄存器(TMRSCR)的位13 计数器溢出标志位(TOF)就会置1。由于将计数状态/控制寄存器(TMRSCR)位 12(TOFIE)置为1,所以当TOF 为1 时,就会产生1 个计数器溢出中断。在该中断中编写一个变量over,使其累加;那么每次计数器达到满值时,就会进入中断中,变量over 就会加1。
输入的脉冲信号每当出现一个上升沿或下降沿时,就会置位 IEF。同时由于计数状态/控制寄存器(TMRSCR)的位 10(IEFIE)置 1,就会产生输入边沿中断。设置计数状态/控制寄存器(TMRSCR)Capture Mode位为01,当置位IEF 时,设置为上升沿装载。因此遇到上升沿时,计数器中的数据就存储在捕获寄存器中。
2 个相邻上升沿发生时,可能的情况可以分为2 种:1)第1 个上升沿发生后,第2 个上升沿发生前,定时/计数寄存器没有发生溢出;2)第1 个上升沿发生过后,在第2 个上升沿到来之前,定时/计数寄存器发生了溢出且可能不止1 次溢出,对应over 会递增。在2 个相邻的上升沿产生的边沿中断中,分别将2 次捕获寄存器中的值赋给变量count1 和count2,同时记录此时的溢出次数over1 和over2。中断子程序流程图,如图3所示。
图3 T 法中断子程序流程图
编写程序如下:
#pragma interrupt called
void Cap1_OnCapture(void)
{
/*Write your code here...*/
index++;
if(index==1)
{
over1=over;
Cap1_GetCaptureValue( & count[index]);
}
if(index==2)
{
over2=over;
Cap1_GetCaptureValue( & count[index]);
……
index=0;
over=0;
}
}
这种方法主要是通过测量一段时间内的脉冲个数来获得转速,也可以称为测频法。同样,使用PE 编程时首先选择EventCntr16,TimerInt Components,并对其进行设置。设置后,PE 底层生成的主要初始化程序包括TI1_Init(void),EC16_Init(void)。TI1_Init(void)主要完成的工作有:
1)设置控制寄存器(TMRA2_CTRL)。这里将位5(LENGTH)置1,这样计数器到达预设值后重新初始化。
2)设置控制寄存器(TMRA3_CTRL)。这里将CM位置为0111,这样就采用级联计数模式,扩大了定时中断的时间(Component 中设置为1 000 ms)。
3)设置计数状态/控制寄存器(TMRA2_SCR,TMRA3_SCR)。
4)清空定时/计数寄存器(TMRA2_CNTR,TMRA3_CNTR)、定时重装载寄存器(TMRA2_LOAD,TMRA3_LOAD)。
5)设置定时比较寄存器(TMRCMP1)。文中定时时间设置为1 s。因为采取级联计数模式,即TMRA2 的输出作为TMRA3 的输入。这里将TMRA3_CMP1 设置为1 279,TMRA2_CMP1 设置为 46 874。每当 TMRA2 的计数器数值达到TMRA2_CMP1 所设置值(46 874)时,TMRA3 的计数器就会加1,直到达到TMRA3_CMP1 所设置值(1 279)时,产生比较成功中断程序,这样共计数46 874×1 279=59 951 846 次。
6)设置计数比较状态/控制寄存器(TMRCOMSCR)。文章中采用级联计数模式,这里将TMRA3_COMSCR 的TCF1EN 位置1,当与3 通道定时比较寄存器 1(TMRCMP1)完成比较时(TCF1 位置 1),计数比较寄存器就会发生中断;CL1 位置1,即在与3 通道 TMRCMP1 比较成功后重装初值。 将 TMRA2_COMSCR 的 CL1 位置 1,即在与 2 通道 TMRCMP1 比较成功后重装初值。
7)1 279,46 874 分别写入 TMRA3_CMPLD1,TMRA2_CMPLD1。
8)设置定时控制寄存器TMRA2_CTRL。这里设置PCS 位为1 000,即设置IP 总线时钟为1 分频。
9)清空定时/计数寄存器TMR2_CNTR,TMR3_CNTR。
10)设置定时控制寄存器TMRA2_CTRL。这里将CM位设为001,在主计数脉冲上升沿计数。
完成上述工作后,定时器产生的中断间隔时间的计算,如式(1)所示。
其中60×106是CPU 源时钟经过分频得到的系统时钟;59 951 846 是设置得到的计数值。因此得到中断的时间为0.999 2 s,接近于1 s。
EC16_Init(void)主要完成的工作有:
1)设置控制寄存器(TMRA0_CTRL)。首先停止计数器的所有功能。
2)设置计数状态/控制寄存器(TMRA0_SCR)。这里将TOFIE 位置1,当计数器溢出标志位(TOF)为1 时,产生计数器溢出中断。
3)设置计数比较状态/控制寄存器(TMRA0_COMSCR)。
4)清空定时/计数寄存器(TMRA0_CNTR)。.
5)设置控制寄存器(TMRA0_CTRL)。这里设置CM为001,即在主计数脉冲的上升沿计数。
在Component 中设置完成后,每1 s 会产生1 个定时中断;同时当计数器A0 溢出后,就会进入溢出中断,使变量over 加1。
图4示出M法中断子程序流程。
图4 M 法中断子程序流程图
编写程序如下:
void TI1_OnInterrupt(void)
{
/*Write your code here...*/
EC161_GetNumEvents( & count1);
over1=over;
……
}
void EC161_Interrupt(void)
{
clrRegBit(TMRA0_SCR,TOF);
……
over++;
}
同时要对底层程序进行修改,清空计数器的同时也要清空变量over。
byte EC161_Reset(void)
{
setReg(TMRA0_CNTR,0x00);
over=0;
……
}
该程序中,输出变量count 值就是测量脉冲的频率。
在实验室中搭建测速平台,通过信号发生器模拟转速信号,通过M法和T 法测得的结果,如表1所示。信号发生器输出信号的频率在1~100 000 范围内,用M法和T 法得到的测量误差中,最大为3.74%,最小为0。整体来讲,采用新的方法得到的试验结果误差范围小、结果可靠。
表1 使用PE 编程的T 法和M 法测量结果表
T 法和M法在电子测速过程中所存在的计数器溢出情况往往被忽略,文章对这种情况进行了处理,通过选用更加高效的PE 编程工具,采用新的软件编程方法,对信号发生器输出的模拟转速信号进行了测速试验。结果表明,该法比前人的软件编程过程更高效、方便且整体代码量小,当输入信号频率在1~100 000 Hz范围内时,得到的测量结果误差范围小、可靠性高。该方法是否可行,还需要在实际的行车过程进行进一步验证。