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.

[参考译文] RTOS/CC2640:硬件中断时间戳

Guru**** 2471680 points
Other Parts Discussed in Thread: CC2650STK

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

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/597407/rtos-cc2640-hardware-interrupts-timestamping

器件型号:CC2640
主题中讨论的其他器件:CC2650STK

工具/软件:TI-RTOS

背景-尝试从 IR 传感器收集硬件中断脉冲。 我正在根据 IR 主机协议接收正确数量的脉冲、但计时已关闭。

数据基于脉冲持续时间、类似于:基本脉冲长度+ 90us * n、其中 N 是0-F (半字节)之间的数字、因此我所需的最小精度小于90us。

问题-我看到的时间戳不够准确。 我通过存储之前的节拍来收集时序-"Clock_getTicks"、 然后在收集到足够的脉冲后、我禁用 IR 处理程序并通知主任务进行处理、在完成处理后、只需重新启用特定数据引脚的中断。

IR 处理程序示例:

空 IR_Interrupt_Handler (空)


   uint32 tick_now = Clock_getTicks();

//存储脉冲: tick_now - IR_data.LAST_ACTIVE_TICKs (我稍后将这些值多路复用为"Clock_tickPeriod"以使它们进入我们的时间(微秒)。

IF (接收到所需的脉冲数)

//1. 禁用中断

//2. 通知主任务以处理数据(完成后、将重置接收缓冲区并启用中断以启动更多 IR 数据的接收


   IR_DATA.LAST_ACTIVE_TICKs = tick_now;   


注意:我尝试在 IR 处理程序内禁用此数据卡上的中断、然后在其末尾重新启用它、这不会改变我的结果、但是当我执行此操作时、它似乎会在一些迭代后锁定、大约200-300个周期的脉冲

是否有更好的方法为硬件中断设置时间戳?

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

    您是否考虑过使用 GPTimer 模块获取更高精度的时间戳?

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

    您好!

    是的、感谢您的建议。 我找到了一些示例并开始研究 GTP 计时器。 这是一个非常有用的示例:

    e2e.ti.com/.../436309  

    我可以让中断进入、但当我测量计时器节拍时、我得到的数字非常高、与预期的值不符。

    我正在读取这些刻度:

    tick_now = TimerValueGet (GPT0_BASE、timer_A);

    当我尝试:

    tick_now = HWREG (GPT0_BASE + GPT_O_TAPR);-我每次得到零、

    提前感谢您的帮助!

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

    我希望能提供更多的信息、以确保我在解决这一问题的正确道路上。

    我已经使用 GPT 0、其他论坛线程和大量研究实施了边缘检测。
    我正在接收中断、并且正在调用处理程序、但问题是时间戳仍然不够准确。 尝试使用 TI CX2640 BLE 芯片实现非常简单的功能所需的时间比预期的要长。 BTW、我使用的是 BLE 堆栈2.2.1。
    是否有人确认或建议如何继续、以确保我们使用 GPT0获得准确的时间戳。
    从理论上讲、GPT0是48MHz 定时器、因此其节拍数应为微秒的1/48–如果我进行计算、该逻辑是基准。
    另外需要仔细检查的是、我使用的预分频值为255、在该模式下(边沿捕捉)将定时器范围扩展了8位以上(16-23)、使其成为24位定时器–这就是我读取该值的原因:
    (uint32_t)(((HWREG (GPT0_BASE + GPT_O_TAPR)& 0x000000FF)<< 16)+ HWREG (GPT0_BASE + GPT_O_TAR);
    如果没有预分频、定时器会复位太频繁、从而难以跟踪中断之间的持续时间。
    代码如下:
    计时器设置:
    ///----------------------------------------------------------
    ///----------------------------------------------------------

    hIrDataPin = PIN_OPEN (&pinIrDataState、IrPinTable);

    //打开外设的电源
    PRCMPowerDomainOn (PRCM_DOMAIN_PERIPh);
    Power_setDependency (PowerCC26XX_Periph_GPT0);
    PRCMLoadSet();
    PRCMPeripheralRunEnable (PRCM_Periph_TIMER0);
    PRCMLoadSet();

    PINCC26XX_setMux (hIrDataPin、XPERT_PIN_IR_DATA、IOC_PORT_MCU_PORT_EVENT0);

    //清除计时器寄存器
    HWREG (GPT0_BASE + GPT_O_CTL)= 0;
    HWREG (GPT0_BASE + GPT_O_TAMR)= 0;
    HWREG (GPT0_BASE + GPT_O_TAPR)= 0;
    HWREG (GPT0_BASE + GPT_O_TBPR)= 0;
    HWREG (GPT0_BASE + GPT_O_TBMR)= 0;
    HWREG (GPT0_BASE + GPT_O_CFG)= 0x00000004;// 16位模式中的定时器

    TimerConfigure (GPT0_BASE、TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME_UP);
    TimerPrescaleSet (GPT0_BASE、TIMER_A、255);
    TimerEventControl (GPT0_BASE、TIMER_A、TIMER_EVENT_POS_EDGE | TIMER_EVENT_NEG_EDGE);
    TimerIntClear (GPT0_BASE、TIMER_CAP_EVENT);
    TimerIntEnable (GPT0_BASE、TIMER_CAP_EVENT);
    TimerIntRegister (GPT0_BASE、TIMER_A、GPT0_A_ISR);
    TimerEnable (GPT0_BASE、TIMER_A);
    ///----------------------------------------------------------
    ///----------------------------------------------------------

    中断处理程序:
    空 GPT0_A_ISR (UARg x)

    TimerIntClear (GPT0_BASE、TIMER_CAP_EVENT);
    uint32_t tick_now =(uint32_t)((HWREG (GPT0_BASE + GPT_O_TAPR)& 0x000000FF)<< 16)+ HWREG (GPT0_BASE + GPT_O_TAR);
    uint32_t ***;

    如果(tick_now < LAST_ACTIVE_TICKs)

    //这似乎不起作用,因为我收到意外的长脉冲,我怀疑是在计时器重置时发生的,但我无法确认。
    PULSE_DURATION =(0x00FFFFFF - LAST_ACTIVE_TICKs)+ TICK;

    其他

    //与0x00FFFFFF 进行 AND 运算,以确保我们不会在较高的两个半字节中错误地放置任何内容
    PULSE_DURATION =(tick_now - LAST_ACTIVE_TICKs)& 0x00FFFFFF;


    //store 脉冲= PULSE_DURATION / 48
    //收集 X 个脉冲之后
    //禁用中断
    //处理脉冲
    //复位脉冲
    //启用中断

    //存储最后一个刻度
    LAST_ACTIVE_TICKs = tick_now;


    此处是预期脉冲和我所得到脉冲(预期/接收)的快照、供参考
    720/529
    885/561
    2070/537
    885/906
    1440/1446.
    885/906
    1350/1354.
    885/906
    810/737
    885/357
    900/709.
    885/382.
    1260/1079
    885/834
    1080/943

    我希望出现某种程度的误差、并且脉冲模式显然有相似之处、但我看到的误差裕度是不可接受的。

    有人能建议我还可以尝试什么吗?
    此时、我不确定代码是否有问题、或者我的硬件设置是否有问题。
    我尝试过两种不同的红外传感器、我接收到的脉冲非常相似。

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

    经过大量的试错、我遵循了 sensortag_cc2650stk 示例中的计时器概念、现在我能够获得准确的时间戳。
    参考:

    启用计时器:
    hIrDataPin = PIN_OPEN (&pinIrDataState、IrPinTable);

    Power_setDependency (PowerCC26XX_Periph_GPT0);
    power_setConstraint (PowerCC26XX_SB_disallow);

    TimerConfigure (GPT0_BASE、TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME_UP);

    PINCC26XX_setMux (hIrDataPin、XPERT_PIN_IR_DATA、IOC_PORT_MCU_PORT_EVENT0);

    TimerLoadSet (GPT0_BASE、TIMER_A、0);
    TimerPrescaleSet (GPT0_BASE、TIMER_A、0x000000FF);/255
    TimerEventControl (GPT0_BASE、TIMER_A、XPERT_GPT0_INTERRUPT_EDGE);
    TimerIntClear (GPT0_BASE、TIMER_CAP_EVENT);
    TimerIntEnable (GPT0_BASE、TIMER_CAP_EVENT);
    TimerIntRegister (GPT0_BASE、TIMER_A、IR_TimerInterrupt_Handler);
    TimerEnable (GPT0_BASE、TIMER_A);

    ISR 处理程序:
    TimerIntClear (GPT0_BASE、TIMER_CAP_EVENT);
    uint32_t tick_now =(uint32_t)((HWREG (GPT0_BASE + GPT_O_TAPR)& 0x000000FF)<< 16)+ HWREG (GPT0_BASE + GPT_O_TAR);

    完成后禁用计时器:
    TimerDisable (GPT0_BASE、TIMER_A);

    if (hIrDataPin!=空)

    PINCC26XX_setMux (hIrDataPin、XPERT_PIN_IR_DATA、IOC_PORT_GPIO);

    PIN_CLOSE (hIrDataPin);
    hIrDataPin =空;


    POWER_releaseDependency (PowerCC26XX_Periph_GPT0);
    power_releaseConstraint (PowerCC26XX_SB_disallow);

    我希望这一点得到更好的记录、上面的希望将帮助其他人