一、基本定时器介绍

在STM32中,基本定时器有TIM6、TIM7等。基本定时器主要包含时基单元,提供16位的计数,能计数0~65535。基本定时器除了计数功能以外,还能输出给DAC模块一个TRGO信号。基本定时器框图如下:

二、时基单元介绍

STM32的所有定时器都具备时基单元,时基单元的功能就是简单的计数,即计数时钟源TMxCLK的脉冲个数,这个时钟源来至APB1总线。高级和通用定时器还可以使用其他的时钟源进行计数,在高级定时器和通用定时器中会详细介绍。在基本定时器框架中可知时基单元包含如下三个部分:

1.ARR 自动重装载寄存器

2.CNT 计数器

3.PSC  预分频器

基本定时器的定时(计数)功能配置如下:

void TIM6_IRQHandler(void)

{

static int counter = 0;

if(TIM_GetITStatus(TIM6,TIM_IT_Update))

{

//在设置TIM_SelectOnePulseMode(TIM6,TIM_OPMode_Single);后中断进去两次

TIM_ClearITPendingBit(TIM6,TIM_IT_Update);

}

}

//基本定时器

void TIM6_Configuration()

{

TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;

NVIC_InitTypeDef  NVIC_InitStruct;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); //时钟使能

TIM_TimeBaseInitStruct.TIM_Period = 10 -1;

TIM_TimeBaseInitStruct.TIM_Prescaler = 72;

TIM_TimeBaseInitStruct.TIM_ClockDivision = 0;

TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;

TIM_TimeBaseInit(TIM6,&TIM_TimeBaseInitStruct);//  TIMx->EGR.UG

NVIC_InitStruct.NVIC_IRQChannel  = TIM6_IRQn;

NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;

NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;

NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;

NVIC_Init(&NVIC_InitStruct);

TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE);

TIM_ClearITPendingBit(TIM6,TIM_IT_Update);

// TIM_SelectOnePulseMode(TIM6,TIM_OPMode_Single);//如需配置单脉冲模式,开启此注释

TIM_ARRPreloadConfig(TIM6,ENABLE);

TIM_Cmd(TIM6,ENABLE);//CEN  位

TIM_ClearITPendingBit(TIM6,TIM_IT_Update);

}

值得说明的是,基本定时器还支持单脉冲模式,配置单脉冲模式如代码注释即可。单脉冲模式要注意的是在定时器溢出两次后才关闭定时器,即失能定时器。在代码中,配置有中断,在单脉冲模式下,可以清晰的看到进入定时器中断2次。

三、定时器信号输出

定时器的信号输出与定时器中的控制寄存器2(TIM6->CR2)的MMS位相关,基本定时器输出的信号只能用作DAC的触发,而高级定时器、通用定时器的输出信号可以触发定时器以及DAC,具体细节这里不细说。定时器信号输出的例子可以参考我的博文http://blog.csdn.net/quentinecho/article/details/79068001。这个例子中使用TIM6输出的TRGO信号启动了DAC产生一个三角波,当然其他的DAC触发方式也可以产生一个三角波。

#include "stm32f10x.h"

#include "stm32f10x_rcc.h"

#include "system_stm32f10x.h"

#include "stm32f10x_dac.h"

#include "stm32f10x_gpio.h"

#include "stm32f10x_tim.h"

/*DAC输出 = Vref x (DOR/4095)*/

//DAC的两个通道可以配置使用

//相同触发源/不同触发源

//同时触发/独立触发    DAC_DualSoftwareTriggerCmd函数设置软件同时触发

//使用波形发生器/不使用波形发生器

//使用三角波发生器/使用噪声发生器/不使用波形发生器

//设置相同DAC_LFSRUnmask_TriangleAmplitude的值/设置不相同DAC_LFSRUnmask_TriangleAmplitude的值

//等等以上各种情况可以任意组合,互不影响。

void DAC_Configuration(void)

{

GPIO_InitTypeDef GPIO_InitStruct;

DAC_InitTypeDef DAC_InitStruct;

//第一步  使能时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC,ENABLE);

//第二步  配置参数

/*一旦使能DACx通道,相应的GPIO引脚就会自动与DAC的模拟输出相连,为了避免寄生的干扰和额外的功耗,引脚PA4/PA5在之前应当设置成“模拟输入”

注意是“模拟输入“,因为STM32中没有模拟输出,所以虽然PA4 PA5是输出模拟信号,也只能设置成GPIO_Mode_AIN*/

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;

GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA,&GPIO_InitStruct);

GPIO_SetBits(GPIOA,GPIO_Pin_4 | GPIO_Pin_5) ;//PA.4  PA.5输入高 ,上拉输入起抗干扰的作用

// /*DAC 通道1  PA4 产生噪声*/

// DAC_InitStruct.DAC_WaveGeneration = DAC_WaveGeneration_Noise;

// DAC_InitStruct.DAC_Trigger = DAC_Trigger_T6_TRGO;//DAC_Trigger_T6_TRGO;

