关于STM32F103精确延时

为了兼容FreeRTOS,所以将延时函数统一规范,后续使用方便移植。此延时针对无晶振,示例为系统倍频64MHz,型号:STM32F103C8T6。

新建SYSTEM文件夹,新增两个文件,delay.c和delay.h

以下为delay.c内容:其中系统已倍频为64M

#include "stm32f10x.h"

double  fac_us=0;								   						
static RCC_ClocksTypeDef  RCC_Clocks;	
void delay_init()
{
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);	//64M-->1us:64
	RCC_GetClocksFreq(&RCC_Clocks);
	fac_us=RCC_Clocks.SYSCLK_Frequency/1000000;//fac_us=64;		 
}								    
    								   
void delay_us(unsigned int nus)
{		
	u32 ticks;
	u32 told,tnow,tcnt=0;
	u32 reload=SysTick->LOAD;					  	 
	ticks=nus*fac_us; 					 		 
	tcnt=0;				
	told=SysTick->VAL;        				
	while(1)
	{
		tnow=SysTick->VAL;	
		if(tnow!=told)
		{	    
			if(tnow<told)tcnt+=told-tnow;		
			else tcnt+=reload-tnow+told;	    
			told=tnow;
			if(tcnt>=ticks)break;
		}  
	};								    
}

void delay_ms(unsigned short nms)
{		 						   
	delay_us((u32)(nms*1000));	
}

以下为delay.h内容

#ifndef _DELAY_H_
#define _DELAY_H_

void delay_us(unsigned int nus);
void delay_ms(unsigned short nms);
void delay_init(void);

#endif

以下大体解释:

1.对于delay_init函数,SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);这句主要设置Systick时钟源,对于为什么不能8分频,主要是为了和FreeRTOS统一。

2.RTOS统一节拍为1ms,所以延时函数里没有额外增加RTOS支持,对于ms级延时,直接调用操作系统的系统延时。


对于无操作系统调用:

void main()
{
    SystemClk_Init();//系统倍频64M
    ...
	while(SysTick_Config(64000)!=0);//1ms中断
	delay_init();
    ...
    while(1)
    {
        ...
    }
}

其中SysTick_Config()函数,主要是设置装载值,设置Systick时钟为系统主时钟,开启systick中断。delay_init()函数再次设置了systick时钟源为主时钟源。


对于FreeRTOS系统调用:

void main()
{
    SystemClk_Init();//系统倍频64M
    ...
	//while(SysTick_Config(64000)!=0);//1ms中断,此处可不加
	delay_init();
    ...
    xTaskCreate(...);
    vTaskStartScheduler();
}

测试:

针对FreeRTOS,分别建立两个任务,分别延时1S来翻转两个LED,其中任务一,用delay_us(1000000);任务二,用vTaskDelay(1000);测试结果正常,LED灯翻转时间相同。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页