STM32在FreeRTOS下的us延时

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 提供的调度器开关函数,如果某个任务调用了调度锁开关函数,处于调度锁开和调度锁关之间的代码在执行期间是不会被高优先级的任务抢占的,即任务调度被禁止。这一点要跟临界段的作用区分开,调度锁只是禁止了任务调度,并没有关闭任何中断,中断还是正常执行的。而临界段进行了开关中断操作。
打开调度锁(禁止任务调度)

c 复制代码
vTaskSuspendAll()

关闭调度锁(允许任务调度)

c 复制代码
xTaskResumeAll(void)

步骤3、4、5

获取当前滴答定时器的重装载值可以通过读取LOAD寄存器实现

c 复制代码
told=SysTick->VAL; 

读取当前计数值通过寄存器VAL实现

c 复制代码
tnow=SysTick->VAL;	

实现代码

c 复制代码
//nus为要延时的us数.		    								   
void delay_us(u32 nus)
{		
	u32 ticks;
	u32 told,tnow,tcnt=0;
	u32 reload=SysTick->LOAD;						//LOAD的值	    	 
	ticks=nus*(SystemCoreClock/1000000); 	//需要的节拍数	  		 
	tcnt=0;
	vTaskSuspendAll();									//阻止OS调度,防止打断us延时
	told=SysTick->VAL;        					//刚进入时的计数器值
	while(1)
	{
		tnow=SysTick->VAL;	
		if(tnow!=told)
		{	    
			if(tnow<told)tcnt+=told-tnow;		//这里注意一下SYSTICK是一个递减的计数器就可以了.
			else tcnt+=reload-tnow+told;	    
			told=tnow;
			if(tcnt>=ticks)break;						//时间超过/等于要延迟的时间,则退出.
		}  
	};
	xTaskResumeAll();										//恢复OS调度									    
}
相关推荐
Messy create2 小时前
【BMS-AFE-温度检测】
stm32·单片机·能源
东莞市永盛电气2 小时前
三相208V变380V变压器,出海工业设备供电适配方案
python·单片机·嵌入式硬件
桃蹊、3 小时前
串口/网络透传实战:FreeRTOS 多任务架构与连接池设计
stm32·物联网·wifi·freertos
Learn-Share_HY3 小时前
[IT Network]如何配置反向路徑過濾器(rp_filter),以解決路由不對稱問題?
linux·嵌入式硬件·物联网·网络协议·tcp/ip·http·iot
深圳市宝华视联4 小时前
医院内网部署手术示教系统注意事项
嵌入式硬件·实时互动·音视频·实时音视频·视频编解码·嵌入式实时数据库
新晨单片机设计5 小时前
S001A-基于STM32单片机超声波视力保护仪【Proteus仿真+Keil程序+原理图】
stm32·单片机·proteus
星河单片机5 小时前
STM32驱动Y01-3IN1空气质量模块+OLED显示完整教程
stm32·单片机·嵌入式硬件·空气质量·甲醛检测·二氧化碳检测·tvoc检测
宣宣猪的小花园.5 小时前
【控制算法】PID 不只是三个参数:比例、积分、微分各在解决什么问题
人工智能·嵌入式硬件·机器学习
玩转单片机与嵌入式5 小时前
深入浅出TinyML 21:INT8量化改变了模型中的哪些数据?
stm32·深度学习·tinyml
别催小唐敲代码5 小时前
stm32_mpu6050_滤波教程
stm32·单片机·嵌入式硬件