我需要用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/