This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CCS/TM4C123GH6PM:使用计时器计算 RPM

Guru**** 1839620 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/582964/ccs-tm4c123gh6pm-using-timer-to-calculate-rpm

器件型号:TM4C123GH6PM

工具/软件:Code Composer Studio

我无法找到正确使用向上计数器的方法。

我将使用簧片开关作为每转的输入。 我只需要使用计时器来获取输入之间的时间。  

-Matt

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Matt、
    请参阅 Driverlib 使用指南、了解如何将计时器配置为时间捕获模式。 下面是使用 Timer0的 TimerA 执行16位输入边沿定时捕获模式的示例。

    SysCtlPeripheralEnable (SYSCTL_Periph_TIMER0);
    TimerConfigure (TIMER0_BASE,(TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME);
    TimerIntEnable (TIMER0_BASE、TIMER_CAP_EVENT);
    TimerControlEvent (TIMER0_BASE、TIMER_A、TIMER_EVENT_POS_EDGE);
    TimerLoadSet (TIMER0_BASE、TIMER_A、0xFFFF);
    TimerControlStall (TIMER0_BASE、TIMER_A、TRUE);
    IntEnable (INT_TIMER0A);
    TimerEnable (TIMER0_BASE、TIMER_A);

    此外、请查看以下帖子、该帖子可能会有所帮助。

    e2e.ti.com/.../2107046
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引述 USER="Matt Cowler"]我只需要使用计时器来获取输入之间的时间。  [/报价]

    也许不是!  是否要简单得多:

    • 将计时器配置为运行1秒
    • 配置第二个计时器以捕获簧片开关的上升沿或下降沿
    • 清除"计数计时器"和(单独) 1秒计时器-然后启用这两个计时器
    • 当1秒定时器"超时"时、禁用"计数定时器"
    • 使用定时器2捕获的"边沿数"是您的结果-但以 RPS 为单位  
    • 乘以60将 RPS 转换为 RPM

    您需要查看 MCU 手册以确定"边沿计数"模式是否接受"向上或向下"(仅限一个)捕获。   如果您采用"倒计时"、则只需确定"计数:开始和结束"之间计数的"差异"。  通常、但并非总是"递减计数"更易于编程、并且在 MCU 实现中更广泛。

    以上是 KISS 的演示-最常产生的结果是"更快、更容易和增强"。

    您的电机-因此您的"边沿捕获时间日志"(如您所建议)可能会遇到很大差异。  那么、您如何"知道"哪个"时间差"是有效的?  所介绍的方法更容易原谅、因为它会在1秒的周期内累积边沿捕获。  没有任何因素阻止您根据您的要求增加或减少捕获周期。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的回复和提供的信息。  

    [引用 USER="CB1_MOBILE "]

    也许不是!  是否要简单得多:

    • 将计时器配置为运行1秒
    • 配置第二个计时器以捕获簧片开关的上升沿或下降沿
    • 清除"计数计时器"和(单独) 1秒计时器-然后启用这两个计时器
    • 当1秒定时器"超时"时、禁用"计数定时器"
    • 使用定时器2捕获的"边沿数"是您的结果-但以 RPS 为单位  
    • 乘以60将 RPS 转换为 RPM

    [/报价]

    您的意思是这样吗?

    //#include "driverlib/debug.h"
    #include 
    #include 
    #include "inc/tm4c123gh66.h"
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    
    #include "inc/hw_types.h"#include "driverlib/sysctl.h"
    #include "driverlib/interrupt_timers_timers/syspertl
    
    
    
    (timers_clused/sys_iptl)/sys_timers_timers/iptpertl
    
    
    (timers_timers_timers/sys_timers_timers/sys_timers_timers/ipttl.h)
    
    
    
    
    
    
    //用于测量信号的前缘
    
    //启用定时器1使用的 D 外设- CPP
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOD);
    
    /*********
    PinTypeTimer (CCP2);//查找计时器引脚并将其配置为计时器功能
    /
    
    GPIOPinTypeTimer (GPIO_PORTD_base、GPIO_PIN_1);//将 GPIO 端口 D 引脚1配置为用作计时器引脚
    GPIOPinConfigure (GPIO_PD1_WT2CCP1);//在 GPIO 端口 D 引脚1上启用 ccp 功能
    
    //启用处理器中断。
    IntMasterEnable();
    // Timer0A 超时中断- evert 100ms
    IntEnable (INT_TIMER0A);
    TimerIntEnable (TIMER0_BASE、TIMER_TINA_TIMEOUT);
    
    //配置两个32位周期定时器。
    TimerConfigure (TIMER0_BASE、TIMER_CFG_PERIOD);//全宽周期定时器
    TimerConfigure (TIMER1_BASE、TIMER_CFG_A_CAP_COUNT);//半宽边沿计数捕获
    
    //配置定时器装载值
    TimerCtlSet (TIMER0_BASE、TIMER_A、SysClockGet=100MHz(100MHz)、TimerCtlRUND= 100MHz (100MHz)/
    时钟周期(100MHz)...)、TimerCtl1 (100MHz)、TimerCtlRUNC000= 100MHz (100MHz)、TimerTimerTimerSet=100MHz (100MHz)、TimerTimerTimerTimerTimer000//Timer1在每个正边沿倒计数时加载一个值(10000)
    
    //配置在捕获模式中触发定时器的信号边沿
    TimerControlEvent (Timer1_base、timer_A、timer_event_POS_EDGE);//设置 Timer1A 在正边沿上触发。
    
    //启用计时器。
    TimerEnable (TIMER0_BASE、TIMER_A);
    TimerEnable (TIMER1_BASE、TIMER_A);
    
    while (1)
    {
    float freq;
    float RPM;
    
    freq =(10000 -定时器)* 1000;//* 1000转换为 Hz
    RPM = freq * 60;
    
    }
    
    
    
    
    *****
    //
    //第一个定时器中断的中断处理程序。
    ////
    *****************
    void Timer0IntHandler (void)//Timer 0A
    {
    //清除计时器中断
    TimerIntClear (TIMER0_BASE、TIMER_TINA_TIMEOUT);
    
    //获取计数器值
    TIMER=TimerValueGet (Timer1_base、timer_A);
    
    //将计数器值重置为10000
    TimerLoadSet (Timer1_base、TimerA);
    
    
    
    // TIMER_A *
    //
    //第二个计时器中断的中断处理程序。
    ////
    *****************
    void Timer1IntHandler (void)//计时器1A
    {
    }
    
    
    
    
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用用户="Matt Cowler"]您的意思是这样吗?

    您明显取得了良好的进步、但公司/我(始终)更喜欢"亲吻"、并且偏离了我的"亲吻"技术大纲。   (不是什么大问题-我会证明我的方法/疯狂是值得您考虑的)

    我们同意使用两个计时器:

    • 计时器1提供"脉冲接受(即门控)时基"。   我建议1秒-您的秒数是它的1/10。  由于您的"拾取"仅提供一个脉冲/电机旋转-单个"漏"脉冲(或"接近"但"尚未到达"的脉冲)会对您的速度测量产生剧烈影响。   回想一下、在(我建议的) 1秒"计数门"的情况下、计时器的内容乘以60以产生 RPM。   使用(短得多)浇口开启时间-将零件序号乘以600!   这意味着您只能将电机转速解析为600RPM -如果捕获到9.99个脉冲、结果将是5400!  (基本上是600RPM 误差-由(无法解释)选择"过短"栅极导通时间引起。   相比之下、1秒选通时间将捕获99.9个脉冲、从而产生5940RPM。  远好得多-你不同意吗?  (注-小数点反映"尚未到达下一个脉冲"- MCU 的计时器是"仅整数"计数器。)
    • 定时器2用作"信号边沿计数器"、由定时器1启用(用于精确的时间范围)。

    为了符合 w/kiss 标准-不应将计时器1配置为"单次触发?"   (您的经验/知识未知-如有必要、请使用网络来帮助) 单次触发的美妙之处是"自动正确启用"计数"计时器2 -仅在所需的(1秒)时间范围内。   当计时器1 (时基)"过期"时、计时器2 (边沿计数器)的内容"冻结"-这使您可以轻松地"读取"该计时器。   您可以通过禁用计时器2来实现(所需的)"冻结计时器2 "、这是由计时器1的"超时"提示的。  在"读取定时器2的内容"并执行"RPS 至 RPM"计算/显示后、您应该"清除"计数器定时器(定时器2)并重新触发"单次触发"(时基)定时器。  (定时器1)

    请注意、您选择了"周期计时器"、这会强制您的过程更加复杂、因为您必须在下一个(非法)输入脉冲到达之前立即读取计数器计时器!  与之形成鲜明对比的是、在您读取计数器(执行计算)之前、一次性计时器在"闲置"状态下相当正常、显示和/或采取控制措施。   该一次性计时器(然后)被重新触发-启用您的"下一个"速度测量。   因此、您已经"逃脱"了"执行下一个速度测量"的所有匆忙。  这是一个良好的 Kiss Design 的标志。   (没有任何东西会阻止您快速启动(下一个) kiss "速度捕获"、但这应该是您的愿望产生的、而不是"设计必要性"。  (即抗亲吻)

    我们注意到、您为边沿计数器选择了32位计时器。  是否真的需要该容量?  (特别是如果您使用100mS 的时基!)  (答案:当然不是- 16位(甚至8位)就足够了) 1秒时基可能需要32位(现在)-如果您决定接受该建议...   (以及您是如何到达1/10秒的时间范围的?)

    考虑以下指导-请推广 kiss -我们将看到您的下一个迭代所揭示的内容...

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我尝试查看修改为 Stellaris 找到的频率计数器是否可行。

    我将使用此函数来计算低 RPM -小于120、这就是我选择32位计时器的原因、因为周期更长。

    定时器的 CCP 配置对我来说也是个问题。  

    以下是否是 Timer1A PFO 上输入脉冲的正确配置

    GPIOPinConfigure (GPIO_PF0_T1CCP0);
    GPIOPinTypeTimer (GPIO_PORTF_BASE、GPIO_PIN_0); 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Matt Cowler"]我试图查看修改为 Stellaris 找到的频率计数器是否可行。

    这种愿望从未出现过,而"Stellaris"已经(很长)了,因为"死/埋"对这里的人似乎没有什么用处。   (我更喜欢提供通用解决方案-为许多人的利益-我将(对其他人)满足您(独特的-和刚刚提出的)愿望。)

    [引用用户="Matt Cowler"]我将使用此函数来计算低 RPM -小于120,这就是我选择32位计时器的原因,因为时间更长。

    因此,您没有使用我代表您详细介绍的“基于 kiss 的解决方案”。   而且-这是您对"低速"要求的"第一个"提及。   在"极低转速"时、我介绍的技术的主要优势是"代码速度和易用性"。  必须延长我之前实施方案的"选通时间"、以便适当(更多)容纳(刚刚接收到)低频信号到达。

    您尚未解决"连续脉冲到达量之间"差值"的预期变化问题。"   您对(超出)"背靠背"脉冲时间分色的捕获将提高测量精度。   (即捕获(例如) 5个连续脉冲之间的时间(脉冲1到达和脉冲5到达之间的差值)。)  将"脉冲5的边沿-脉冲1的边沿"的持续时间除以4 (而不是5)会减少由速度变化引起的误差。   (我们除以4、而不是5、因为我们有(仅) 4个"信号边沿"Deltas"。)  (即 T2-T1、T3-T2、T4-T3和 T5-T4。)  同样、不需要捕获"每个"脉冲的"到达时间"(尽管该方法可行)。   留给读者的是捕获(仅)脉冲1的"到达时间"、然后捕获脉冲5或10等的"方式"。  提示:ARM MCU 具有许多计时器。  额外积分-捕获并记录信号到达时间#1和5 (仅限)-采用(仅限一个)计时器...

    您对 PF0的选择尤其不幸、因为该引脚(以及其他引脚)是"特别挑战"。   (因此引入了更多的防 kiss -没有(明显)原因)  论坛搜索将揭示该 PIN 的" gotcha "和所需的操作。

    我的建议是研究、查找并采用具有出色"每个旋转输出的脉冲数"的电机轴驱动器件(可能是编码器)。   这甚至更能支持此处之前详述的速度测量方法...