一、指令数延时(浪费cpu资源)
受系统频率影响,同样的语句,实际延时时间波动很大
void delay(unsigned int);
delay(100); //执行100个nop
二、按照系统时钟换算指令数延时(浪费cpu资源)
// 小于10us的执行不精准,不同系统频率下需要自行调整div值
AT_VOLATILE_RAM_CODE
void delay_us_by_nop(u32 usec)
{
u32 sys = clk_get("sys");
u32 cnt, div;
if(usec == 1) { div = 30;}
else if(usec == 2){ div = 12;}
else if(usec == 3){ div = 8; }
else if(usec < 10){ div = 6; }
else { div = 5; }
cnt = usec * (sys / 1000000L / div);
while(cnt--){ asm volatile("nop"); }
}
int clk_set_sys_lock(int clk, int lock_en);
extern void clk_set_en(u8 en);
clk_set_en(0); 可执行此函数,锁住系统频率不被修改。
三、定时器计算延时(浪费cpu资源)延时要大于5us
函数是AC632 - BD19的寄存器写法,其他芯片参考sdk对应工程的写法
//有概率会被中断打断,导致延时变大
AT_VOLATILE_RAM_CODE
void delay_us_by_timer0(u32 usec)
{
usec -= 2; //usec > 5,减掉此函数执行本身的耗时,48M->2us,24M->5us
JL_TIMER0->CON = BIT(14);
JL_TIMER0->CNT = 0;
JL_TIMER0->PRD = clk_get("lsb") / 2 / 1000000L * usec;
JL_TIMER0->CON = BIT(0) | BIT(6); //lsb clk 2分频
while ((JL_TIMER0->CON & BIT(15)) == 0);
JL_TIMER0->CON = BIT(14);
}
//关中断,临界区延时
AT_VOLATILE_RAM_CODE
void delay_us_by_timer0_irq(u32 usec)
{
usec -= 2; //usec > 5,减掉此函数执行本身的耗时,48M->2us,24M->5us
local_irq_disable();
JL_TIMER0->CON = BIT(14);
JL_TIMER0->CNT = 0;
JL_TIMER0->PRD = clk_get("lsb") / 2 / 1000000L * usec;
JL_TIMER0->CON = BIT(0) | BIT(6); //lsb clk 2分频
while ((JL_TIMER0->CON & BIT(15)) == 0);
JL_TIMER0->CON = BIT(14);
local_irq_enable();
}
//ms级延时,一般要求不需要精准,不用加关中断
AT_VOLATILE_RAM_CODE
void delay_ms_by_timer0(u32 msec)
{
JL_TIMER0->CON = BIT(14);
JL_TIMER0->CNT = 0;
JL_TIMER0->PRD = clk_get("lsb") / 64 / 1000L * msec;
JL_TIMER0->CON = BIT(0) | BIT(5) | BIT(4); //lsb clk 64分频
while ((JL_TIMER0->CON & BIT(15)) == 0);
JL_TIMER0->CON = BIT(14);
}
四、系统调度延时(不浪费CPU资源)单位:10ms
void os_time_dly(int time_tick);
os_time_dly(1); //参数1,即延时10ms,会切出当前任务,执行其他任务
小于10ms的延时方式,都会浪费CPU资源。
任务调度延时,只有10ms单位的,改不了 <10ms 的单位。
其他
//注意,不加volatile 实现不了
void my_delay(u32 num)
{
volatile counter = 0;
while(counter < num)
{
counter++;
}
}