manhuami2007 发表于 2023-11-23 10:43

[MSPM0L1306 LaunchPad 开发套件] 8-定时器的输入捕获

<div class='showpostmsg'><div>这次用mspm0l1306实现的小项目需要用到输入捕获,前面2个帖子也把定时器的其它功能进行了测试,也算是把定时器的功能都试了一遍。TI的定时器还是易用的,包括CCS的初始化功能,还有清晰的函数名,都能帮助用户快速上手。</div>

<div>在本例中使用输入捕获的目的是测量输入信号的频率。因此使用输入捕获需要用到2个中断:load中断和捕获中断。通过2次捕获之间的时间差,得到信号的频率。</div>

<div>捕获使用的是TIMG1,设置的定时器周期为2S,初始化如下图所示:</div>

<div></div>

<div></div>

<div>中断使用通道0的捕获和定时器的load中断</div>

<div></div>

<div>在load负载中记录load的次数,在捕获时记录当前CCR的值,通过下面这个函数获得CCR的值。</div>

<div><strong>DL_Timer_getCaptureCompareValue</strong>(CAPTURE_0_INST,<em>DL_TIMER_CC_0_INDEX</em>);</div>

<div>通过将每次捕获的时间放入环形数组中,然后在后台的while循环中读取最近两次的计数值得到时间差,从而计算信号的频率。</div>

<div>代码见下方</div>

<div>中断函数</div>

<div>
<pre>
<code>typedef struct {
    uint32_t period;
    uint32_t ccr;
}TimestampStruct;

typedef struct{
    TimestampStruct time;
    uint8_t write_index;
    uint32_t count;
}TimestampBufStruct;

TimestampBufStruct timestamp_buf;
void CAPTURE_0_INST_IRQHandler()
{
    TimestampStruct nowtime;
    static uint32_t period_count;
    switch(DL_TimerG_getPendingInterrupt(CAPTURE_0_INST)){

      case DL_TIMER_IIDX_CC0_DN:
            nowtime.period = period_count;
            nowtime.ccr = DL_Timer_getCaptureCompareValue(CAPTURE_0_INST,DL_TIMER_CC_0_INDEX);
            write_new_timestamp(nowtime);
            DL_GPIO_togglePins(USER_PORT,USER_R_LED_PIN);
            break;
      case DL_TIMER_IIDX_LOAD:
            period_count++;
            DL_GPIO_togglePins(USER_PORT,USER_R_LED_PIN);
            break;
      default:
            break;
    }
}</code></pre>

<p>时间戳写入环形数组的代码</p>

<pre>
<code>void write_new_timestamp(TimestampStruct timestamp)
{
    timestamp_buf.time = timestamp;
    timestamp_buf.count++;
    timestamp_buf.write_index++;
    if(timestamp_buf.write_index &gt;= 20){
      timestamp_buf.write_index = 0;
    }
}</code></pre>

<p>计算频率的代码</p>

<pre>
<code>uint32_t get_timestamp_diff()
{
    uint8_t index = timestamp_buf.write_index;
    TimestampStruct nowtime,lasttime;
    char str1;
    uint32_t time_dif = 0;
    if(index &gt; 0){
      nowtime = timestamp_buf.time;
    }else{
      nowtime = timestamp_buf.time;
    }
    if((index -1) &gt; 0){
      lasttime = timestamp_buf.time;
    }else{
      lasttime = timestamp_buf.time;
    }


    if(nowtime.period == lasttime.period){
      time_dif = lasttime.ccr- nowtime.ccr;
    }else if(nowtime.period -lasttime.period == 1){

      nowtime.ccr = 40000-nowtime.ccr;
      lasttime.ccr = 40000-lasttime.ccr;
      time_dif = 40000 - lasttime.ccr + lasttime.ccr;

    }else{
      time_dif = (nowtime.period - lasttime.period -1)*40000;
      time_dif += 40000 - lasttime.ccr + lasttime.ccr;
    }

    return time_dif;
}
float compute_freq()
{
    uint32_t diff;
    float freq;
    if(timestamp_buf.count &gt;= 2){
      diff = get_timestamp_diff();
      if(diff != 0){
            freq =20000.0 /diff;
            return freq;
      }else{
            return 0;
      }
    }else{
      return 0;
    }
}</code></pre>

<p>主函数</p>

<pre>
<code>char str ="helo";
float frq;
int i_frq;
int main(void)
{


    SYSCFG_DL_init();
//    APP_DL_UART_0_init();
    NVIC_EnableIRQ(CAPTURE_0_INST_INT_IRQN);
    send_multi_data_by_uart((uint8_t*)str,strlen(str));
    DL_TimerG_startCounter(CAPTURE_0_INST);
    while (1) {
      delay_cycles(32000000);
      frq = compute_freq();
      i_frq = (int)frq;
      snprintf(str,50,"freq:%d\r\n",i_frq);
      send_multi_data_by_uart((uint8_t*)str,strlen(str));
    }
}</code></pre>

<p>&nbsp;</p>
</div>

<div>计算的频率还是比较准的,用示波器输出了1khz的信号,采集到的频率也是1khz。</div>

<div></div>

<div>最后要补充的是,编译器好像不支持浮点数,用想用sprintf函数输出浮点数的值时,会进入硬件错误的死循环中,所以代码改成了输出整型数据。</div>
</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                                                                                (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

Jacktang 发表于 2023-11-24 07:25

<p>TI的定时器操作起来不是很复杂</p>

Walter_Lai 发表于 2024-7-24 22:23

<p>请问下想测50K这些频率高一点的应该怎么配啊?</p>
页: [1]
查看完整版本: [MSPM0L1306 LaunchPad 开发套件] 8-定时器的输入捕获