解决FreeRTOS下systick系统定时器延时不精准--STM32F4 FreeRTOS下通过DWT实现精确us延时

前言

因为在FreeRTOS项目的练习中,使用到了DTH11温湿度传感器,这是一个单总线驱动的传感器,在驱动的过程中对延时的精确要求比较高,并且需要使用us级的延时。FreeRTOS中并没有现成的us级延时可供使用,起初我用的是裸机中使用的systick系统定时器,但是上系统后就无法正常驱动DTH11了。

代码

#include "delay.h" 

#define SYS_DWT_DELAY 0 /* 0为DWT延时 1为系统定时器延时*/

#if SYS_DWT_DELAY 1
static u8  fac_us=0;//us延时倍乘数
static u16 fac_ms=0;//ms延时倍乘数
//初始化延迟函数
//SYSTICK的时钟固定为HCLK时钟的1/8
//SYSCLK:系统时钟
void delay_init(u8 SYSCLK)
{
	SysTick->CTRL&=0xfffffffb;//bit2清空,选择外部时钟  HCLK/8
	fac_us=SYSCLK/8;		    
	fac_ms=(u16)fac_us*1000;
}	

//延时nms
//注意nms的范围
//SysTick->LOAD为24位寄存器,所以,最大延时为:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK单位为Hz,nms单位为ms
//对72M条件下,nms<=1864 
void delay_ms(u16 nms)
{	 		  	  
	u32 temp;		   
	SysTick->LOAD=(u32)nms*fac_ms;//时间加载(SysTick->LOAD为24bit)
	SysTick->VAL =0x00;           //清空计数器
	SysTick->CTRL=0x01 ;          //开始倒数  
	do
	{
		temp=SysTick->CTRL;
	}
	while(temp&0x01&&!(temp&(1<<16)));//等待时间到达   
	SysTick->CTRL=0x00;       //关闭计数器
	SysTick->VAL =0X00;       //清空计数器	  	    
}   

//延时nus
//nus为要延时的us数.		    								   
void delay_us(u32 nus)
{		
	u32 temp;	    	 
	SysTick->LOAD=nus*fac_us; //时间加载	  		 
	SysTick->VAL=0x00;        //清空计数器
	SysTick->CTRL=0x01 ;      //开始倒数 	 
	do
	{
		temp=SysTick->CTRL;
	}
	while(temp&0x01&&!(temp&(1<<16)));//等待时间到达   
	SysTick->CTRL=0x00;       //关闭计数器
	SysTick->VAL =0X00;       //清空计数器	 
}

#else

/*DWT 延时*/
void dwt_delay_init(void)
{
    CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; // 使能DWT
    DWT->CYCCNT = 0; // 清空计数器
    DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; // 使能CYCCNT
}

void delay_us(uint32_t nus)
{
    uint32_t ticks = nus * (SystemCoreClock / 1000000); // 将时间转换为时钟周期数
    uint32_t start = DWT->CYCCNT;
    while ((DWT->CYCCNT - start) < ticks); // 等待时间到达
}

void delay_ms(u16 nms)
{	 
	for(u16 i = 0; i < nms; i++)
		delay_us(1000);		    
} 

#endif
#ifndef __DELAY_H
#define __DELAY_H 		

#include "main.h"

void delay_init(u8 SYSCLK);
void dwt_delay_init(void);
void delay_ms(u16 nms);
void delay_us(u32 nus);

#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值