STM32F103 定时器中断实验

实验目的

STM32集成了丰富的定时器资源,通过本实验学习STM32的定时器(TIM)的使用,数据手册请参看第13,14 ,15章

实验简介

STM32一共8个都为16位的定时器。其中TIM6,TIM7 是基本定时器;TIM2,TIM3,TIN4,TIM5是通用定时器:TIM1和TIM8是高级定时器。
基本定时器(TIM6和TIM7)
这两个定时器只具备最基本的定时器功能,就是累加的时钟脉冲超过预定值时,能触发中断或触发DMA请求。由于在芯片内部与DAC外设相连,可通过触发输出驱动DAC。也可以作为其它通过定时器的时钟基准,框图如下:
在这里插入图片描述
通用定时器(TIM2~TIM5)
通用定时器是一个通过可编程预分频器驱动的16位自动装载计数器构成。它适用于多种场合,包括测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和PWM)。

使用定时器预分频器和RCC时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整
在这里插入图片描述
高级定时器(TIM1和TIM8)
TIM1和TIM8是两个高级定时器,他们具有基本,通用定时器的所有功能,还具有三相六步电机的接口,刹车功能(break function)及用于PWM驱动电路的死区时间控制等,使得它非常适合于电机控制。
在这里插入图片描述

有关寄存器

**APB1 外设时钟使能寄存器(RCC_APB1ENR) **
在这里插入图片描述
在这里插入图片描述
预分频器和自动重装载寄存器
在这里插入图片描述
TIM1 和TIM8 DMA/中断使能寄存器(TIMx_DIER)
在这里插入图片描述
在这里插入图片描述
TIM1 和TIM8 控制寄存器 1(TIMx_CR1)
在这里插入图片描述
在这里插入图片描述
TIM1 和TIM8 状态寄存器(TIMx_SR)
在这里插入图片描述
在这里插入图片描述

寄存器代码

test.c

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"

int main(void)
{
	Stm32_Clock_Init(9);
	uart_init(72,115200);
	delay_init(72);
	LED_Init();
	TIM3_Int_Init(4999,7199);
	//TIM3初始化(自动重装载值,时钟预分频系数)
	//Tout= ((arr+1)*(psc+1))/Tclk; 
	// 因为APB1 的时钟分频数不为 1,所以 TIM2~7
	// 的时钟频率将为 APB1 时钟的两倍。也就是72
	//本实验计算Tout=(5000*7200)/72=500 000us
	//这是一共定时时间
	while(1)
	{
		LED1 = !LED1;
		delay_ms(500);
	}
}




timer.h

#ifndef __TIMER_H
#define __TIMER_H
#include "sys.h"

void TIM3_Int_Init(u16 arr,u16 psc);
#endif

timer.c

#include "timer.h"
#include "led.h"

void TIM3_IRQHandler(void)
{
	if(TIM3->SR & 0x0001)
	//溢出中断,由硬件置1
	{
		LED2 = !LED2;
	}
	TIM3->SR &= ~(1<<0);
	//清除中断标志位
}

