c - pic18f在C中的延迟x微秒

标签 c assembly embedded 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;

最佳答案

在我看来,从这一部分来看:

#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")


也就是说,PIC_CLK每增加400万,您就需要另外一条nop指令。

我没有使用较早的版本,因为它们只是在较低的时钟速度下使用缩放功能-由于您不能执行nop的一半或四分之一,因此它们只是将循环计数减少到一半或四分之一,然后执行完整的< cc>多次。

因此,对于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


总之,这些是每个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


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

divisor = 1
nopcount = picclk / 4000000 - 3
jumpsize = nopcount * 2 + 2

关于c - pic18f在C中的延迟x微秒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4747511/

相关文章:

c - Sparkfun SC16IS750 不适用于 Raspberry Pi

C函数指针赋值

c++ - 将 4 个原始字节转换为 32 位 float

c - 如何跟踪二进制文件中的项目

c++ - 找出几个对象的最大尺寸以放置新的

assembly - NASM:计算 32 位数字中有多少位设置为 1

debugging - DOS DEBUG 跟踪命令无法按我的预期工作

c - 如何在c中添加char类型整数

c - 输出错误重定向(关于stderr)

c - 为什么不能将 asm 中调用 c 库 printf 的 stdout 传送到其他程序?