stm32定时器

文章详细介绍了Systick定时器的概念、工作原理以及STM32中的通用定时器分类和配置流程。Systick作为系统滴答定时器,用于延时和实时系统的心跳时钟,而STM32的通用定时器支持多种计数模式,并提供了详细的配置函数说明。此外,文章还给出了定时器在智能公交定位和交通红绿灯控制等实际应用中的例子。
摘要由CSDN通过智能技术生成
  • Systick定时器

1、定时器概念

定时器:是芯片内部用于计数从而得到时长的一种外设。

定时器定时长短与什么有关???(定时器定时长短与频率及计数大小有关)

定时器频率换算单位:1GHZ=1000MHZ=1000 000KHZ = 1000 000 000HZ

在1MHZ下,1us计1个数;在100MHZ下,1us计100个数;

2、Systick定时器

Systick定时器,是一个简单的定时器,对于CM3,CM4内核芯片,都有Systick定时器。常用来做延时,或者实时系统的心跳时钟。这样可以节省MCU资源,不用浪费一个定时器。比如uCOS/FreeRTOS中,分时复用,需要一个最小的时间戳,一般在STM32+UCOS系统中,都采用Systick做uCOS心跳时钟。

 Systick定时器就是系统滴答定时器,一个24 位的倒计数定时器,计到0 时,将从RELOAD 寄存器中自动重装载定时初值。只要不把它在SysTick 控制及状态寄存器中的使能位清除,就永不停息,即使在睡眠模式下也能工作。

一共4个Systick寄存器

    CTRL             SysTick 控制和状态寄存器 

    LOAD            SysTick 自动重装载除值寄存器 

    VAL               SysTick 当前值寄存器 

CALIB            SysTick 校准值寄存器

 

 

 

  • STM32通用定时器

1、定时分类及时钟频率

STM32定时器分类:高级控制定时器、通用定时器、基本定时器

高级控制定时器:TIM1 TIM8

通用定时器:TIM2 TIM3 TIM4 TIM5 TIM9 TIM10 TIM11 TIM12 TIM13 TIM14

基本定时器:TIM6 TIM7

挂在APB1下的定时器:TIM2 TIM3 TIM4 TIM5 TIM6 TIM7 TIM12 TIM13 TIM14

挂在APB2下的定时器:TIM1 TIM8 TIM9 TIM10 TIM11

 

挂在APB1下的定时器时钟频率:42MHZ X 2 = 84MHZ

挂在APB2下的定时器时钟频率:84MHZ X 2 = 168MHZ

2、通用定时器的计数模式

通用定时器可以向上计数、向下计数、向上向下双向计数模式。

①向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且产生一个计数器溢出事件。

②向下计数模式:计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件。

③中央对齐模式(向上/向下计数):计数器从0开始计数到自动装入的值-1,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数。

 

3、定时器框架分析

 

4、通用定时器3配置流程

通用定时器需要添加的库函数文件:stm32f4xx_tim.c

1、能定时器时钟。

     RCC_APB1PeriphClockCmd();

2、初始化定时器,配置ARR,PSC。

     TIM_TimeBaseInit();

3、启定时器中断,配置NVIC。

      NVIC_Init();

4、设置 TIM3_DIER  允许更新中断

TIM_ITConfig();

5、使能定时器。

      TIM_Cmd();

6、编写中断服务函数。

      TIMx_IRQHandler();

三、函数说明

