STM32 基本定时器

Wesley13
• 阅读 652

1. STM32****的Timer简介

STM32中一共有11个定时器,其中2个高级控制定时器,4个普通定时器和2个基本定时器,以及2个看门狗定时器和1个系统嘀嗒定时器。其中系统嘀嗒定时器是前文中所描述的SysTick,看门狗定时器以后再详细研究。今天主要是研究剩下的8个定时器。

定时器

计数器分辨率

计数器类型

预分频系数

产生DMA请求

捕获/比较通道

互补输出

TIM1

TIM8

16位

向上,向下,向上/向下

1-65536之间的任意数

可以

4

TIM2

TIM3

TIM4

TIM5

16位

向上,向下,向上/向下

1-65536之间的任意数

可以

4

没有

TIM6

TIM7

16位

向上

1-65536之间的任意数

可以

0

没有

其中TIM1和TIM8是能够产生3对PWM互补输出的高级登时其,常用于三相电机的驱动,时钟由APB2的输出产生。TIM2-TIM5是普通定时器,TIM6和TIM7是基本定时器,其时钟由APB1输出产生。由于STM32的TIMER功能太复杂了,所以只能一点一点的学习。因此今天就从最简单的开始学习起,也就是TIM2-TIM5普通定时器的定时功能。

2****基本定时器TIM6-TIM7

2.1 时钟基本特征

基本定时器TIM6和TIM7各包含一个16位自动装载计数器,由各自的可编程预分频器驱动。

它们可以作为通用定时器提供时间基准,特别地可以为数模转换器(DAC) 提供时钟。实际上,它

们在芯片内部直接连接到DAC并通过触发输出直接驱动DAC。

这2个定时器是互相独立的,不共享任何资源。

2.2 TIM6-7****主要特征

TIM6和TIM7定时器的主要功能包括:

● 16位自动重装载累加计数器

● 16位可编程( 可实时修改)预分频器,用于对输入的时钟按系数为1~65536 之间的任意数值

分频

● 触发DAC的同步电路

● 在更新事件(计数器溢出)时产生中断/DMA 请求

图144 基本定时器框图

2.3 计数器模式

TIM6-TIM7可以由向上计数。向上计数模式中,计数器从0计数到自动加载值(TIMx_ARR计数器内容),然后重新从0开始计数并且产生一个计数器溢出事件。

2.4 编程步骤

1. 配置优先级;

2. 使能时钟

3. 配置GPIO;

4. 配置TIME;

5.使能计数器;

6.开中断;

7.清除标志位;

具体配置如下:

(1) NVIC_Configuration(void);配置优先级

(2) void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)使能时钟

(3) void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);配置GPIO

(4) TIM_Configuration (void);配置TIM6/TIM7

(5) TIM_Cmd(TIM7, ENABLE);使能定时器

(6) TIM_ITConfig(TIM7,TIM_IT_Update,ENABLE);使能中断

(7) TIM_ClearFlag(TIM7, TIM_FLAG_Update);清除标志位

步骤(4)中的预分频系数用来确定TIMx所使用的时钟频率,具体计算方法为:CK_INT/(TIM_Perscaler+1)。CK_INT是内部时钟源的频率,是根据2.1中所描述的APB1的倍频器送出的时钟,TIM_Perscaler是用户设定的预分频系数,其值范围是从0 – 65535。

步骤(4)中的时钟分割定义的是在定时器时钟频率(CK_INT)与数字滤波器(ETR,TIx)使用的采样频率之间的分频比例。TIM_ClockDivision的参数如下表:

TIM_ClockDivision

描述

二进制值

TIM_CKD_DIV1

tDTS = Tck_tim

0x00

TIM_CKD_DIV2

tDTS = 2 * Tck_tim

0x01

TIM_CKD_DIV4

tDTS = 4 * Tck_tim

0x10

步骤(4)中需要禁止使用预装载缓冲器。当预装载缓冲器被禁止时,写入自动装入的值(TIMx_ARR)的数值会直接传送到对应的影子寄存器;如果使能预加载寄存器,则写入ARR的数值会在更新事件时,才会从预加载寄存器传送到对应的影子寄存器。

ARM中,有的逻辑寄存器在物理上对应2个寄存器,一个是程序员可以写入或读出的寄存器,称为preload register(预装载寄存器),另一个是程序员看不见的、但在操作中真正起作用的寄存器,称为shadow register(影子寄存器);设计preload register和shadow register的好处是,所有真正需要起作用的寄存器(shadow register)可以在同一个时间(发生更新事件时)被更新为所对应的preload register的内容,这样可以保证多个通道的操作能够准确地同步。如果没有shadow register,或者preload register和shadow register是直通的,即软件更新preload register时,同时更新了shadow register,因为软件不可能在一个相同的时刻同时更新多个寄存器,结果造成多个通道的时序不能同步,如果再加上其它因素(例如中断),多个通道的时序关系有可能是不可预知的。

3. 程序源代码

