文档章节

stm32 通用定时器使用

kangxin1234
 kangxin1234
发布于 2015/09/07 20:41
字数 1426
阅读 397
收藏 5

        stm32的定时器又多又复杂,但复杂意味着强大吧。我用的是stm32f103ZET6,有2个基本定时器TIM6和TIM7可以用来触发DAC,4个通用定时器TIM2,TIM3,TIM4,TIM5,两个高级定时器TIM1和TIM8,还有两个专用定时器SysTick和RTC。

        TIM2,3,4,5,6挂在APB1总线上,TIM1,8挂在APB2总线上,V3.5固件库默认时钟为APB1=36MHz,APB2=72MHz。不过由于对于定时器来说APB1预分频系数为1时频率*2,所以定时器计数时钟TIMXCLK都为72MHz。

        通用定时器功能:1、基本时基功能计时。2、输入捕获(可用于测量脉冲周期和占空比)。3、输出比较(四个通道可以当做四个定时器使用)。4、PWM功能。5、正交编码器。

        基本定时器:首先也是最重要的当然是定时器的时钟配置了,如果TIMXCLK是72MHz,根据你的需要对时钟进行分频,分频就是对结构体中的两个成员进行赋值,

.TIM_Prescaler  //这个成员是预分频,对应一个16位的分频寄存器,也就是说你可以进行1-65536分频。这个分频一般都能满足需求。
.TIM_ClockDivision //这个是分频可能会对,定时器外部计数时的滤波器有影响,所以不用它就行,直接赋值为TIM_CKD_DIV1一分频,就是不分频。因为.TIM_Prescaler这个分频就够用了。

        简单定时功能配置方式如下:

void tim2Config(void)          //简单定时功能
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); 	//使能时钟
	TIM_TimeBaseStructInit(&TIM_TimeBaseInitStructure);					
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;		//向上计数
	TIM_TimeBaseInitStructure.TIM_Prescaler = 71;	        //71+1分频,1MHz周期1us
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;//时钟不分频
	TIM_TimeBaseInitStructure.TIM_Period = 1000-1;		//溢出周期1000	=  1ms	
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);	
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);	
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);	//开启溢出中断计数到TIM_Period时,发生中断				
	TIM_Cmd(TIM2, ENABLE);			//使能TIM2		

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);		//配置中断向量
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}

        关于中断向量可以看一下这个博客:http://www.cnblogs.com/dyllove98/archive/2013/08/01/3230973.html

中断函数:

void TIM2_IRQHandler(void)
{
		
    if( TIM_GetITStatus(TIM2 , TIM_IT_Update) != RESET ) //是否为溢出中断
    {
		 
		
		TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update); //清除中断挂起位           
    }
}

        这里注意一定要清除中断挂起位,不然会一直中断。

2、PWM模式:

    PWM模式理解起来简单其实就是有两个寄存器,一个是周期寄存器,另一个是比较寄存器。周期寄存器控制周期,比较寄存器控制有效电平(是高电平还是低电平由.TIM_OCPolarity_High的值决定)时间。假如向上计数时,计数器寄存器从零计数,计数到达比较寄存器中的值之前一直为有效电平,之后为另一个电平。计数到周期寄存器中的值时,一个周期完成。这样就成了PWM了。

1、配置GPIO模式。2、配置TIM_TimeBaseInitTypeDef结构体。3、配置TIM_OCInitTypeDef结构体。

static void TIM3_GPIO_Config(void) 
{
  GPIO_InitTypeDef GPIO_InitStructure;

	/* TIM3 clock enable */
	//PCLK1经过2倍频后作为TIM3的时钟源等于72MHz
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); 

  /* GPIOA and GPIOB clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE); 

  /*GPIOA Configuration: TIM3 channel 1 and 2 as alternate function push-pull */
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;		    // 复用推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /*GPIOB Configuration: TIM3 channel 3 and 4 as alternate function push-pull */
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_0 | GPIO_Pin_1;

  GPIO_Init(GPIOB, &GPIO_InitStructure);
}

/*
 * 函数名:TIM3_Mode_Config
 * 描述  :配置TIM3输出的PWM信号的模式,如周期、极性、占空比
 * 输入  :无
 * 输出  :无
 * 调用  :内部调用
 */
