STM32 基本定时器

发布者:雅逸之风最新更新时间:2022-03-14 来源: eefocus关键字:STM32  基本定时器 手机看文章 扫描二维码
随时随地手机看文章

本文为野火学习笔记。

定时器分类

   stm32f1系列。除互联型设备,共有8个定时器,分为基本,通用,高级3种定时器。不同的定时器有不同的功能。

  基本定时器为 TIM6,TIM7 。其只能定时,没有外部IO,且16位计数器只能向上计数。

  通用定时器为 TIM2/3/4/5 , 可以定时;也可输出比较和输入捕捉,每个定时器有4个IO,16位计数器可上下计数。

  高级定时器为 TIM1/8 ,在通用的基础上多了互补输出信号的功能,每个定时器有8个IO口。


功能框图

  下图为基本定时器的结构框图:

时钟源

  定时器的时钟源名为 TIMxCLK,可以在时钟树中找到

  可见 TIMxCLK 时钟是来自于APB1 的,而 APB1 的预分频器一般选择2分频,使得 APB1 总线的时钟为36M;因此,TIMExCLK 的时钟为72M.


计数器时钟

  时钟接入触发控制器,经过 PSC 预分频器分频,驱动CNT计数器。 PSC 为16位分配器,可对时钟信号进行1~65536分频。最终计数器的时钟计算公式如下。

image.png

  公式中分母+1的操作是官方规定的。


计数器

   CNT 为16位计数器,只能向上计数,计数达到指定数时,更新事件,清零从头计数。


自动重载寄存器

  寄存器中储存着计数最大值,计到此数,若配置了中断,会产生中断。


影子寄存器

  自动重载寄存器ARR和预分频器PSC下有阴影,表示其有影子寄存器。影子寄存器起到缓冲的作用,若在计数器仍在计数时,修改ARR或PSC的值,如果直接写入,则计数器直接清零,重新开始计数。若向影子寄存器写入,则会在当前计数周期结束后,修改值,计数器不会被打断。


定时器时间计算

image.png

中断

  基本定时器只在溢出时才会产生中断,溢出时也可产生DMA请求。TIMx_DIER寄存器控制DMA和中断的使能,TIMx_EGR 寄存器记录溢出事件的产生。


固件库编程

定时器初始化结构体

typedef struct

{

  uint16_t TIM_Prescaler;            //预分频器

  uint16_t TIM_CounterMode;          //计数模式

  uint16_t TIM_Period;               //ARR

  uint16_t TIM_ClockDivision;        //时钟分频

  uint8_t TIM_RepetitionCounter;     //重复计数器

} TIM_TimeBaseInitTypeDef; 


   在这里,计数模式表示的是向上还是向下计数。最后两个参数是不是基本定时器的功能,不用配置。


开始编程

  基本寄存器十分简单,只能计时。这里编写一个使得LED以1秒间隔闪烁的程序。


初始化TIM6

void BASIC_TIM_Config(void)

{

TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;

//BASIC_TIM_NVIC_Config();   //后面加上这句

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE);

TIM_TimeBaseStruct.TIM_Period     = 1000;

TIM_TimeBaseStruct.TIM_Prescaler  = 71;

TIM_TimeBaseInit(TIM6,&TIM_TimeBaseStruct);

//清除中断标志位

TIM_ClearFlag(TIM6,TIM_FLAG_Update);

//使能中断请求

TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE);

//使能计数器

TIM_Cmd(TIM6,ENABLE);

//暂时关闭时钟,等待使用


}


  基本定时器只能向上计数,因此,初始化结果体中只需配置 PSC 和ARR。配置PSC=71,ARR=1000。即计数一次为1ms。

  接下来我们希望在计数完成发生中断,按照 中断应用总结 中的步骤,使能外设中断。

  使用 TIM_ClearFlag 清除中断标志位,计数溢出的事件被称为更新事件,对应固件库中的标志位叫 TIM_FLAG_Update。然后使用 TIM_ITConfig 使能更新事件的中断。

  最后使用 TIM_Cmd 使能定时器。这里我们完成了TIM6的初始化和外设中断使能,下面继续配置中断。


