stm32f407探索者开发板(二十三)——定时器中断实验

简介: stm32f407探索者开发板(二十三)——定时器中断实验

一、通用定时器知识回顾

1.1 时钟的选择

计数器时钟可以由下列时钟源提供:(这里,我们选第一个)

内部时钟(CK_INT)

②外部时钟模式1:外部输入脚(TIx)

③外部时钟模式2:外部触发输入(ETR)(仅适用TIM2,3,4)

④内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器Timer1而作为另一个定时器Timer2的预分频器。

1.2 内部时钟的选择

如果APB1的分频系数不是1,则通用定时器的时钟等于APB1时钟的2倍

如果APB1的分频系数是1,则通用定时器的时钟等于APB1时钟。

1.3 计数器模式

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

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

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

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

二、常用寄存器和库函数配置

2.1 计数器当前值寄存器CNT

对数值进行加减

2.2 预分频寄存器TIMx_PSC

对时钟进行预分频

2.3 自动重装载寄存器(TIMx_ARR)

对计数器自动重装载(数值)

2.4 控制寄存器1(TIMx_CR1)

确定向上还是向下计数器

2.5 DMA中断使能寄存器(TIMx_DIER)

·位0·进行使能中断

2.6 定时器参数初始化

void TIM_TimeBaseInit(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;  //
  uint8_t TIM_RepetitionCounter; //高级定时器
} TIM_TimeBaseInitTypeDef; 


主要是前面三个,下面是范例

TIM_TimeBaseStructure.TIM_Period = 4999; TIM_TimeBaseStructure.TIM_Prescaler =7199; TIM_TimeBaseStructure.TIM_ClockDivision =   TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode =   TIM_CounterMode_Up; 
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); 

2.7 定时器使能函数

void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)

2.8 定时器中断使能函数

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

2.9 状态标志位获取和清除

FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);

三、手把手写定时器中断实验

3.1 步骤

使能定时器时钟

RCC_APB1PeriphClockCmd();

初始化定时器,配置ARR,PSC

TIM_TimeBaseInit();

开启定时器中断,配置NVIC

NVIC_Init();

使能定时器

TIM_Cmd();

编写中断服务函数

TIMx_IRQHandler();

3.2 程序要求

通过定时器中断配置,每500ms中断一次,然后中断服务函数中控制LED实现LED1状态取反(闪烁)。

Tout(溢出时间)=(ARR+1)(PSC+1)/Tclk

3.3 timer.c

#include "timer.h"
#include "led.h"
void TIM3_Init(u16 arr,u16 psc)
{
  TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStrue;
  NVIC_InitTypeDef NVIC_InitStruc;
  
  TIM_TimeBaseInitStrue.TIM_ClockDivision=TIM_CKD_DIV2;
  TIM_TimeBaseInitStrue.TIM_CounterMode=TIM_CounterMode_Up;
  TIM_TimeBaseInitStrue.TIM_Period=arr;
  TIM_TimeBaseInitStrue.TIM_Prescaler=psc;
  
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //使能定时器时钟
  TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStrue);
  TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
  
  NVIC_InitStruc.NVIC_IRQChannel=TIM3_IRQn;
  NVIC_InitStruc.NVIC_IRQChannelCmd=ENABLE;
  NVIC_InitStruc.NVIC_IRQChannelPreemptionPriority=0X01;
  NVIC_InitStruc.NVIC_IRQChannelSubPriority=0X03;
  NVIC_Init(&NVIC_InitStruc);
  
  TIM_Cmd(TIM3,ENABLE);
}


void TIM3_IRQHandler(void)
{
  if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)
  {
    LED1=!LED1;
    TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
  }
}

相关文章
|
4月前
|
传感器
stm32f407探索者开发板(二十二)——通用定时器基本原理讲解
stm32f407探索者开发板(二十二)——通用定时器基本原理讲解
325 0
|
4月前
STM32CubeMX 定时器
STM32CubeMX 定时器
137 0
|
4月前
|
程序员
stm32f407探索者开发板(二十一)——窗口看门狗
stm32f407探索者开发板(二十一)——窗口看门狗
137 0
|
4月前
|
芯片
stm32f407探索者开发板(二十)——独立看门狗实验
stm32f407探索者开发板(二十)——独立看门狗实验
293 0
|
5月前
使用STM32F103标准库实现定时器控制LED点亮和关闭
通过这篇博客,我们学习了如何使用STM32F103标准库,通过定时器来控制LED的点亮和关闭。我们配置了定时器中断,并在中断处理函数中实现了LED状态的切换。这是一个基础且实用的例子,适合初学者了解STM32定时器和中断的使用。 希望这篇博客对你有所帮助。如果有任何问题或建议,欢迎在评论区留言。
416 2
|
4月前
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
675 0
|
6月前
|
传感器
STM32标准库ADC和DMA知识点总结-1
STM32标准库ADC和DMA知识点总结
|
5月前
|
IDE 开发工具
使用STM32F103标准库实现自定义键盘
通过本文,我们学习了如何使用STM32F103标准库实现一个简单的自定义键盘。我们首先初始化了GPIO引脚,然后实现了一个扫描函数来检测按键状态。这个项目不仅能够帮助我们理解STM32的GPIO配置和按键扫描原理,还可以作为进一步学习中断处理和低功耗设计的基础。希望本文对你有所帮助,祝你在嵌入式开发的道路上不断进步!
498 4