先上代码
static void DelayLoop(uint32_t count)
{
__ASM volatile(" MOV R0, %0" : : "r"(count));
__ASM volatile(
"loop: \n"
#if defined(__GNUC__) && !defined(__ARMCC_VERSION)
" SUB R0, R0, #1 \n"
#else
" SUBS R0, R0, #1 \n"
#endif
" CMP R0, #0 \n"
" BNE loop \n"
:
:
: "r0");
}
void SDK_DelayAtLeastNs(uint32_t delayTime_ns, uint32_t coreClock_Hz)
{
uint64_t count;
if (delayTime_ns > 0U)
{
count = delayTime_ns;
//NSEC_TO_COUNT(delayTime_ns, coreClock_Hz);
assert(count <= UINT32_MAX);
#if defined(SDK_DELAY_USE_DWT) && defined(DWT) /* Use DWT for better accuracy */
enableCpuCycleCounter();
/* Calculate the count ticks. */
count += getCpuCycleCount();
if (count > UINT32_MAX)
{
count -= UINT32_MAX;
/* Wait for cyccnt overflow. */
while (count < getCpuCycleCount())
{
}
}
/* Wait for cyccnt reach count value. */
while (count > getCpuCycleCount())
{
}
#else
/* Divide value may be different in various environment to ensure delay is precise.
* Every loop count includes three instructions, due to Cortex-M7 sometimes executes
* two instructions in one period, through test here set divide 1.5. Other M cores use
* divide 4. By the way, divide 1.5 or 4 could let the count lose precision, but it does
* not matter because other instructions outside while loop is enough to fill the time.
*/
#if (__CORTEX_M == 7)
count = count / 3U * 2U;
#else
count = count / 4U;
#endif
DelayLoop((uint32_t)count);
#endif /* defined(SDK_DELAY_USE_DWT) && defined(DWT) */
}
}
RT1176的 SDK提供了 us级别的阻塞延时,但是我的应用:点亮ws2812b,需要ns的延时
所以我想在SDK的基础上修改,但是发现自己的修改并不准确
所以用了最老土的办法,手动修改,然后测量,再修改…
最后得出下面的数据,分别是延时800ns和400ns
#define BIT0 do{GPIO_PinWrite(WS2812B_DATA_GPIO, WS2812B_DATA_PIN, 1U);\
SDK_DelayAtLeastNs(110, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);\
GPIO_PinWrite(WS2812B_DATA_GPIO, WS2812B_DATA_PIN, 0U);\
SDK_DelayAtLeastNs(280, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);}while(0)
#define BIT1 do{GPIO_PinWrite(WS2812B_DATA_GPIO, WS2812B_DATA_PIN, 1U);\
SDK_DelayAtLeastNs(280, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);\
GPIO_PinWrite(WS2812B_DATA_GPIO, WS2812B_DATA_PIN, 0U);\
SDK_DelayAtLeastNs(110, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);}while(0)
最后附带一下发送的函数
void Write()
{
for(uint8_t j=0;j<48;j++)
{
uint32_t temp = Board_Color[j];
for(uint8_t i=0;i<24;i++)
{
if((temp&0x800000) != 0)
{
BIT1;
}
else
{
BIT0;
}
temp<<=1;
}
}
}