STM32F407ZET6延时函数

        利用系统滴答定时器,实现单片机的精确延时。在ARM Cortex-M3和M4内核中有一个Systick定时器,它是一个24位的向下计数定时器,当计数到0时,它就会从Load寄存器中自动重装定时初值,只要不把CTRL寄存器中的ENABLE清0,它就永不停。

        Systick定时器常用来做精确延时,或者实时系统的心跳时钟。这样可以节省MCU资源,不用浪费一个定时器。

        精确延时的意义:在很多传感器中,延时需要精确到us,用来做一个启动信号,如果说延时不精确,很难捕捉到启动信号。

相关寄存器

 代码实现:

delay.h

#ifndef _DELAY_H_
#define _DELAY_H_
#include "stm32f4xx.h"

void delay_ms(uint32_t nms);

void delay_us(uint32_t nus);


#endif

delay.c

#include "delay.h"

//延时函数:毫秒级别
void delay_ms(uint32_t nms)
{
	uint32_t tmp;
	while(nms--)
	{
		SysTick->LOAD = 168000000/8/1000;	//计数初值,延时1ms
		SysTick->VAL = 0;					//清空当前值
		SysTick->CTRL |= 0x1;				//开始计数
		do
		{
			tmp = SysTick->CTRL;			//获取CTRL状态
		}while((tmp&0x1) && !(0x1<<16));

		SysTick->VAL = 0;					//清空当前值
		SysTick->CTRL &= 0;					//关闭计数
	}
}

//延时函数:微秒级别
void delay_us(uint32_t nus)
{
	uint32_t tmp;
	while(nus--)
	{
		SysTick->LOAD = 168000000/8/1000000;	//计数初值,延时1us
		SysTick->VAL = 0;					//清空当前值
		SysTick->CTRL |= 0x1;				//开始计数
		do
		{
			tmp = SysTick->CTRL;			//获取CTRL状态
		}while((tmp&0x1) && !(0x1<<16));

		SysTick->VAL = 0;					//清空当前值
		SysTick->CTRL &= 0;					//关闭计数
	}

}


main.c

#include <stm32f4xx.h>  //stm32标准头文件
#include "sys.h"
#include "delay.h"


//初始化led
void init_led(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	//开启GPIOF的时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;			
	//模式选择:输入、输出、复用、模拟
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;		//输出模式
	//类型选择:推挽、开漏
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;		//推挽模式
	//速度选择:低速、中速、快速、高速
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//高速模式
	//上下拉选择:无上下拉、上拉、下拉
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;	//无上下拉

	//初始化GPIOF
	GPIO_Init(GPIOF, &GPIO_InitStructure);

    GPIO_SetBits(GPIOF,GPIO_Pin_9);//初始状态设置为高电平,熄灭

}

int main(void)
{

	//设置嘀嗒定时器时钟源
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//用于配置延时函数
	
	init_led();

	while(1)
	{
        GPIO_ResetBits(GPIOF,GPIO_Pin_9);   //将引脚设置为低电平(点亮)
		delay_ms(500);							//延时一会
		
		GPIO_SetBits(GPIOF,GPIO_Pin_9);		//将引脚设置为高电平(熄灭)
		delay_ms(500);
	} 
}

 

 主函数中对于时钟源的配置说明:

/**
  * @brief  Configures the SysTick clock source.
  * @param  SysTick_CLKSource: specifies the SysTick clock source.
  *   This parameter can be one of the following values:
  *     @arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source.
  *     @arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source.
  * @retval None
  */
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
{
  /* Check the parameters */
  assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));
  if (SysTick_CLKSource == SysTick_CLKSource_HCLK)
  {
    SysTick->CTRL |= SysTick_CLKSource_HCLK;
  }
  else
  {
    SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;
  }
}

void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource);

参数选择:

SysTick _ clk source _ HCLK _ div 8:AHB时钟除以8,选择作为systick时钟源。 

SysTick_CLKSource_HCLK:选择AHB时钟作为SysTick时钟源。

SysTick_CLKSource_HCLK_Div8:AHB时钟/8=168MHz/8=21MHz(推荐)

SysTick_CLKSource_HCLK:AHB时钟=168MHz

最大延时时间分别是多久:

SysTick_CLKSource_HCLK_Div8:(2^24 - 1)/2100000 = 798.915ms

SysTick_CLKSource_HCLK:(2^24 - 1)/168000000 = 99.864375ms

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值