对于pic18f,在C中延迟x微秒

Hug*_*orx 2 c embedded assembly delay pic18

我需要一个用C编写的精确时间延迟函数,它将pic程序执行延迟给定的微秒数.我确实在microchipc.com上找到了一个使用ASM的例子,但代码只允许时钟速度高达32000000.我的时钟速度需要64000000,但由于我不明白代码是如何工作的我无法修改它做我需要的.任何人都可以提供一些代码的解释或建议如何实现类似的东西?

#if PIC_CLK == 4000000
  #define DelayDivisor 4
  #define WaitFor1Us asm("nop")
  #define Jumpback asm("goto $ - 4") 
#elif PIC_CLK == 8000000
  #define DelayDivisor 2
  #define WaitFor1Us asm("nop")
  #define Jumpback asm("goto $ - 4")
#elif PIC_CLK == 16000000
  #define DelayDivisor 1
  #define WaitFor1Us asm("nop")
  #define Jumpback asm("goto $ - 4")
#elif PIC_CLK == 20000000
  #define DelayDivisor 1
  #define WaitFor1Us asm("nop"); asm("nop")
  #define Jumpback asm("goto $ - 6")
#elif PIC_CLK == 32000000
  #define DelayDivisor 1
  #define WaitFor1Us asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop")
  #define Jumpback asm("goto $ - 12")
#else
#error delay.h - please define PIC_CLK correctly
#endif

#define DelayUs(x) { \
delayus_variable=(unsigned char)(x/DelayDivisor); \
asm("movlb (_delayus_variable) >> 8"); \
WaitFor1Us; } \
asm("decfsz (_delayus_variable)&0ffh,f"); \
Jumpback;
Run Code Online (Sandbox Code Playgroud)

pax*_*blo 6

在我看来这个部分:

#elif PIC_CLK == 16000000
  #define DelayDivisor 1
  #define WaitFor1Us asm("nop")
  #define Jumpback asm("goto $ - 4")
#elif PIC_CLK == 20000000
  #define DelayDivisor 1
  #define WaitFor1Us asm("nop"); asm("nop")
  #define Jumpback asm("goto $ - 6")
#elif PIC_CLK == 32000000
  #define DelayDivisor 1
  #define WaitFor1Us asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop")
  #define Jumpback asm("goto $ - 12")
Run Code Online (Sandbox Code Playgroud)

每增加400万PIC_CLK,你需要另外一条nop指令.

我没有使用过早期的那些因为它们只是在较低的时钟速度下使用缩放功能 - 因为你不能执行一半或四分之一nop,它们只是将循环计数减少到一半或四分之一并执行nop多次完整.

因此,对于6400万(比上一个多3200万),你需要另外8个nop指令(3200万除以400万),并且每个指令将跳跃大小增加2(PIC18F具有2字节指令宽度) ,你应该能够使用以下内容:

#elif PIC_CLK == 32000000
  #define DelayDivisor 1
  #define WaitFor1Us asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop")
  #define Jumpback asm("goto $ - 12")
#elif PIC_CLK == 64000000
  #define DelayDivisor 1
  #define WaitFor1Us asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop") \
                     asm("nop"); asm("nop"); asm("nop"); asm("nop"); \
                     asm("nop"); asm("nop"); asm("nop"); asm("nop");
  #define Jumpback asm("goto $ - 28")
#else
#error delay.h - please define PIC_CLK correctly
#endif
Run Code Online (Sandbox Code Playgroud)

总之,这些是每个PIC_CLK值所需的值,即下一代更快的概率:

PIC_CLK    Divisor  NOP count  Jump size
---------  -------  ---------  ---------
  1000000       16          1          4
  2000000        8          1          4
  4000000        4          1          4
  8000000        2          1          4
 16000000        1          1          4
 20000000        1          2          6
 24000000        1          3          8
 28000000        1          4         10
 32000000        1          5         12
 64000000        1         13         28
 96000000        1         21         44
128000000        1         29         60
Run Code Online (Sandbox Code Playgroud)

或者,如果您希望公式的值大于或等于1600万:

divisor = 1
nopcount = picclk / 4000000 - 3
jumpsize = nopcount * 2 + 2
Run Code Online (Sandbox Code Playgroud)