MCC18、48Mhz、18F87J50 中的延迟

发布于 2024-08-16 00:55:05 字数 237 浏览 11 评论 0原文

我应该如何为带有 48MHz 晶振的 PIC 18f87J50 编写延迟宏 和MCC18的编译器。延迟应该在我们身上。所以我可以写:Delay_us(201) 并确实得到了 201us 的延迟。

我现在所拥有的是:

#define Delay_us(n) (Delay10TCYx(((n) * (uint16_t) 12 + 9) / 10))

在我的示波器上它似乎不正确! :/

How should I write a delay macro for an PIC 18f87J50 with a 48MHz crystal
and compiler of MCC18. The delay should be in us. So I for example can write: Delay_us(201)
and really get 201us delay.

What I have now is:

#define Delay_us(n) (Delay10TCYx(((n) * (uint16_t) 12 + 9) / 10))

And it doesn't seem right at my oscilloscope! :/

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

恬淡成诗 2024-08-23 00:55:05

PIC 将时钟除以 4,因此对于 48Mhz,每个操作码以 0.0833us 或每 us 12 个周期运行。我使用 MPLAB 并输入不同的 us 值并在模拟器中进行检查,以便周期数符合我的预期。调整功能的最好方法是看组件或使用模拟器。

您可以执行类似以下操作,但您必须调整编译器的函数调用。

#define OVERHEAD (2)

void Delay_us(uint8_t us)
{
   if ( us <= OVERHEAD ) return; // prevent underflow
   us  -= OVERHEAD ;             // overhead of function call in us.

   Nop();       // 1  extra overhead to make function overhead an even us.
   Nop();       // 1  add or remove Nop's as necessary.
   Nop();       // 1
   //Nop();       // 1
   //Nop();       // 1
   //Nop();       // 1
   //Nop();       // 1
   //Nop();       // 1
   //Nop();       // 1
   //Nop();       // 1
   //Nop();       // 1
   //Nop();       // 1

   do   // loop needs to be 12 cycles so each cycle is 1us.
   {
      Nop();       // 1
      Nop();       // 1
      Nop();       // 1
      Nop();       // 1
      Nop();       // 1
      Nop();       // 1
      Nop();       // 1
      Nop();       // 1
      ClrWdt();    // 1
   } while(--us);  // 3
}

The PIC divides the clock by 4 so for 48Mhz each opcode runs in 0.0833us or 12 cycles per us. I used MPLAB and put in different us values and checked in the simulator so that the number of cycles came out as I expected. The best way to adjust the function is to look at the assembly or use the simulator.

You can do something like the following but you will have to adjust the function call for your complier.

#define OVERHEAD (2)

void Delay_us(uint8_t us)
{
   if ( us <= OVERHEAD ) return; // prevent underflow
   us  -= OVERHEAD ;             // overhead of function call in us.

   Nop();       // 1  extra overhead to make function overhead an even us.
   Nop();       // 1  add or remove Nop's as necessary.
   Nop();       // 1
   //Nop();       // 1
   //Nop();       // 1
   //Nop();       // 1
   //Nop();       // 1
   //Nop();       // 1
   //Nop();       // 1
   //Nop();       // 1
   //Nop();       // 1
   //Nop();       // 1

   do   // loop needs to be 12 cycles so each cycle is 1us.
   {
      Nop();       // 1
      Nop();       // 1
      Nop();       // 1
      Nop();       // 1
      Nop();       // 1
      Nop();       // 1
      Nop();       // 1
      Nop();       // 1
      ClrWdt();    // 1
   } while(--us);  // 3
}
提笔书几行 2024-08-23 00:55:05

部分不准确可能是由于对计算传递给Delay10TCYx 的值的表达式进行求值造成的。由于该表达式包含除法,因此控制器可能需要相当长的时间来计算该值。

Part of the inaccuracy might be due to the evaluation of the expression that calculates the value that is passed to Delay10TCYx. Since this expression contains a division, it can take quite some time for the controller to calculate that value.

森林迷了鹿 2024-08-23 00:55:05

MCC 手册解释了创建延迟循环所涉及的非常简单的数学。您可以实现自己的循环,而不是依赖库延迟函数。

The MCC manual explains the very simple math that is involved in creating delay loops. You can just implement your own loop instead of relying on library delay functions.

楠木可依 2024-08-23 00:55:05

我发现这使我的延迟更加准确:

void Delay_uS(byte uSec) {

   do {
       Delay1TCY();            // 1
       Delay1TCY();            // 1
       Delay1TCY();            // 1
       Delay1TCY();            // 1
       Nop();                        // 1
       Nop();                        // 1
       Nop();                        // 1
       ClrWdt();                        // 1; Clear the WDT
       } while(--uSec);        // 3
}

对此还有其他想法或回复吗?

感谢 Dario G 在...另一个论坛;)

I found that this made my delay us much more accurate:

void Delay_uS(byte uSec) {

   do {
       Delay1TCY();            // 1
       Delay1TCY();            // 1
       Delay1TCY();            // 1
       Delay1TCY();            // 1
       Nop();                        // 1
       Nop();                        // 1
       Nop();                        // 1
       ClrWdt();                        // 1; Clear the WDT
       } while(--uSec);        // 3
}

Any other Ideas or replys regarding this?

Thanks to Dario G at.... another forum ;)

逆光飞翔i 2024-08-23 00:55:05

我听说这会更准确,但我的示波器只是给我其他正确的值。当我编译的时候它会做一些事情吗?我不是在最高等级做的吗?

#define CONST_RANGE(min, val, max) (sizeof(char (*)[(val) >= (min) && (val) <= (max) ? +1 : -1]), (val))
#define Delay_ms(n) Delay1KTCYx(CONST_RANGE(1, (n) * 12L, 255))
#define Delay_us(n) Delay10TCYx(CONST_RANGE(1, ((n) * 12L + 6) / 10, 255))

I heard this would be even more accurate, but my ocsilloscope just give me other values then right. Could it have something to do when I'm compiling?? That im not doing it at the highest lvl??

#define CONST_RANGE(min, val, max) (sizeof(char (*)[(val) >= (min) && (val) <= (max) ? +1 : -1]), (val))
#define Delay_ms(n) Delay1KTCYx(CONST_RANGE(1, (n) * 12L, 255))
#define Delay_us(n) Delay10TCYx(CONST_RANGE(1, ((n) * 12L + 6) / 10, 255))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文