首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

请教脉冲累计器的“分辨率”

在论坛上也看了许多tx的关于脉冲捕捉和脉冲累加器的帖子,明白一些,也还存在很多不懂的地方。我同时也对级联后的16位脉冲累计通道A进行了配置(似乎比B复杂一些),得出的效果也对于100Hz以下的脉冲输入不敏感,我纳闷了,用输入捕捉(IC)方式,可以很精确地采集并计算出脉冲的周期,不至于脉冲累积器的分辨率就只这么低吧。想来问题要不出在对脉冲累积器的初始化,要不硬件问题,请各位大侠指点一哈^_^

请教脉冲累计器的“分辨率”

在使用S12系列单片机(DP256)进行脉冲累计的测试,发现按照我的如下初始化配置:
void pbca_init(void)
{
    PBCTL_PBEN = 1;
    TCTL4_EDG0A = 1;
    TCTL4_EDG0B = 0;//Capture on rising edges only
}

使用级联后的16位通道B进行脉冲累计,脉冲由PT0输入,定期读取PACN10(Pulse Accumulators Count 10 Register; 0x00000064 ***/)的值来反映一定时间上的脉冲数,然后可计算出脉冲频率。
请问:1)这种方式用来计算脉冲频率有问题吗?
2)我读取PACN10,发现其最大的分辨率只在100Hz,也就是说100Hz以下频率的脉冲输入(我使用的是函数发生器输入方波信号),该脉冲累计器没用变动,当高于100Hz时,PACN10开始累计。请问,这正常吗?我希望能够如实第捕捉从1Hz到10KHz的脉冲频率

[此贴子已经被作者于2007-7-2 11:23:32编辑过]

比如我在主程序中10ms读取一次PACN10的值,然后将当前值与上一次读取的值相减,这样的差值就是就可以计算出脉冲频率。这样的计算有问题吗?10ms时间我是通过模数递减计数器(MDC)产生1ms定时中断,累计10次得出的

版主的回复好快啊,谢谢

[此贴子已经被作者于2007-7-2 13:25:26编辑过]

不好意思,我下午想到一些东西,可能对于解决这个有所启发,正在理清头绪
我下午随意在本子上写了一些什么是频率,10ms采集的对比
频率就是单位时间的脉冲数量,设脉冲数量为0~Nmax,单位时间就是1s
那么频率 f = (0~Nmax)/ (1 s)
1)目前我是10ms计算读取一次脉冲累加器(PACN10)的值,
此时频率计算 f1 = ( (0~Nmax)÷100 )/ (10 ms)
从( (0~Nmax)÷100 )这个式子来看,实际采集来的脉冲数被人为地压缩了100倍。
2)如果我是1s计算读取一次脉冲累加器(PACN10)的值,
此时频率计算 f2 = ( (0~Nmax) )/ (1s)
这样似乎就没用“分辨率”降低的忧虑了,但是这样,对于脉冲计算的延时,是相当滞后的。比如车速采集,不知道这样考虑是否正确
是的,确实很多数值被丢掉了。今天谢谢strongchen的回答和帮助。我还有一些问题可能还要实践一下,遇到了问题再请教大家。
其实在运算中并没用对PACN10÷100,只是以每10ms读取一次累加寄存器的方式,100Hz以内的脉冲是不能被侦测到差值的,上面f1 = ( (0~Nmax)÷100 )/ (10 ms)或者f2 = ( (0~Nmax) )/ (1s)的计算完全是由单位换算看到出现的绝对误差。呵呵,我的表述不知道是否清楚。不过我觉得这是个问题。
下午,做了一个最简单的脉冲计数程序。我所遇到的问题,现在想来,既非初始化的问题,也不是硬件的毛病。是“定时”读取PCN10或者PCN32中存在的误差。我把整个project贴出来,可能会说得更清楚

word plus_data[10];
void mdc_init(void) //MDC初始化,配置为1ms定时基准
{
    MCCTL = 0xcd;
    MCCNT = 2000;
}

