定时器驱动

前言

(1)本系列是基于STM32的项目笔记,内容涵盖了STM32各种外设的使用,由浅入深。

(2)小编使用的单片机是STM32F105RCT6,项目笔记基于小编的实际项目,但是博客中的内容适用于各种单片机开发的同学学习和使用。

学习目标

  1. 掌握STM32单片机通用定时器初始化。
  2. 完成定时器1ms的定时功能。
  3. 实验效果:LED灯1秒闪烁。

主要内容

STM32单片机的定时器

STM32总共有8个定时器,分别是2个高级定时器(TIM1、TIM8),4个通用定时器(TIM2、TIM3、TIM4、TIM5)和2个基本定时器(TIM6、TIM7)

定时器初始化,分为3个部分

(1)打开定时器时钟

(2)配置定时器参数

(3)配置定时器中断,并打开定时器中断功能

本节我们使用的是定时器4,所以要对定时器4进行初始化操作。

打开定时器时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
配置定时器参数
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

	TIM_DeInit(TIM4); 
	TIM_TimeBaseStructure.TIM_Period = 1000;   			//1ms 
	TIM_TimeBaseStructure.TIM_Prescaler = SystemCoreClock/1000000 - 1;              
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;     
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);	
	
	TIM_ClearFlag(TIM4, TIM_FLAG_Update);					  
	TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); 
					 
	TIM_Cmd(TIM4, ENABLE); 

相关参数说明:

TIM_Period: 设置自动重装载寄存器周期的值

TIM_Prescaler: 设置时钟频率除数的预分频值 1M // 0.000 001秒 1uS

为什么要-1; 因为从0开始计算 0表示1分配 1表示2分配…/

72000 000 / 1000 000 = 72; //71

72M进行72分频下来就是1M,1M是时钟频率,1/1M=1us是定时器一个计数周期。要积累period=1000才会产生定时器中断,即定时器中断的周期是1us*1000=1ms。

TIM_ClockDivision://设置时钟分割,与定时器定时时间无关

TIM_CounterMode://TIM 向上计数

配置后,定时器的定时时间为1s,这里给出算定时器定时时间的公式:

① 定时器时钟频率 = 72M/(Prescaler+1);

② 一个计数周期 = 1/定时器时钟频率;

③定时时间 = Period * 定时器时钟时间;

配置定时器中断
      NVIC_InitTypeDef NVIC_InitStructure;

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置NVIC中断分组2

	NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;///先占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;        ///代优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

配置NVIC中断分组2
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
定时器中断服务函数
void TIM4_IRQHandler(void)///定时器4 中断服务函数
{
	hal_LedProc();
	TIM_ClearFlag(TIM4, TIM_FLAG_Update);
}

hal_timer.h代码

#ifndef _HAL_TIMER_H_
#define _HAL_TIMER_H_


void hal_timerInit(void);

#endif

hal_timer.c代码

#include "stm32F10x.h"
#include "hal_timer.h"
#include "hal_led.h"
#include "string.h"

/*******************************************************************************
* Function Name  : static void hal_timer4Config(void)
* Description    : 定时器硬件配置函数
* Input          : None
* Output         : None
* Return         : None
* Attention		 	 : None
*******************************************************************************/
static void hal_timer4Config(void)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
	
	TIM_DeInit(TIM4); 
	TIM_TimeBaseStructure.TIM_Period = 1000; 			//1ms  
	TIM_TimeBaseStructure.TIM_Prescaler = SystemCoreClock/1000000 - 1;              
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;     
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);	
	
	TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); ///打开定时器4中断				 
	TIM_Cmd(TIM4, ENABLE);   ///打开定时器4

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置NVIC中断分组2
	
	NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;///先占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;        ///从优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}


/*******************************************************************************
* Function Name  : void hal_timerInit(void)
* Description    : 定时器初始化
* Input          : None
* Output         : None
* Return         : None
* Attention		 	 : None
*******************************************************************************/
void hal_timerInit(void)
{
	hal_timer4Config();
}
/
void TIM4_IRQHandler(void)
{
	hal_LedProc();
	TIM_ClearFlag(TIM4, TIM_FLAG_Update);
}
//



hal_led.c代码

#include "stm32F10x.h"
#include "hal_timer.h"
#include "hal_led.h"

static void hal_LedConfig(void);
static void hal_Led1Turn(void);

void hal_LedInit(void)
{
	hal_LedConfig();
}
/
/
void delay_1sTest(void)
{
	unsigned int i=0;
	i = 7200000;
	while(i--);   
}

static void hal_LedHandle(void)
{
//	delay_1sTest();
//	GPIO_ResetBits(LED8_PORT,LED8_PIN);
//	GPIO_ResetBits(LED7_PORT,LED7_PIN);
//	delay_1sTest();
//	GPIO_SetBits(LED8_PORT,LED8_PIN);
//	GPIO_SetBits(LED7_PORT,LED7_PIN);
  static unsigned short delayt =0;
	delayt ++;
  if(delayt > 999)
	{1秒钟
		hal_Led1Turn();
		delayt = 0;
	}	
}
//


void hal_LedProc(void)
{
	hal_LedHandle();
}

static void hal_LedConfig(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;	
	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC,ENABLE); 						 
	GPIO_InitStructure.GPIO_Pin = LED8_PIN | LED7_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; ; 
	GPIO_Init(LED8_PORT, &GPIO_InitStructure);
	
	GPIO_ResetBits(LED8_PORT,LED8_PIN);
	GPIO_SetBits(LED7_PORT,LED7_PIN);
}


static void hal_Led1Turn(void)
{/1-》0    0-》1
	GPIO_WriteBit(LED8_PORT,LED8_PIN,(BitAction)(1-GPIO_ReadOutputDataBit(LED8_PORT,LED8_PIN)));
	GPIO_WriteBit(LED7_PORT,LED7_PIN,(BitAction)(1-GPIO_ReadOutputDataBit(LED7_PORT,LED7_PIN)));
}
/

main.c代码

#include "stm32f10x.h"
#include "hal_timer.h"
#include "hal_led.h"
#include "hal_gpio.h"


int main(void)
{
	hal_LedInit();
	hal_GpioConfig_init();	
	hal_timerInit();
  while (1)
  {	
//		if(hal_Gpio_AcStateCheck() == STA_AC_BREAK)
//		{
//			GPIO_ResetBits(LED7_PORT,LED7_PIN);
//		}
//		else
//		{	
//			GPIO_SetBits(LED7_PORT,LED7_PIN);			
//		}		
//		hal_LedProc();
  }
}

猜你喜欢

转载自blog.csdn.net/weixin_62261692/article/details/132500698