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

  • 2
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在STM32f103zet6中,可以使用SysTick定时器来实现延时函数。下面是一个简单的延时函数示例: ```c void delay_ms(uint32_t ms) { uint32_t tickstart = HAL_GetTick(); while((HAL_GetTick() - tickstart) < ms); } ``` 该函数使用了HAL库中的HAL_GetTick()函数来获取当前系统时钟计数器的值,然后通过不断循环判断当前时间是否超过要求的延时时间来实现延时。 需要注意的是,该函数的精度受到系统时钟计数器的精度和循环判断的时间开销的影响,可能存在一定误差。如果需要更高精度的延时,可以考虑使用其他定时器或外部时钟源。 ### 回答2: STM32F103ZET6是一款32位的微控制器,内置了ARM Cortex-M3内核。在使用STM32F103ZET6进行程序开发时,我们常常需要用到延时函数。 在STM32F103ZET6芯片中,并没有内置延时函数,所以我们需要自己编写延时函数来实现延时操作。通常我们可以使用定时器或者循环来进行延时。 一种常见的方法是使用循环延时函数。我们可以通过循环来实现精确的延时时间。首先,我们需要初始化一个变量并赋予一个适当的值,该值表示延时时间的大小。然后,我们可以使用一个while循环来不断减小该变量的值,直到该变量为零时,循环结束。这样可以保证延时的准确性,但是会占用CPU的运行时间,对于一些高精度的延时需求可能不够满足。 另一种方法是使用定时器延时函数。我们可以设置一个定时器,并配置一个适当的定时时间,当定时器的计数器等于我们设置的定时时间时,会触发一个中断。我们可以在中断处理函数中设置一个标志位,在主循环中判断该标志位是否被置位,如果被置位,则表示延时时间已经到达。这样可以实现较高精度的延时,并且不会占用CPU的过多时间。 总而言之,对于STM32F103ZET6芯片来说,延时函数是需要自己编写的。可以根据需求选择适合的延时方法,在循环延时和定时器延时之间做权衡,以满足不同的延时需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值