配置中断优先级分组

  因程序只有这一个中断,优先级分组并不重要,这里配置中断优先级分组为0;


NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

1

配置NVIC

static void BASIC_TIM_NVIC_Config(void)

{

NVIC_InitTypeDef NVIC_InitStruct;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

NVIC_InitStruct.NVIC_IRQChannel    = TIM6_IRQn;

NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;

NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStruct.NVIC_IRQChannelSubPriority        = 3;

NVIC_Init(&NVIC_InitStruct);

}


  配置主优先级为0,子优先级为3。在初始化 TIM6 中使用这个函数。


中断服务函数

  在 startup_stm32f10x_hd.s 中找到TIM6中断的函数名,在 stm32f10x_it.c 编写中断服务函数。


extern volatile uint16_t time;

void TIM6_IRQHandler(void)

{

if(TIM_GetITStatus(TIM6,TIM_IT_Update) != RESET)

{

time++;

TIM_ClearITPendingBit(TIM6,TIM_IT_Update);//清除中断标志位

}

}


进入中断后,检查是否真的中断,并设一个全局变量 time, 用来完成1s的记录。最后使用 TIM_ClearITPendingBit 清除中断标志位。


main函数

#define LED_G_GPIO_PIN   GPIO_Pin_0

#define LED_G_GPIO_PORT  GPIOB

#define LED_G_TEOOGLE   {LED_G_PPIO_RORT->ODR ^= LED_G_GPIO_PIN;}


volatile uint16_t time=0;


int main(void)

{

LED_GPIO_Config();

BASIC_TIM_Config();

while(1)

{

if (time ==1000)//1s一进

{

time = 0;//计时归零

LED_G_TEOOGLE;//led反转

}

}

}

关键字:STM32  基本定时器 引用地址:STM32 基本定时器

上一篇:STM32 SPI读写FLASH
下一篇:EXTI_ClearITPendingBit与EXTI_ClearFlag区别

推荐阅读最新更新时间:2024-11-06 10:33