static void TIM3_Mode_Config(void)
{
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;

	/* PWM信号电平跳变值 */
	u16 CCR1_Val = 500;        
	u16 CCR2_Val = 375;
	u16 CCR3_Val = 250;
	u16 CCR4_Val = 125;

/* -----------------------------------------------------------------------
    TIM3 Configuration: generate 4 PWM signals with 4 different duty cycles:
    TIM3CLK = 72 MHz, Prescaler = 0x0, TIM3 counter clock = 72 MHz
    TIM3 ARR Register = 999 => TIM3 Frequency = TIM3 counter clock/(ARR + 1)
    TIM3 Frequency = 72 KHz.
    TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR)* 100 = 50%
    TIM3 Channel2 duty cycle = (TIM3_CCR2/ TIM3_ARR)* 100 = 37.5%
    TIM3 Channel3 duty cycle = (TIM3_CCR3/ TIM3_ARR)* 100 = 25%
    TIM3 Channel4 duty cycle = (TIM3_CCR4/ TIM3_ARR)* 100 = 12.5%
  ----------------------------------------------------------------------- */

  /* Time base configuration */		 
  TIM_TimeBaseStructure.TIM_Period = 999;       //当定时器从0计数到999,即为1000次,为一个定时周期
  TIM_TimeBaseStructure.TIM_Prescaler = 71;	    //设置预分频:不预分频,即为72MHz
  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;	//设置时钟分频系数:不分频
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //向上计数模式

  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

  /* PWM1 Mode configuration: Channel1 */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;	    //配置为PWM模式1
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;	
  TIM_OCInitStructure.TIM_Pulse = CCR1_Val;	   //设置跳变值,当计数器计数到这个值时,电平发生跳变
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  //当定时器计数值小于CCR1_Val时为高电平

  TIM_OC1Init(TIM3, &TIM_OCInitStructure);	 //使能通道1

  TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);

  /* PWM1 Mode configuration: Channel2 */
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR2_Val;	  //设置通道2的电平跳变值,输出另外一个占空比的PWM

  TIM_OC2Init(TIM3, &TIM_OCInitStructure);	  //使能通道2

  TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);

  /* PWM1 Mode configuration: Channel3 */
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR3_Val;	//设置通道3的电平跳变值,输出另外一个占空比的PWM

  TIM_OC3Init(TIM3, &TIM_OCInitStructure);	 //使能通道3

  TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);

  /* PWM1 Mode configuration: Channel4 */
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR4_Val;	//设置通道4的电平跳变值,输出另外一个占空比的PWM

  TIM_OC4Init(TIM3, &TIM_OCInitStructure);	//使能通道4

  TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);

  TIM_ARRPreloadConfig(TIM3, ENABLE);			 // 使能TIM3重载寄存器ARR

  /* TIM3 enable counter */
  TIM_Cmd(TIM3, ENABLE);                   //使能定时器3	
}

/*
 * 函数名:TIM3_PWM_Init
 * 描述  :TIM3 输出PWM信号初始化,只要调用这个函数
 *         TIM3的四个通道就会有PWM信号输出
 * 输入  :无
 * 输出  :无
 * 调用  :外部调用
 */
void TIM3_PWM_Init(void)
{
	TIM3_GPIO_Config();
	TIM3_Mode_Config();	
}

改变PWM占空比,即是改变比较寄存器的值。使用这个函数

void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);
void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3);
void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4);

使用方法简单例如要改变,TIM3通道1的占空比就这样,TIM_SetCompare1(TIM3, 900); 900为新的比较寄存器的值。

工程文件链接timer.c timer.h stm32f10x_it.c

© 著作权归作者所有

上一篇: stm32 DMA使用
下一篇: stm32 Uart 串口
kangxin1234

kangxin1234

粉丝 38
博文 51
码字总数 35417
作品 0
程序员
私信 提问
【STM32】通用定时器的基本原理(实例:定时器中断)

STM32F1xx官方资料: 《STM32中文参考手册V10》-第14章通用定时器 STM32的定时器 STM32F103ZET6一共有8个定时器,其中分别为: 高级定时器(TIM1、TIM8);通用定时器(TIM2、TIM3、TIM4、T...

qq_38410730
2018/04/18
0
0
STM32 定时器输入捕获实现红外遥控数据接收

之前已经写过了一个使用定时器普通计时功能来识别红外遥控数据的文章。本次是使用定时器输入捕获来实现,这种方法比起定时器普通计数来说要更加复杂一些,不过效果会更好。 一、原理 1、红外...

u011303443
2017/09/11
0
0
STM32 嵌入式学习入门(4)——PWM原理

STM32 嵌入式学习入门(4)——PWM原理 本文先对STM32F103的通用定时器作一简单介绍,然后详细介绍通用定时器的一个应用——输出PWM波形的原理。整个文章以介绍“怎么用”为主,对于通用定时...

felikzhang
2018/02/13
0
0
STM32 通用定时器的输出PWM功能 学习笔记

首先来说,你要使用PWM模式你得先选择用哪个定时器来输出PWM吧!除了TIM6、TIM7这两个普通的定时器无法输出PWM外,其余的定时器都可以输出PWM,每个通用定时器可以输出4路PWM,高级定时器TIM...

liuyong19
2017/07/19
0
0
STM32学习笔记(5)——通用定时器PWM输出

1、TIMER输出PWM基本概念 脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是...

葫芦娃的后桌
2018/08/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

视频如何加水印?

很多视频制作者的视频都被他人盗用过,为了防止自己的劳动成果被他人窃取,给视频加水印对于视频制作者来说,是一件非常重要的事情。那么下面分享一个手机给视频加水印的方法,一起来看看吧!...

白米稀饭2019
30分钟前
5
0
004-Envelop-基于Blockstack的文件传输dapp

本篇文章主要介绍基于Blockstack的文件传输工具; ####A-链接地址 官网地址:https://envelop.app/ Github地址:https://github.com/envelop-app ####B-特性: 1: Share private files easil...

Riverzhou
33分钟前
7
0
SpringCloud——声明式调用Feign

Feign声明式调用 一、Feign简介 使用Ribbon和RestTemplate消费服务的时候,有一个最麻烦的点在于,每次都要拼接URL,组织参数,所以有了Feign声明式调用,Feign的首要目标是将Java HTTP客户端...

devils_os
39分钟前
7
0
《JAVA核心知识》学习笔记 (22. 数据结构)

22.1.1. 栈(stack) 栈( stack)是限制插入和删除只能在一个位置上进行的表,该位置是表的末端,叫做栈顶 (top)。它是后进先出(LIFO)的。对栈的基本操作只有 push(进栈)和 pop(出栈...

Shingfi
44分钟前
6
0
你对AJAX认知有多少(1)?

AJAX(一) AJAX技术对于前段或者后端工程师来说,都是必不可缺的 那我们这几期都来细细品味一下AJAX的相关知识,直接上干货喽~ 1、什么是AJAX,为什么要使用Ajax(请谈一下你对Ajax的认识) 什么...

理性思考
52分钟前
15
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部