本例实现的是通过TIM7的定时功能,使得LED灯按照1s的时间间隔来闪烁

原理图:

/*
* 文件名: main.c
* 内容简述:
* 从0开始创建一个工程,通过按键1触发中断1实现灯1的闪亮
* 再通过按键2触发中断抢占 中断1实现小灯2的闪亮
*
* 2个LED指示灯,对应的GPIO为 : PC3 PC1
* 输出为0点亮LED
* 输出为1关闭LED
* 2个按键 对应 PB7 PA11
*/
#include "stm32f10x.h"

/* 延时函数 */
void Delay(__IO uint32_t nCount)
{
//__IO 就是volatile,加上这个后可以避免延时函数被编译器优化掉
for(;nCount != 0; nCount--);
}

/* GPIO配置函数 */
void GPIO_Configuration(void)
{
/*定义2个结构体变量 */
GPIO_InitTypeDef GPIO_InitStructure;
/*开启GPIOB,GPIOC ,复用口时钟的 时钟 */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE);

/*给GPIO_InitStructure.GPIO_Pin GPIO_InitStructure.GPIO_Mode GPIO_InitStructure.GPIO_Speed付初始值*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
// 将连接LED3的GPIO设置为推挽输出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
//设置为10MHZ的速度
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//初始化GPIOC
GPIO_Init(GPIOC, &GPIO_InitStructure);

}
/********配置优先级*****************/
void NVIC_Configuration(void)
{
//定义一个结构体
NVIC_InitTypeDef NVIC_InitStructure;
//设置优先级组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0) ;
//设置 TIM7线
NVIC_InitStructure.NVIC_IRQChannel =TIM7_IRQn;
//使能优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//配置抢断优先级
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0;
//配置响应优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;
NVIC_Init(&NVIC_InitStructure);
//设置存入寄存器
NVIC_SetVectorTable (NVIC_VectTab_FLASH ,0x0);

}
//*****定时器初始化*********
void TIM_Configuration (void)
{

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
// TIM_Cmd(TIM7, DISABLE);
//预分频系数为36000-1,这样计数器时钟为72MHz/36000 = 2kHz
TIM_TimeBaseStructure.TIM_Prescaler = 36000 - 1;
//设置时钟分割 TIM_CKD_DIV1=0x0000,不分割
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
//设置计数器模式为向上计数模式
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up ;
//设置计数溢出大小,每计2000个数就产生一个更新事件
TIM_TimeBaseStructure.TIM_Period = 2000 - 1;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
//将配置应用到TIM7中
TIM_TimeBaseInit(TIM7,&TIM_TimeBaseStructure);
TIM_UpdateRequestConfig( TIM7, TIM_UpdateSource_Regular);
//使能计数器
TIM_Cmd(TIM7, ENABLE);
//使能中断
TIM_ITConfig(TIM7,TIM_IT_Update,ENABLE);
//清除标志位
// TIM_ClearFlag(TIM7, TIM_FLAG_Update);
}
//*****************************

//主函数
int main(void)
{
/*
这个函数是ST库中的函数,函数实体在
Libraries\CMSIS\Core\CM3\system_stm32f10x.c
配置内部Flash接口,初始化PLL,配置系统时钟的频率
系统时钟缺省配置为72MHz
*/
GPIO_Configuration ();
NVIC_Configuration ();
TIM_Configuration ();
while(1)
{
}
}

it.c中的程序

void TIM7_IRQHandler(void)
{

//检测是否发生溢出更新事件

if(TIM_GetITStatus(TIM7, TIM_IT_Update)== SET)

{

GPIOC->ODR ^= GPIO_Pin_3;
TIM_ClearITPendingBit(TIM7 , TIM_FLAG_Update);

}

}

编程心得:

1.注意应用定时器是要开的使能 TIM_Cmd(TIM7, ENABLE)-计数器使能 TIM_ITConfig (TIM7,TIM_IT_Update,ENABLE)-中断使能 RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM7,ENABLE)-时钟

2.进入中断后一定要记得清楚标志位 TIM_ClearITPendingBit(TIM7 , TIM_FLAG_Update);

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
STM32 PWM输出
文将介绍通过STM32的定时器输出PWM,如果对定时器不太熟悉的同学可以看下之前的文章《STM32基础定时器详解(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzIxNTg1NzQwMQ%3D%3D%26mid%3D2247
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
STM32 输入捕获功能
本文将介绍通过STM32的定时器输入捕获,如果对定时器不太熟悉的同学可以看下之前的文章《STM32基础定时器详解(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzIxNTg1NzQwMQ%3D%3D%26mid%3D2247
Wesley13 Wesley13
3年前
ESP32看门狗
翻自https://docs.espressif.com/projects/espidf/zh\_CN/latest/apireference/system/wdts.html?highlightwdt\_CPPv216esp\_int\_wdt\_initv概述ESPIDF支持两种类型的看门狗:中断看门狗定时器和任务看门狗定时器(T
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这