void TIM3_Int_Init(u16 arr,u16 psc)
{
	RCC->APB1ENR |= 1<<1; 
	//TIM3使能
	TIM3->ARR = arr; 
	//设置计数器自动重装值
	TIM3->PSC = psc;
	 //预分频器
	TIM3->DIER |= 1<<0;   
	//允许中断更新
	TIM3->CR1  |= 0x01;   
	//使能定时器3
	
	MY_NVIC_Init(1,3,TIM3_IRQn,2);
	//设置中断 抢占1 响应3 组2

HAL库代码

main.c

#include MyIncludes.h

void timetick_isr(void)
{
  HAL_HPIO_TogglePin(GPIOC,GPIO_PIN_4|GPIO_PIN_5);
}

int main(void)
{
  System_Init();
  LED_Init();
  SysTick_Init(NULL);
  Timer_Init(1,1000,timetick_isr);
  //定时器中断初始化
  //三个参数: 使用TIM1  自动重载值参数
  //函数指针
  while(1)
  {
  
  }
}

Timerx.h

#ifndef __TIMERX_H_
#define __TIMERX_H_

#include "stm32f1xx.h"
#include "stm32_types.h"
#include "stm32f1xx_hal.h"

typedef struct
{
  void (*T1_Handle)(void);
  void (*T2_Handle)(void);
  void (*T3_Handle)(void);
  void (*T4_Handle)(void);
  void (*T5_Handle)(void);
  void (*T6_Handle)(void);
  void (*T7_Handle)(void);
  void (*T8_Handle)(void);
}_TIMER_ISR;
//定时器中断中运行的函数的结构体

void Timer_Init(uint8_t timer_num,uint32_t ms,void (*ISR)(void));
//定时器初始化函数

#endif

Timerx.c

#include "Timerx.h"

_TIMER_ISR Timer_ISR;
//定时器中断结构体变量声明
TIM_HandleTypeDef Tim1_Handle;
TIM_HandleTypeDef Tim3_Handle;
TIM_HandleTypeDef Tim4_Handle;
TIM_HandleTypeDef Tim7_Handle;

void Timer_Init(uint8_t timer_num,uint32_t ms,void(*ISR)(void))
{
   TIM_TypeDef *TIMx;
   uint32_t uwPrescalerValue = 0;
   uwPrescalerValue = (uint32_t)((SystemCoreClock)/10000)-1;
   //时钟预分频系数:(72000000/10000)-1 =719
   //计数频率 = 时钟频率/(时钟预分频系数+1)
   //72000000/(719+1)=1000000 = 0.1ms;   
   //0.1ms计数频率
   //(感觉单位应该是MHz,这上面写的是ms)
    if(timer_num == 1)
    //定时器1,高级定时器
    {
      TIMx = TIM1;
      __HAL_RCC_TIM1_CLK_ENABLE();
      //定时器1使能
      Timer_ISR.T1_Handle = ISR;
       //中断后进行函数指针
       Tim1_Handle.Instance = TIMx;
       //设置定时器
       Tim1_Handle.Init.Period = 10 * ms - 1;    //自动重装值
       Tim1_Handle.Init.Prescaler = uwPrescalerValue;
       //设置计数频率为0.1ms计一次数
       Tim1_Handle.Init.ClockDivision = 0;     
       //时钟不分频,来自RCC
       Tim1_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
       //递增计数
       HAL_TIM_Base_Init(&Tim1_Handle);
       //初始化定时器参数
       HAL_TIM_Base_Start(&Tim1_Handle);
       //使能定时器及中断
        
       HAL_NVIC_SetPriority(TIM1_UP_TIM10_IRQn,4,0);
      // 配置NVIC中断
       HAL_NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn); 
       //使能中断 
    }
    else if( timer_num ==3 )
    {
      TIMx = TIM3;
      __HAL_RCC_TIM3_CLK_ENABLE();
      Timer_ISR.T3_Handle = ISR;
 
       Tim3_Handle.Instance = TIMx;
       Tim3_Handle.Init.Period = 10 * ms -1;
       Tim3_Handle.Init.Prescaler = uwPrescalerValue;
       Tim3_Handle.Init.ClockDivision = 0;
       Tim3_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
       HAL_TIM_Base_Init(&Tim3_Handle);
       HAL_TIM_Base_Start_IT(&Tim3_Handle);
 
       HAL_NVIC_SetPriority(TIM3_IRQn,4,0);
       HAL_NVIC_EnableIRQ(TIM3_IRQn);
    }

    else if( timer_num ==4 )
    {
       TIMx = TIM4;
       __HAL_RCC_TIM4_CLK_ENABLE();
       Timer_ISR.T4_Handle = ISR;
       
        Tim4_Handle.Instance = TIMx;
        Tim4_Handle.Init.Period = 10 * ms - 1;
        Tim4_Handle.Init.Prescaler = uwPrescalerValue;
        Tim4_Handle.Init.ClockDivision = 0;
        Tim4_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
        HAL_TIM_Base_Init(&Tim4_Handle);
        
        HAL_NVIC_SetPriority(TIM4_IRQn,4,0);
        HAL_NVIC_EnableIRQ(TIM4_IRQn);
    }
     
    else if( timer_num == 7)
    {
     TIMx = TIM7;
     __HAL_RCC_TIM7_CLK_ENABLE();
     Timer_ISR.T7_Handle = ISR;
     
     Tim7_Handle.Instance = TIMx;
     Tim7_Handle.Init.Period = 10 * ms - 1;
     Tim7_Handle.Init.Prescaler = uwPrescalerValue;
     Tim7_Handle.Init.ClockDivision = 0;
     Tim7_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
     HAL_TIM_Base_Init(&Tim7_Handle);
     HAL_TIM_Base_Start_IT(&Tim7_Handle);

     HAL_NVIC_SetPriority(TIM7_IRQn,4,0);
     HAL_NVIC_EnableIRQ(TIM7_IRQn);
    }
}

void TIM1_UP_TIM10_IRQHandler(void)
//TIMER中断服务函数 1和10共用中断
{
  HAL_TIM_IRQHandler(&Tim1_Handle);
  //处理定时器1中断请求函数
}

void TIM3_IRQHandler(void)
{
  HAL_TIM_IRQHandler(&Tim3_Handle);
}

void TIM4_IRQHandler(void)
{
 HAL_TIM_IRQHandler(&Tim4_Handle);
}

void TIM7_IRQHandler(void)
{
 HAL_TIM_IRQHandler(&Tim7_Handle);
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
//用户回调函数,在HAL_TIM_IRQHandler中调用
{
 if(htim == &Tim1_Handle)
 {
   if(Timer_ISR.T1_Handle != NULL)
     Timer_ISR.T1_Handle();
     //定时器1回调
 }
 else if( htim == &Tim3_Handle)
 {
   if(Timer_ISR.T3_Handle != NULL)
   Timer_ISR.T3_Handle();
 }
 else if( htim == &Tim4_Handle)
 {
   if(Timer_ISR.T4_Handle!= NULL)
   Timer_ISR.T4_Handle();
 }
 else if(htim == &Tim7_Handle)
 {
   if(Timer_ISR.T7_Handle != NULL)
   Timer_ISR.T7_Handle();
 }
}

  • 7
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值