全网最简单实现stm32基本定时器实现毫秒级精确延时

在stm32中,系统滴答定时器可以实现精确的延时,但有时需要使用基本定时器实现精确延时,保证接下来采取的方法是全网最简单的方法。

使用的平台是野火mini开发板

第一步 配置tim6



#define  BASIC_TIM6                           TIM6
#define  BASIC_TIM6_CLOCK_CMD    RCC_APB1PeriphClockCmd
#define  BASIC_TIM6_CLK                  RCC_APB1Periph_TIM6
#define  BASIC_TIM6_IRQ                  TIM6_IRQn  
#define  BASIC_TIM6_IRQHandler       TIM6_IRQHandler

这是定时器6的头文件的宏定义,为了在以后做移植更加方便

TIM_TimeBaseInitTypeDef   TIM_TimeBaseInitstructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE);
	
	TIM_TimeBaseInitstructure.TIM_Period=1000;
	
	
	TIM_TimeBaseInitstructure.TIM_Prescaler=71;
	
	TIM_TimeBaseInit(BASIC_TIM6,&TIM_TimeBaseInitstructure);
	
	TIM_ClearFlag(BASIC_TIM6,TIM_FLAG_Update);
	/*设置时钟中断源为 计数更新中断*/
	TIM_ITConfig(BASIC_TIM6,TIM_IT_Update,ENABLE);
	
	//TIM_Cmd(BASIC_TIM6,ENABLE);
	//注意这里我并没有使能定时器,这一部非常关键

关于TIM_Period,TIM_Prescaler这两个参数 的选择问题,参考野火电子的资料,写的非常详细,使用71,和1000,在接下来进入一次中断的时间就是1ms。

配置nvic

NVIC_InitTypeDef NVIC_InitStructure;
  
 
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
  
  
  NVIC_InitStructure.NVIC_IRQChannel = BASIC_TIM6_IRQ;
	
 
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
 
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
 
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
 
  NVIC_Init(&NVIC_InitStructure);

第二步 中断函数的书写

在配置中断函数之间 ,在主文件里面设置一个***全局变量***,
中断函数就是按照下面的方式写 其中的变量 time就是我们前面设置的全局变量。

void BASIC_TIM6_IRQHandler()
{
	if(TIM_GetITStatus(BASIC_TIM6,TIM_IT_Update)!=RESET)
	{
		time--;
		
		TIM_ClearITPendingBit(BASIC_TIM6,TIM_IT_Update);
	}
}

编写延时函数

void  base_time_delay_ms(u16 t)
{
	time=t;
	TIM_Cmd(BASIC_TIM6,ENABLE);
	while(time!=0);
	if(time==0)
	{
		time=t;
		TIM_Cmd(BASIC_TIM6,DISABLE);
	}
	
}

延时函数如上,进入函数将形参赋值给全局变量,然后打开定时器,等待变量在中断函数中一直减小到0,然后重新赋值,关闭定时器。

总结

base_time_delay_ms(50);
	GPIO_SetBits(LED1_GPIO_PORT,LED1_GPIO_PIN);
	base_time_delay_ms(50);
	GPIO_ResetBits(LED1_GPIO_PORT,LED1_GPIO_PIN);
	base_time_delay_ms(50);

在主函数里面调用延时函数,填入的参数就是延时的毫秒数。
即可实现基于定时器的精确延时。

  • 3
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
STM32中,我们可以使用定时器实现毫秒别的延时。具体实现步骤如下: 1. 初始化定时器:选择一个可用的定时器,设置其时钟源和分频系数,使其每个定时器周期为1毫秒。例如,如果设置定时器时钟源为APB1时钟(42MHz),分频系数为42000,那么每个定时器周期为1毫秒。 2. 配置定时器中断:使能定时器中断,并在中断服务函数中设置一个标志位,用于表示定时器已经到达指定的时间。 3. 编写延时函数:在延时函数中,设置一个计数器并清零,然后等待定时器中断标志位被置位。当标志位被置位时,计数器加1并将标志位清零,直到计数器的值等于延时毫秒数为止。 以下是一个示例代码: ``` #include "stm32f4xx.h" void TIM2_Init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_TimeBaseStructure.TIM_Period = 1000 - 1; TIM_TimeBaseStructure.TIM_Prescaler = 42000 - 1; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_Cmd(TIM2, ENABLE); } volatile uint32_t DelayTimer; void Delay_ms(uint32_t nTime) { DelayTimer = nTime; while (DelayTimer); } void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(TIM2, TIM_IT_Update); if (DelayTimer > 0) { DelayTimer--; } } } int main(void) { TIM2_Init(); while (1) { Delay_ms(1000); // 延时1秒 // 执行需要延时的操作 } } ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值