// DAC_InitStruct.DAC_OutputBuffer = DAC_OutputBuffer_Disable;//输出缓存可以用来减少输出阻抗,无需外部运放即可直接驱动外部负载

// DAC_InitStruct.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bits10_0;//每次触发计算一次LSFR算法,并将得到的值再加上DAC_DHRx的数值,去掉溢出位后写入DAC_DORx寄存器,输出特定的电压

// DAC_Init(DAC_Channel_1,&DAC_InitStruct);//参与LSFR算法的位数由DAC_LFSRUnmask_TriangleAmplitude来确定,DAC_LFSRUnmask_Bits10_0数值表示有10位参与LSFR计算

/*DAC 通道1  PA4 普通数模转换*/

DAC_InitStruct.DAC_WaveGeneration = DAC_WaveGeneration_None;//关闭波形发生器

DAC_InitStruct.DAC_Trigger = DAC_Trigger_T6_TRGO;//DAC_Trigger_Software/DAC_Trigger_Ext_IT9

DAC_InitStruct.DAC_OutputBuffer = DAC_OutputBuffer_Disable;//输出缓存可以用来减少输出阻抗,无需外部运放即可直接驱动外部负载

DAC_InitStruct.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;//该参数与噪声/三角波发生器相关,普通DAC转换是设置为0即可

DAC_Init(DAC_Channel_1,&DAC_InitStruct);

/*DAC 通道2  PA5 产生三角波*/

DAC_InitStruct.DAC_WaveGeneration = DAC_WaveGeneration_Triangle;

DAC_InitStruct.DAC_Trigger = DAC_Trigger_T6_TRGO;

DAC_InitStruct.DAC_OutputBuffer = DAC_OutputBuffer_Disable;

DAC_InitStruct.DAC_LFSRUnmask_TriangleAmplitude = DAC_TriangleAmplitude_4095;//内部的三角波计数器每次触发时候之后累加1,该计数器的值与DAC_DHRx的数值相加,去掉溢出位后写入DAC_DORx寄存器,输出电压

DAC_Init(DAC_Channel_2,&DAC_InitStruct);//三角波计数器的最大值由DAC_LFSRUnmask_TriangleAmplitude来确定,当计数器达到这个最大值,然后三角波计数器开始递减

//第三步  使能器件

//DAC_SetDualChannelData(DAC_Align_12b_R,4095,0);等价于DAC_SetChannel1Data(DAC_Align_12b_R, 4095); DAC_SetChannel2Data(DAC_Align_12b_R, 0);

/*DAC 通道1  PA4 使能*/

DAC_SetChannel1Data(DAC_Align_12b_R, 4095);  //12位右对齐数据格式设置DAC值  设置值最大为4095,设置成4096则溢出,DORx即为0

DAC_Cmd(DAC_Channel_1, ENABLE);  //使能DAC1

/*DAC 通道2  PA5 使能*/

DAC_Cmd(DAC_Channel_2, ENABLE);  //使能DAC1

DAC_SetChannel2Data(DAC_Align_12b_R, 0);  //12位右对齐数据格式设置DAC值

}

//基本定时器

void TIM6_Configuration()

{

TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;

//第一步  使能时钟

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); //时钟使能

//第二步 配置参数

TIM_TimeBaseInitStruct.TIM_Period = 10 -1;

TIM_TimeBaseInitStruct.TIM_Prescaler = 72;

TIM_TimeBaseInitStruct.TIM_ClockDivision = 0;

TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;

TIM_TimeBaseInit(TIM6,&TIM_TimeBaseInitStruct);//  TIMx->EGR.UG

/*TIM6,7可以输出3种类型的TRGO信号

#define TIM_TRGOSource_Reset               ((uint16_t)0x0000) //复位 UG

#define TIM_TRGOSource_Enable              ((uint16_t)0x0010) //使能 CEN

#define TIM_TRGOSource_Update              ((uint16_t)0x0020) //更新事件

*/

TIM_SelectOutputTrigger(TIM6,TIM_TRGOSource_Update);//输出触发TRGO信号  这里TRGO信号就是定时器溢出产生的更新信号

//第三步  使能器件

TIM_Cmd(TIM6,ENABLE);//CEN  位

}

int main()

{

DAC_Configuration();

TIM6_Configuration();

while(1)

{

}

}

看到这里还是没懂的话可以参考这个视频资料

http://www.makeru.com.cn/live/1392_1199.html?s=45051

