STM32:基本定时器详解

发布者:丝语轻风最新更新时间:2018-12-28 来源: eefocus关键字:stm32  基本定时器 手机看文章 扫描二维码
随时随地手机看文章

一、基本定时器介绍


在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)

{

}

}


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

上一篇:stm32 运行时间测量与间隔执行
下一篇:STM32定时器写精准的延时函数

推荐阅读最新更新时间:2024-03-16 16:21

STM32学习笔记---SysTick定时器
Q:什么是SYSTick定时器? SysTick 是一个24 位的倒计数定时器,当计到0 时,将从RELOAD 寄存器中自动重装载定时初值。只要不把它在SysTick 控制及状态寄存器中的使能位清除,就永不停息。 Q:为什么要设置SysTick定时器? (1)产生操作系统的时钟节拍 SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常(异常号:15)。在以前,大多操作系统需要一个硬件定时器来产生操作系统需要的滴答中断,作为整个系统的时基。因此,需要一个定时器来产生周期性的中断,而且最好还让用户程序不能随意访问它的寄存器,以维持操作系统 心跳 的节律。 (2)便于不同处理器之间程序移植。 Cortex‐M3处
[单片机]
<font color='red'>STM32</font>学习笔记---SysTick<font color='red'>定时器</font>
stm32汇编实例
例子一 1 ;RCC寄存器地址映像 2 RCC_BASE EQU 0x40021000 3 RCC_CR EQU (RCC_BASE + 0x00) 4 RCC_CFGR EQU (RCC_BASE + 0x04) 5 RCC_CIR EQU (RCC_BASE + 0x08) 6 RCC_APB2RSTR EQU (RCC_BASE + 0x0C) 7 RCC_APB1RSTR EQU (RCC_BASE + 0x10) 8 RCC_AHBENR EQ
[单片机]
<font color='red'>stm32</font>汇编实例
STM32 分散加载文件 .sct 解析
1、STM32 启动文件与 .sct 文件分析 1) 定义STACK段,{NOINIT,读写}:分配一段内存大小为0.5K; 2) 定义HEAP段, {NOINIT,读写}:分配一段内存大小为1K; 3) 定义RESET段,{DATA,只读}:DCD各种中断向量; 4) 定义|.text|段,{CODE,只读}:Reset_Handler函数,函数中最后加载了__main; 对剩余的中断函数进行了弱定义; 在最后还有一段用户初始化堆栈的代码__user_initial_stackheap。 那这些代码都存放在什么位置呢? 5) 分析 .sct 文件: 分散加载文件(即scatter file,后
[单片机]
STM32芯片引脚为什么有那么多组VDD?
做过单片机产品的朋友都知道,STM32芯片有多组VDD和VSS,如下图: 那么为什么有这么多引脚呢?少一点不好吗?引脚越少,PCB走线越容易。 其实芯片这样设计是有原因的。 1、增加电流供应能力 单片机IO口输出电流的能力是有限的,传统单片机的IO口一般为10mA左右,现在单片机的IO口一般为20-25mA。 多个IO口加起来,相当于增加了很多供电通道,扩大了电流供应能力。相比单个引脚的VDD,增强了可靠性。 如图,假如一个IO口流过的电流是20mA,三个IO口就是60mA。 2、方便就近取电 为了方便描述,我画了一个如下示意图。 假如只有一组VDD,从①处供电,当②处需要用电时,只能沿着箭头所示路径流动,可以看出距离较远
[单片机]
<font color='red'>STM32</font>芯片引脚为什么有那么多组VDD?
(五)stm32工程代码HardFault异常查错调试方法
一、导致异常的原因很多,例如:直接使用未分配空间的指针、栈溢出等一场非法操作便会使程序进入HardFault异常状态。下面介绍怎么找出程序中的异常。 接下来在keil_MDK工程中,编译代码,并debug,之后全速运行,可以看到如下图所示程序进入HardFault异常。 如下所示我们找到SP寄存器,0x200045B8即为栈地址,栈里面的值依次为R0~R3、R12、PC(Return address)、xPSR(CPSR或SPSR)、LR。如图我们看到划红线的地方,注意从右往左看。分别为0x0800427D和0x08004BFA。 在show code at address中输入0x08004BFA,点击go to即找
[单片机]
(五)<font color='red'>stm32</font>工程代码HardFault异常查错调试方法
stm32的IO模式具体意义
Ⅰ、写在前面 在开发STM32的时候,都需要对IO的模式进行配置(GPIO_InitStructure. GPIO_Mode = xxx)。但是,你们都知道各种模式的具体意义吗? 有的人问:IO口输出可以上拉吗? 开漏输出是干什么用的? 其实这些问题并不难,只要你了解到每一种模式的真正意思,相信这些问题都不会难道你。本文的内容比较基础,也比较实用,希望对你有所帮助。 关于本文的详细内容请看下面章节 Ⅱ、模式说明 STM32芯片的IO有8中模式: (1)GPIO_Mode_AIN 模拟输入 (2)GPIO_Mode_IN_FLOATING 浮空输入 (3)GPIO_Mode_IPD 下拉输入 (4)GPIO_Mode_IPU 上
[单片机]
<font color='red'>stm32</font>的IO模式具体意义
STM32学习之Flash(主存储块、系统存储器和选项字节)详解
说到STM32的FLSAH,我们的第一反应是用来装程序的,实际上,STM32的片内FLASH不仅用来装程序,还用来装 芯片 配置、芯片ID、自举程序等等。当然, FLASH还可以用来装数据。 自己收集了一些资料,现将这些资料总结了一下,不想看的可以直接调到后面看怎么操作就可以了。 FLASH分类 根据用途,STM32片内的FLASH分成两部分:主存储块、信息块。 主存储块用于存储程序,我们写的程序一般存储在这里。 信息块又分成两部分:系统存储器、选项字节。 系统存储器存储用于存放在系统存储器自举模式下的启动程序(BootLoader),当使用ISP方式加载程序时,就是由这个程序执行。这个区域由芯片厂写入BootLoa
[单片机]
意法STM32系列获ARM RealView微控制器开发工具包支持
ARM公司日前宣布RealView微控制器开发工具包将支持意法半导体基于ARM Cortex-M3处理器的全新STM32F1xx系列器件。 STM32F101(接入行)和STM32F103(性能行)将是意法半导体首个基于ARM Cortex-M3处理器的器件系列,兼具卓越的高性能和低功耗。该系列器件拥有高达72MHz的CPU时钟速度、128Kbyte片上闪存ROM及20Kbyte片上RAM,还包括A/D、CAN、USB、SPI、I2C等众多外设及多达80个GPIO。 RealView微控制器开发工具包3.1可为新器件提供支持。这一最新版本保留了Keil Vision 3集成开发环境(IDE)易于使用的特性,并增加了针对STM3
[焦点新闻]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

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