/**

  * @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)

函数说明:SysTick时钟源配置

返回值:无

uint32_t SysTick_CLKSource:时钟源

SysTick_CLKSource_HCLK_Div8:  HCLK/8 = 21MHZ

SysTick_CLKSource_HCLK: HCLK = 168MHZ

void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct)

函数功能:定时器初始化

返回值:无

TIM_TypeDef* TIMx:选择定时器

 TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct:定时器结构体

typedef struct

{

    uint16_t TIM_Prescaler;

    uint16_t TIM_CounterMode;

    uint16_t TIM_Period;

    uint16_t TIM_ClockDivision;

} TIM_TimeBaseInitTypeDef;

1.    第一个参数 TIM_Prescaler 是用来设置分频系数。

2.    第二个参数 TIM_CounterMode 是用来设置计数方式,上面讲解过,可以设置为向上计数,向下计数方式还有中央对齐计数方式,比较常用的是向上计数模式TIM_CounterMode_Up 和向

下计数模式 TIM_CounterMode_Down。

3.   第三个参数是设置自动重载计数周期值,这在前面也已经讲解过。

4.   第四个参数是用来设置时钟分频因子

void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState)

函数说明:定时器的中断配置

返回值:无

TIM_TypeDef* TIMx:选择哪个定时器

uint16_t TIM_IT:中断方式

TIM_IT_Update (更新中断)

TIM_IT_CC1    

TIM_IT_CC2    

TIM_IT_CC3    

TIM_IT_CC4    

TIM_IT_COM    

TIM_IT_Trigger

TIM_IT_Break  

FunctionalState NewState:是否使能

void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)

函数说明:定时器使能

返回值:无

TIM_TypeDef* TIMx:选择哪个定时器

 

FunctionalState NewState:是否使能

ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT)

函数功能:获取定时器中断标志位

返回值:SET或RESET

TIM_TypeDef* TIMx:选择定时器

uint16_t TIM_IT:中断事件

  *            @arg TIM_IT_Update: TIM update Interrupt source

  *            @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source

  *            @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source

  *            @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source

  *            @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source

  *            @arg TIM_IT_COM: TIM Commutation Interrupt source

  *            @arg TIM_IT_Trigger: TIM Trigger Interrupt source

  *            @arg TIM_IT_Break: TIM Break Interrupt source

void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT)

函数功能:清空定时器中断标志位

返回值:无

TIM_TypeDef* TIMx:选择定时器

uint16_t TIM_IT:中断事件

  *            @arg TIM_IT_Update: TIM update Interrupt source

  *            @arg TIM_IT_CC1: TIM Capture Compare 1 Interrupt source

  *            @arg TIM_IT_CC2: TIM Capture Compare 2 Interrupt source

  *            @arg TIM_IT_CC3: TIM Capture Compare 3 Interrupt source

  *            @arg TIM_IT_CC4: TIM Capture Compare 4 Interrupt source

  *            @arg TIM_IT_COM: TIM Commutation Interrupt source

  *            @arg TIM_IT_Trigger: TIM Trigger Interrupt source

  *            @arg TIM_IT_Break: TIM Break Interrupt source

四、定时器应用

智能公交一体机,定时器每隔固定时间向服务器发送自己的定位

 

 

交通红绿灯定时1S将数字进行倒数

 Systick延时

#include "delay.h"

int my_us = 21;  	//1us计21个数
int my_ms = 21000;  //1ms计21000个数

void Delay_Init(void)
{
	//SysTick时钟源配置  168MHZ/8 = 21MHZ;
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);

}

//int nus最大值:798915
void delay_us(int nus) //1000000
{
	u32 temp = 0x00; //u32 == unsigned int
	
	//设置重载值寄存器
	SysTick->LOAD = my_us*nus-1;   
	//设置VAL为0
	SysTick->VAL = 0x00;
	//启动定时器,VAL开始计数
	SysTick->CTRL |= (0x01<<0);

	//查询状态位是否为1
	do
	{
		temp = SysTick->CTRL;
		  //判断定时器是否开启	 判断CTRL第16是否为1
	}while( (temp &(0x01<<0)) && !(temp & (0x01<<16)) );
	
	
	//关闭定时器,完成一次的计数,从而达到延时
	SysTick->CTRL &= ~(0x01<<0);
}

//int nms最大值:798
void delay_ms(int nms) //1000000
{
	u32 temp = 0x00; //u32 == unsigned int
	
	//设置重载值寄存器
	SysTick->LOAD = my_ms*nms-1;   
	//设置VAL为0
	SysTick->VAL = 0x00;
	//启动定时器,VAL开始计数
	SysTick->CTRL |= (0x01<<0);

	//查询状态位是否为1
	do
	{
		temp = SysTick->CTRL;
		  //判断定时器是否开启	 判断CTRL第16是否为1
	}while( (temp &(0x01<<0)) && !(temp & (0x01<<16)) );
	
	
	//关闭定时器,完成一次的计数,从而达到延时
	SysTick->CTRL &= ~(0x01<<0);
}


void delay_s(int ns)
{
	int i;
	
	for(i=0; i<ns; i++)
	{
		delay_ms(500);
		delay_ms(500);
	}
}


#ifndef __DELAY_H
#define __DELAY_H

#include "stm32f4xx.h"


void Delay_Init(void);
void delay_us(int nus);
void delay_ms(int nms);
void delay_s(int ns);


#endif
#include "stm32f4xx.h"
#include "led.h"
#include "key.h"
#include "exti.h"
#include "delay.h"
void delay(int n)
{
	int i, j;

	for(i=0; i<n; i++)
		for(j=0; j<20000; j++);
}


int main(void)
{
	int key_count = 0;
	//设置NVIC分组(一个工程只能设置一个分组) 
	//第二分组;抢占优先组取值范围:0~3 响应先组取值范围:0~3
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	Led_Init();
	Delay_Init();

	
	while(1)
	{
		
		delay_s(1);
		LED0_CH;
	
		
	}
}

Systick中断

#include "stm32f4xx.h"
#include "led.h"
#include "key.h"
#include "exti.h"
#include "delay.h"

u32 delay_connt = 0;

void delayms(int nms);

int main(void)
{
	int key_count = 0;
	//设置NVIC分组(一个工程只能设置一个分组) 
	//第二分组;抢占优先组取值范围:0~3 响应先组取值范围:0~3
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	Led_Init();
	//SystemCoreClock = 168000000  1ms产生一次中断
	SysTick_Config(SystemCoreClock/1000);
	
	//GPIO_ResetBits(GPIOE, GPIO_Pin_14);
	
	while(1)
	{
		
		delayms(1000);
		LED0_CH;
	
	}
}


void delayms(int nms)//假设填入100
{
	//时间赋值给delay_connt
	delay_connt = nms;

	while(delay_connt);
}



//SysTick中断 1ms
void SysTick_Handler(void)
{
	
	if(delay_connt!=0)
	{
		delay_connt--;
	}

}


time定时器

#include "tim.h"


/**************************************
函数说明
TIM3挂在APB1, TIM3频率:84MHZ
TIM3为16位定时器
**************************************/
void Tim3_Init(void)
{
	
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseInitStruct;
	NVIC_InitTypeDef  NVIC_InitStruct;
	
	
	
	//1、能定时器时钟。
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	
	TIM_TimeBaseInitStruct.TIM_Prescaler	= 83; 					//84分频  84MHZ/84 = 1MHZ
	TIM_TimeBaseInitStruct.TIM_Period		= (1000-1); 			//ARR的值,在1MHZ计1000个数,用时1ms
	TIM_TimeBaseInitStruct.TIM_CounterMode	= TIM_CounterMode_Up;	//计数模式:向上计数
	TIM_TimeBaseInitStruct.TIM_ClockDivision= TIM_CKD_DIV1;			//分频因子
	//2、初始化定时器,配置ARR,PSC。
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct);
	


	NVIC_InitStruct.NVIC_IRQChannel						= TIM3_IRQn; //中断通道,中断通道在stm32f4xx.h文件当中查找
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority	= 2;		 //抢占优先级			
	NVIC_InitStruct.NVIC_IRQChannelSubPriority			= 2;		 //响应优先级
	NVIC_InitStruct.NVIC_IRQChannelCmd					= ENABLE;	 //使能通道
	//3、启定时器中断,配置NVIC。
    NVIC_Init(&NVIC_InitStruct);		

	
	//4、设置 TIM3_DIER  允许更新中断
	TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
	//5、使能定时器。
	TIM_Cmd(TIM3, ENABLE);

}

void TIM3_IRQHandler(void)
{
	//判断标志位是否置1
	if(TIM_GetITStatus(TIM3, TIM_IT_Update) == SET)
	{
		GPIO_ToggleBits(GPIOE, GPIO_Pin_14);
	}
	//清空标志位
	TIM_ClearITPendingBit(TIM3, TIM_IT_Update);

}
#ifndef __TIM_H
#define __TIM_H

#include "stm32f4xx.h"


void Tim3_Init(void);

#endif
#include "stm32f4xx.h"
#include "led.h"
#include "key.h"
#include "exti.h"
#include "delay.h"
#include "tim.h"


void delay(int n)
{
	int i, j;

	for(i=0; i<n; i++)
		for(j=0; j<20000; j++);
}


int main(void)
{
	int key_count = 0;
	//设置NVIC分组(一个工程只能设置一个分组) 
	//第二分组;抢占优先组取值范围:0~3 响应先组取值范围:0~3
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	Led_Init();
	Delay_Init();
	Tim3_Init();
	
	while(1)
	{
		
		delay_s(1);
		LED0_CH;
	
		
	}
}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hqb_newfarmer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值