3

我正在使用带有 HiTech ANSI C 编译器和 MPLAB v8.43 的 PIC18F14K50。我的 PIC 代码终于启动并运行和工作,除了延迟功能。这对我的应用程序至关重要——我需要它在给定的毫秒、秒或分钟数内处于某些状态。

我一直试图为此找到解决方案大约 2 周,但到目前为止还没有成功。我放弃并asm("nop");在循环中编写了自己的延迟函数,但这会产生非常不可预测的结果。如果我告诉它等待半秒或 5 秒,它就足够准确了。但是,一旦我告诉它等待更长的时间——比如 10 分钟,延迟只会持续大约 10 到 20 秒,而 2 分钟以上是比 500 毫秒延迟更短的眨眼。

这是我的配置保险丝和wait()功能:

#include <htc.h>

__CONFIG(1, FOSC_IRC   & FCMEN_OFF & IESO_OFF & XINST_OFF);
__CONFIG(2, PWRTEN_OFF & BOREN_OFF & WDTEN_OFF);
__CONFIG(3, MCLRE_OFF);
__CONFIG(4, STVREN_ON  & LVP_OFF   & DEBUG_OFF);
__CONFIG(5, 0xFFFF);
__CONFIG(6, 0xFFFF);
__CONFIG(7, 0xFFFF);

void wait(int ms)
{
  for (int i = 0; i < ms; i++)
    for (int j = 0; j < 12; j++)
      asm("nop");
}

就像我说的那样,如果我打电话wait(500)到那wait(30000)我会得到半秒到 30 秒的延迟到我感兴趣的容差范围内 - 但是如果我打电话wait(600000)那么我不会像我期望的那样延迟 10 分钟,而是大约 10-15 秒,wait(120000)不会延迟 2 分钟,而是快速眨眼。

理想情况下,我想让内置__delay_ms()函数工作并从我的内部调用wait(),但是我没有取得任何成功。如果我尝试这样做,#include <delay.h>那么我的 MPLAB 会抱怨没有这样的文件或目录。如果我查看 HiTech 示例中的 delay.h ,有一个已DelayUs(unsigned char)定义的和一个extern void DelayMs(unsigned char)我没有尝试过的,但是当我尝试将 extern 直接放入我的 C 代码中时,在链接时出现未定义的符号错误。

中短延迟和长延迟之间的差异是没有意义的。我唯一的解释是编译器已经优化了 NOP 或其他东西。

就像我说的,它是带有上述配置保险丝的 PIC18F14K50。我对 PIC 没有太多经验,但我认为它在这种设置下运行在 4MHz。

我对来自库或宏的外部函数或带有 NOP 的手写函数感到满意。我所需要的只是让它精确到每分钟几秒钟左右。

4

3 回答 3

4

PIC 是 16 位微控制器吗?我的猜测是你在等待的值上溢出,它会在 2^15 之后溢出(32,767 是有符号的 16 位 int 的最大值)。

于 2012-04-12T04:35:50.847 回答
3

如果将int变量更改为unsigned,则最多可以达到 65535 毫秒。要高于此,您需要使用long作为参数类型并将循环嵌套得更深。

于 2012-04-12T04:42:46.013 回答
1

一个更好的长期解决方案是编写一个延迟函数,该函数使用芯片中的一个内置硬件定时器。如果您有其他中断触发和使用一些 CPU 周期等情况,您的 NOP 延迟将不会在很长一段时间内准确

于 2012-04-12T21:26:14.593 回答