利用基本定时器TIM7实现精准延时

点击查看代码
/**
   ******************************************************************************
   * @file    main.c 
   * @author  
   * @version 
   * @date    2024/06/28
   * @brief   实现利用基本定时器TIM7实现定时10s,每隔10s触发一次中断,实现控制
							蜂鸣器的鸣叫
							
							
   ******************************************************************************
**/

#include "stm32f4xx.h"  //必须包含


//LED的初始化
void  LED_Config()
{
	//1.定义GPIO外设的结构体变量
	GPIO_InitTypeDef  GPIO_InitStructure;
	
	//2.打开GPIOF端口的时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
	
	//3.配置PF9引脚为输出模式
	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;
	
	//4.对GPIOF端口进行初始化
	GPIO_Init(GPIOF, &GPIO_InitStructure);
	
	GPIO_SetBits(GPIOF,GPIO_Pin_9);//LED不亮
}

//BEEP的初始化
void  BEEP_Config()
{
	//1.定义GPIO外设的结构体变量
	GPIO_InitTypeDef  GPIO_InitStructure;
	
	//2.打开GPIOF端口的时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
	
	//3.配置PF9引脚为输出模式
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_8;
	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;
	
	//4.对GPIOF端口进行初始化
	GPIO_Init(GPIOF, &GPIO_InitStructure);
	
	GPIO_ResetBits(GPIOF,GPIO_Pin_8);//BEEP默认不响
}



//延时微秒 注意:Systick是24bit的递减计数器  约等于798915us,所以参数不可以超过这个值
void delay_us(u32 nus)
{
	SysTick->CTRL = 0; 						 // 向控制状态寄存器中写入0,目的关闭系统嘀嗒定时器
	SysTick->LOAD = (nus * 21) - 1;// 指的是计数次数,定时时间 = 计数次数 * 计数周期
	SysTick->VAL  = 0; 						 // 清除当前数值寄存器的值
	SysTick->CTRL = 1; 						 // 开启了定时器,并且定时器的时钟源选择了21MHZ--> 计数周期 = 1/21us
	while ((SysTick->CTRL & 0x00010000)==0);//等待延时时间到达
	SysTick->CTRL = 0; 						 // 向控制状态寄存器中写入0,目的关闭系统嘀嗒定时器

}

//延时毫秒 注意:Systick是24bit的递减计数器  约等于798ms,所以参数不可以超过这个值
void delay_ms(u32 nms)
{
	SysTick->CTRL = 0; 						 			// 向控制状态寄存器中写入0,目的关闭系统嘀嗒定时器
	SysTick->LOAD = (nms * 21*1000) - 1;// 指的是计数次数,定时时间 = 计数次数 * 计数周期
	SysTick->VAL  = 0; 						 			// 清除当前数值寄存器的值
	SysTick->CTRL = 1; 						 			// 开启了定时器,并且定时器的时钟源选择了21MHZ--> 计数周期 = 1/21us
	while ((SysTick->CTRL & 0x00010000)==0);//等待延时时间到达
	SysTick->CTRL = 0; 						 			// 向控制状态寄存器中写入0,目的关闭系统嘀嗒定时器
}

//延时秒
void delay_s(u32 ns)
{
	while(ns--)
	{
		delay_ms(500);
		delay_ms(500);
	}
}


//TIM7的中断服务程序
void TIM7_IRQHandler(void)
{
	//判断中断是否发生
  if (TIM_GetITStatus(TIM7, TIM_IT_Update) != RESET)
  {
		GPIO_ToggleBits(GPIOF,GPIO_Pin_8);//BEEP每隔500ms电平翻转一次
		
		//清除TIM6的中断标志
    TIM_ClearITPendingBit(TIM7, TIM_IT_Update);
   
  }
}



//TIM7的初始化
void  TIM7_Config()
{
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	
	//1.打开TIM7的时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE);
	
	//2.定义结构体变量并对结构体变量的成员进行赋值
	TIM_TimeBaseStructure.TIM_Prescaler = 42000-1;							//预分频值,TIM6的时钟是84MHZ,所以可以降低频率 500us计数一次
	TIM_TimeBaseStructure.TIM_Period = 20000-1;									//计数次数,这个值会写入自动重载寄存器 500us * 20000 = 10s
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数模式,基本定时器TIM6和TIM7只允许递增计数

	//3.对定时器进行初始化
	TIM_TimeBaseInit(TIM7, &TIM_TimeBaseStructure);
	
	//4.配置NVIC外设+对NVIC外设进行初始化
	NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn;					//中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;		
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);

	//5.选择TIM7的中断源 基本定时器TIM6和TIM7只能选择更新中断
	TIM_ITConfig(TIM7,TIM_IT_Update , ENABLE);
	
	//6.打开定时器TIM7
	TIM_Cmd(TIM7, ENABLE);
}

int main()
{
	
	//1.硬件的初始化
	LED_Config();  
	BEEP_Config();
	TIM7_Config();
	
	
	while(1)
	{
		 
		
	}
}





posted @ 2025-08-30 12:22  w1888  阅读(13)  评论(0)    收藏  举报