零基础入门stm32基本定时器详解的更多相关文章

  1. stm32通用定时器详解

    在stm32的开发中我们经常会用到定时器,因此在学习stm32的过程中定时器是必须要学的,而定时主要又分为三大类分别为: 高级控制定时器(TIM1与TIM8) 通用定时器(TIM2~TIM5) 基本定 ...

  2. Linux基础入门 vim常用命令详解

    介绍 vim是一个文本编辑程序 没有菜单,只有命令,且命令繁多 命令行模式下相关命令 移动光标 ​ h: ← 左移 ​ l: → 右移 ​ j: ↓ 下移 ​ k: ↑ 上移 ​ gg: 光标移动文件 ...

  3. STM32固件库详解

    STM32固件库详解   emouse原创文章,转载请注明出处http://www.cnblogs.com/emouse/ 应部分网友要求,最新加入固件库以及开发环境使用入门视频教程,同时提供例程模板 ...

  4. 040 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 02 while循环的执行流程

    040 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 02 while循环的执行流程 本文知识点:while循环的执行流程 三种循环结构中的第一种--wh ...

  5. 036 01 Android 零基础入门 01 Java基础语法 04 Java流程控制之选择结构 03 嵌套if结构

    036 01 Android 零基础入门 01 Java基础语法 04 Java流程控制之选择结构 03 嵌套if结构 本文知识点:Java中的嵌套if结构 什么是嵌套if结构? 概念: 嵌套if结构 ...

  6. STM32F103的11个定时器详解(转)

    源:STM32F103的11个定时器详解 STM32F103系列的单片机一共有11个定时器,其中:2个高级定时器4个普通定时器2个基本定时器2个看门狗定时器1个系统嘀嗒定时器 出去看门狗定时器和系统滴 ...

  7. Linux及Arm-Linux程序开发笔记(零基础入门篇)

    Linux及Arm-Linux程序开发笔记(零基础入门篇)  作者:一点一滴的Beer http://beer.cnblogs.com/ 本文地址:http://www.cnblogs.com/bee ...

  8. 2020年数据库概念与MySQL的安装与配置-从零基础入门MySQL-mysql8版本

    作者 | Jeskson 来源 | 达达前端小酒馆 从零基础入门MySQL数据库基础课 数据的概念,简介,安装与配置,Windows平台下MySQL的安装与配置. 数据库的概念:数据库是一个用来存放数 ...

  9. 【Linux开发】Linux及Arm-Linux程序开发笔记(零基础入门篇)

    Linux及Arm-Linux程序开发笔记(零基础入门篇) 作者:一点一滴的Beer http://beer.cnblogs.com/ 本文地址:http://www.cnblogs.com/beer ...

随机推荐

  1. 一文搞懂如何使用Node.js进行TCP网络通信

    摘要: 网络是通信互联的基础,Node.js提供了net.http.dgram等模块,分别用来实现TCP.HTTP.UDP的通信,本文主要对使用Node.js的TCP通信部份进行实践记录. 本文分享自 ...

  2. 环形链表II

    题目描述: 给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始). 如果 p ...

  3. Shell系列(7)- 通配符

    通配符 通配符 作用 ? 匹配一个任意字符 * 匹配0个或任意多个任意字符,也就是可以匹配任何内容 [] 匹配中括号中任意一个字符.例如:[abc]代表一定匹配一个字符,或者是a,或者是b,或者是c. ...

  4. command ' cl.exe' failed: No such file or directory解决办法

    1.安装C ++编译器 https://pan.baidu.com/s/1D1-tM-mWO4TVLdTrh3k1GA    提取码:ym67 2.找到安装文件夹:Visual C++ Build T ...

  5. django 安装redis及session使用redis存储

    环境:centos 7.4 第一:安装redis 下载redis并安装: wget http://download.redis.io/releases/redis-5.0.5.tar.gz yum - ...

  6. P3190-[HNOI2007]神奇游乐园【插头dp】

    正题 题目链接:https://www.luogu.com.cn/problem/P3190 题目大意 \(n*m\)的网格上有权值,求一条权值和最大的不交回路. \(1\leq n\leq 100, ...

  7. 测试开发【提测平台】分享12-掌握日期组件&列表状态格式化最终实现提测管理多条件搜索展示功能

    微信搜索[大奇测试开],关注这个坚持分享测试开发干货的家伙. 本章内容思维导图如下,由于需要各种状态下的菜单操作,所以需要先实现提测信息的列表基础页面,然后再推进其他需求开发 基本知识点学习 Date ...

  8. Spring动态代理的生成-如何判断是使用JDK动态代理还是CGlib代理

    前言 在上一篇文章中讲到了Spring是如何获取对应的Bean的增强,然后本次主要讲解一下Spring如何在获取到增强后创建Spring代理的. 在步入正题之前先给大家看一下Spring创建代理的大致 ...

  9. Linux下Electron loadURL报错 ERR_FAILED(-2) Not allowed to load local resource

    Linux下Electron loadURL报错 ERR_FAILED(-2) Not allowed to load local resource 背景 使用electron-vue的时候,窗体创建 ...

  10. C++核心编程 1 程序的内存模型

    1.内存分区模型 C++程序在执行时,将内存大方向划分为4个区域 代码区:存放函数体的二进制代码,由操作系统进行管理(写的所有代码都在代码区) 全局区:存放全局变量.静态变量以及常量 栈   区:由编 ...