STM32串口自动识别波特率
1写在前面 关于自动识别UART串口波特率的这个问题,相信有项目经验,或者认真研究过串口的朋友都应该多多少少知道一点自动识别的方法。 可能绝大部分知道的就是通过波特率一一匹配来实现,这种方法也是最常见,而且还比较有效的一种方法。 上面这种方法就是大家熟知的通过软件来检测波特率的方法,其实,还有一种方法就是通过硬件自身完成波特率来检测。 针对STM32,在ST官方其实在应用笔记和参考手册文档中都有提到。下面,我结合文档简单讲下硬件自动波特率检测的内容。 2 STM32硬件自动波特率检测 ABR:Auto Baud Rate,自动波特率检测使接收设备能够接受来自各种以不同速率工作的发送设备的数据,无需事先建立数据
[单片机]
<font color='red'>STM32</font>串口自动识别波特率
stm32 外设配置时注意RCC开启的问题
RCC的全称是Reset and Clock Control 复位和时钟控制 复位就不必讲了,和实际编程的联系不是很大。 时钟是必须要理解的,不然程序就不能按照设计的来运行。 例如: GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); RCC_APB2PeriphClockCmd(RCC_APB2Periph
[单片机]
stm32 窗口看门狗 wwdg与独立看门狗iwdg的配置运用
STM32笔记之十二:时钟不息工作不止,systic时钟应用 a) 目的:使用系统时钟来进行两项实验 周期执行代码与精确定时延迟。 b) 初始化函数定义: void SysTick_Configuration(void); c) 初始化函数调用: SysTick_Configuration(); d) 初始化函数: void SysTick_Configuration(void) { SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//时钟除8 SysTick_SetReload(250000);
[单片机]
通过串口实现stm32的IAP功能
感觉stm32官方的IAP例程写的太乱了,于是自己写了个串口IAP,希望可以帮助到正在或者即将学习IAP的童鞋们! 用的MCU是stm32f103ze,编译工具室IAR 5.4,仅仅用了USART1,不需要按键来,即仅仅使用了2个管脚,就实现了串口IAP的功能。 大概思路如下: IAP部分:IAP地址如下 #define StartAddr ((u32)0x08000000) #define EndAddr ((u32)0x08010000) IAP 程序部分大概思路: 1.将 通过串口接收的APP文件利用数组先保存下来存储到USART_Buffer中
[单片机]
STM32 ADC转换
STM32具有1~3个ADC。这些ADC可以相互独立使用,也可以使用双重模式。STM32的ADC是12位逐次逼近型的模拟/数字转换器。它有18个通道,可测量16个外部和2个内部信号源。各通道可以单次、连续、扫描或间断模式执行。 ADC其实检测的是电压信号,然后在将它转换数字信号。在我使用开发板上,ADC能检测的电压范围为0~3.3v,其转换成数字信号后对应的数字量范围为:0~4095。 下面就讲讲STM32 ADC转换功的实现。还是基于我自己的规范工程上修改!! 1、工程的修改 1)由于要使用ADC功能,必须使用到库文件stm32f10x_adc.c,所以将是stm32f10x_adc.c文件添加到STM32F10x_Std
[单片机]
<font color='red'>STM32</font> ADC转换
stm32之DMA研究
在做实验之前,首先必须明白什么是DMA,DMA的作用又体现在哪里。 DMA,即直接内存存储,在一些数据的传输中,采用DMA方式,从而将CPU解放出来。让CPU有足够的时间处理其他的事情。 stm32使用DMA的相关操作: 1、DMA的配置 要配置的有DMA传输通道选择,传输的成员和方向、普通模式还是循环模式等等。 void DMA_Configuration(void) { DMA_InitTypeDef DMA_InitStructure; //DMA设置: //设置DMA源:内存地址&串口数据寄存器地址 //方向:内存-- 外设 //每次传输位:8bit //传输大小DMA_BufferSize=SEN
[单片机]
一种基于STM32利用始终定时实现延迟的方法
  传统上我们常用delay函数进行延迟,然而这种方式有一个很大的弊端那就是需要占用相当长的时钟周期,此时原本该用于计算各类复杂算法的计算内核都要随着系统一起停下来,很不经济也容易造成问题处理不及时的后果。   事实上,我们只需要利用时钟中断的方式,利用一个全局变量作为标志为即可具体程序如下: u8 time3_tmp = 0;//时钟标志 u8 fun_flag;//服务函数标志 void Timer3_Config(void)//配置 { TIM_TimeBaseInitTypeDef TIM_TimeBaseStruture; ////////重定义结构体 TIM_DeInit(TIM3);
[单片机]
STM32-DAC生成1Hz三角波【DAC触发方式深入理解】
前文《STM32-一文搞懂DAC》的1.2节对触发方式进行了详细的说明,也简单介绍了三角波的生成原理。本文记如何配置一定频率的三角波以及为什么这么配置。 1 概述 三角波的数据生成是由一个单独的计数器往复加减生成的,每次触发之后该计数器会加1/减1。在每个周期过峰值之前,每次触发条件之后加1;过峰值之后,每次触发条件之后减1。但是要先想生成三角波必须以固定的周期加减其输出幅度!也就是以固定的周期触发转换!怎么办呢?谁可以让它以固定的周期?哈哈蛤,定时器!通过设定三角波计数器最大值、定时器触发周期,就可以确定生成的三角波的频率。 前文回顾: DACx模块内部有一个三角波计数器,每次触发事件之后3个APB1时钟周期后累加1
[单片机]
STM32-DAC生成1Hz三角波【DAC触发方式深入理解】
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved