c - PIC32MZ 上的 Microchip Harmony 时序问题

标签 c performance timer interrupt pic32

我正在使用 MPLABX + Harmony 框架为 PIC32MZ1024EFK064 编写代码。

我的目标是,每微秒触发一次 ISR。 为了对此进行测试,我在 ISR 的 1000000 次循环后切换 LED:

uint32_t xxx = 0;

void __ISR(_TIMER_2_VECTOR, ipl1AUTO) IntHandlerDrvTmrInstance0(void)
{

    xxx++;

    if(xxx > 1000000){

        xxx = 0;
        blink();

    }

    PLIB_INT_SourceFlagClear(INT_ID_0,INT_SOURCE_TIMER_2);

}

Timer2 以 80MHz 的频率运行,预分频器为 1,定时器周期为 80。

在我的第一次尝试中,LED 每 4 秒切换一次(ISR = 每 4us)。

我发现通过将 PBCLK7 的后分频器从 2 更改为 1,我可以达到 2 秒。 (现在 CPU 核心运行在 160MHz 而不是 80MHz)。

但即使我将定时器周期更改为 1,我的 LED 也只会每 2 秒切换一次。

知道如何进一步加快速度吗?

更新:

子例程 blink() 太慢了。 直接操作Register,工作在1us

void __ISR(_TIMER_2_VECTOR, ipl1AUTO) IntHandlerDrvTmrInstance0(void)
{
    LATBINV = 1<<8;
    PLIB_INT_SourceFlagClear(INT_ID_0,INT_SOURCE_TIMER_2);
}

最佳答案

我对那个特定的微 Controller 不是很熟悉,但我经常使用 Microchip PIC,所以这里有一些你可能想看看的要点:

1- 首先确保您的时钟(CPU 和 PBCLK)确实以您认为的速度运行。您通常可以在外部引脚上输出一些内部时钟(通常是 PIC32 上的 REFCLKO)。这样您就可以使用示波器测量它们并确保它们的配置正确。

2- 确保最小化中断的内部执行时间。检查 PLIB_INT_SourceFlagClear() 是一个类似宏的函数还是一个实际的函数调用。如果这是一个函数调用,您可能希望在寄存器级别工作以避免这种开销。

3- 启用编译器优化。顺便说一句,在中断中使用全局变量将其声明为 volatile (或在中断处理程序函数中声明为静态)也是一种很好的做法。

4- 除非 Microchip 明确记录,否则请验证您是否应该在中断处理程序开始而不是结束时清除中断。在你的情况下可能会发生什么,特别是如果你将它的周期设置为很短的时间,你的计时器会再次到期,而你仍然在你的中断处理程序中但在你清除它的标志之前。这将导致在您的中断再次触发之前有额外的延迟。你想要的是尽快清除标志,这样如果计时器再次到期,它会设置标志,这将导致你的中断处理程序在完成执行后立即再次触发。当然,这不会给您的后台应用程序任何时间来执行……

5- 我还假设您的计时器已正确配置,即当周期到期时它会将其内部计数重新加载为 0,但请查看以确保情况确实如此。

弗兰克

关于c - PIC32MZ 上的 Microchip Harmony 时序问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44912896/

相关文章:

c - 未知类型名称 'clockid_t'

C - 链表 - 删除节点

c - 按网络顺序将无符号字节数组直接写入 ip.ip_dest 是否安全?

c++ - 找不到 Libcurl OpenSSL

css - 大小单位 : rem, em 和 px 之间的速度测试

java - 计划作业上的 ScheduledExecutorService、timerService 和无状态 EJB

timer - 为什么Arduino在millis函数中每1.024ms使用一次中断?

c - 如何在 C 中使虚拟 shell 不接受任何参数?

performance - Nativescript 导航非常慢

javascript - 有没有更有效的方法在 jQuery 中添加和删除类?