#pragma CODE_SEG NON_BANKED //MDC中断服务程序
#pragma TRAP_PROC
void MDC_ISR(void)
{
    MCCNT=2000;
    MCFLG=0x80;

    if ( mdc_cout > 60000 )
    {
        mdc_cout = 0;
    }
    mdc_cout++;

    if ( !(mdc_cout%100) ) //100ms定时标识
    {
        plus_run_flag = 1;
    } 
}
#pragma CODE_SEG DEFAULT


void pbca_init(void) //脉冲累加器B的开启与边沿捕捉的配置
{
    PBCTL_PBEN = 1;
    TCTL4_EDG0A = 1;
    TCTL4_EDG0B = 0;
}

void plus_cont(void) //一定时间(100ms)内脉冲数量
{
    static word oldValue;

    plus_data[0] = abs(PACN10 - oldValue);
    oldValue = PACN10;
}

void main(void)
{
    DisableInterrupts;
    mdc_init();
    pbca_init();

    EnableInterrupts;

    while(1)
    {

        if(plus_run_flag) //100ms定时标志位
        {
            plus_run_flag = 0;
            plus_cont();
        }
    }
}

    目前100ms读取一次PACN10的值并与前一次记录下来的值作比较,得到该100ms内的脉冲数N,即N/100ms = N*10/1s = N*10 Hz,只是作减法,但是低于10Hz的脉冲,却由于我是100ms的读取,能捕捉到,但在我的差值plus_data[0]上是没用大的持续变化的,因此计算出来脉冲频率“分辨率”只能是10Hz;昨天我用10ms的周期定时读取PACN10,差值plus_data[0]更是只在100Hz开外变动,即只能识别诸如1.1~1.2Khz,而没法读到1.100~1.299Khz,
这样分析一下,不知道是不是抓住了根本。

[此贴子已经被作者于2007-7-3 14:56:48编辑过]

还要一个问题想请教,我可否在PTO上既使用输入捕捉(IC)功能,又能开启脉冲累积器进行计数,也就是想用“IC算周期”和“脉冲累积器算频率”共同计算同一个输入信号的频率,而不使用两个通道分开进行采集。
(我试着在程序中将IC的初始化和pbca_init(void)初始化均打开,实际只是IC初始化起作用,即只输入捕捉采集到数据,PACN10无变化)
我打包发上来啦http://bbs.chinaecnet.com/uploadImages/plus_test.rar
现在打包的是将IC的初始化ic_init()和pbca_init(void)初始化均打开,最后只有IOC0_wData采集到了周期值,plus_data[0]的值却不正常(在跳动),我希望是能够“‘IC算周期’和‘脉冲累积器算频率’共同计算同一个输入信号的频率”http://bbs.chinaecnet.com/uploadImages/plus_test2.rar
plus_test2.rar 中,如果单个初始化,如只进行脉冲捕捉ic_init()初始化,或者之将B通道的脉冲累积器使能pbca_init(void),则结果正常。是不是该PTO对于这两个功能不能复用?
首先谢谢strongchen的解答,^_^
是的,我后来也发现问题之所在,“当查询频率快于信号频率时”,PACN10=oldValue,结果是统计不出当前脉冲的,不过我总是要类似的方法来计算频率吧,如果要求有比较好的实时性,采集并且滤波之后不致于滞后太多。如果把输入频率调至1Hz并实时监控PACN10的值,确实能够看到该累积器是从0至0xFFFF在递增的。

另外,PAC和IC共享相同的引脚,用它来对同一引脚进行记录,为何我让其一同工作的时候(前者用于记录脉冲数量,后者记录脉冲周期)在plus_test2.rar 中,得到的脉冲数量却不正常,但是偶尔能够采集到正常,问题又出在哪里呢?

[此贴子已经被作者于2007-7-4 8:57:03编辑过]

plus_test2.rar的main.c中发现,读取TC0H的值对脉冲累积器的值PCN10有影响,怎么解决呢?
我设置PT0脚输入捕捉和脉冲累积器B使能,当我读取TC0H的值对脉冲累积器的值PCN10有影响(把PCN10清零了),不知这种做法是否妥当,有没用办法不让PCN10被清零。我看说明文档中,只是ICSYS中的LATQ位设为1(锁存方式)时候,才会在捕捉到内容并转移至保存寄存器,才会将8为的脉冲累积器清零。然而,我设置的是队列方式,而且用的是级联后的累计其B。有点不明白了
返回列表