网站建设书,公司网站建设网站优化网络推广,企业做网站大概需要多少钱,龙岩新罗区建设局网站STM32在FreeRTOS下的us延时
前言
freeRTOS下跑SPI时需要微秒级别的延时#xff0c;但是freeRTOS只提供了毫秒级的#xff0c;记录一下实现us延时的方法。
前期分析
最简单的方式就是开个定时器或者干脆直接计算一下用nop做都可以实现us延时#xff0c;但是显然还是使用滴…STM32在FreeRTOS下的us延时
前言
freeRTOS下跑SPI时需要微秒级别的延时但是freeRTOS只提供了毫秒级的记录一下实现us延时的方法。
前期分析
最简单的方式就是开个定时器或者干脆直接计算一下用nop做都可以实现us延时但是显然还是使用滴答定时器更为优雅。 滴答定时器SysTick挂在NVIC上是一个24位的减数定时器通过STK_LOAD寄存器控制其重装载值STK_VAL寄存器存储了当前的计数值因此实现思路如下 1、计算延时器件要计的计数值 2、关闭任务调度防止延时的时候被任务调度器打断 3、获取当前重装载值当触发了重装载以后计算需要使用 4、获取开始延时时寄存器里面的计数值 5、不断获取当前的计数值 6、当当前计数值大于需要计的计数值时退出延时
步骤1
滴答定时器SysTick的时钟输入为HCLK的八分频则其最小频率也大于1MHZ因此直接拿其时钟频率除1M则可以得到计时1us所需要的计数值通过与目标延时时间单位为us相乘即可以得到总计数时间。
步骤2
任务调度的开关需要使用到调度锁其概念如下 调度锁就是 RTOS 提供的调度器开关函数如果某个任务调用了调度锁开关函数处于调度锁开和调度锁关之间的代码在执行期间是不会被高优先级的任务抢占的即任务调度被禁止。这一点要跟临界段的作用区分开调度锁只是禁止了任务调度并没有关闭任何中断中断还是正常执行的。而临界段进行了开关中断操作。 打开调度锁禁止任务调度
vTaskSuspendAll()关闭调度锁允许任务调度
xTaskResumeAll(void)步骤3、4、5
获取当前滴答定时器的重装载值可以通过读取LOAD寄存器实现
toldSysTick-VAL; 读取当前计数值通过寄存器VAL实现
tnowSysTick-VAL; 实现代码
//nus为要延时的us数.
void delay_us(u32 nus)
{ u32 ticks;u32 told,tnow,tcnt0;u32 reloadSysTick-LOAD; //LOAD的值 ticksnus*(SystemCoreClock/1000000); //需要的节拍数 tcnt0;vTaskSuspendAll(); //阻止OS调度防止打断us延时toldSysTick-VAL; //刚进入时的计数器值while(1){tnowSysTick-VAL; if(tnow!told){ if(tnowtold)tcnttold-tnow; //这里注意一下SYSTICK是一个递减的计数器就可以了.else tcntreload-tnowtold; toldtnow;if(tcntticks)break; //时间超过/等于要延迟的时间,则退出.} };xTaskResumeAll(); //恢复OS调度
}