STM32通用定时器基本定时功能与PWM_第1页
STM32通用定时器基本定时功能与PWM_第2页
STM32通用定时器基本定时功能与PWM_第3页
STM32通用定时器基本定时功能与PWM_第4页
STM32通用定时器基本定时功能与PWM_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

/1.

STM32的Timer简介STM32中一共有11个定时器,其中2个高级控制定时器,4个普通定时器和2个基本定时器,以及2个看门狗定时器和1个系统嘀嗒定时器.其中系统嘀嗒定时器是前文中所描述的SysTick,看门狗定时器以后再详细研究。今天主要是研究剩下的8个定时器。定时器计数器分辨率计数器类型预分频系数产生DMA请求捕获/比较通道互补输出TIM1TIM816位向上,向下,向上/向下1—65536之间的任意数可以4有TIM2TIM3TIM4TIM516位向上,向下,向上/向下1-65536之间的任意数可以4没有TIM6TIM716位向上1-65536之间的任意数可以0没有其中TIM1和TIM8是能够产生3对PWM互补输出的高级登时其,常用于三相电机的驱动,时钟由APB2的输出产生。TIM2—TIM5是普通定时器,TIM6和TIM7是基本定时器,其时钟由APB1输出产生。由于STM32的TIMER功能太复杂了,所以只能一点一点的学习。因此今天就从最简单的开始学习起,也就是TIM2-TIM5普通定时器的定时功能.

2.

普通定时器TIM2-TIM52.1

时钟来源计数器时钟可以由下列时钟源提供:·内部时钟(CK_INT)·外部时钟模式1:外部输入脚(TIx)·外部时钟模式2:外部触发输入(ETR)

·内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器Timer1而作为另一个定时器Timer2的预分频器。

由于今天的学习是最基本的定时功能,所以采用内部时钟。TIM2—TIM5的时钟不是直接来自于APB1,而是来自于输入为APB1的一个倍频器。这个倍频器的作用是:当APB1的预分频系数为1时,这个倍频器不起作用,定时器的时钟频率等于APB1的频率;当APB1的预分频系数为其他数值时(即预分频系数为2、4、8或16),这个倍频器起作用,定时器的时钟频率等于APB1的频率的2倍。APB1的分频在STM32_SYSTICK的学习笔记中有详细描述.通过倍频器给定时器时钟的好处是:APB1不但要给TIM2-TIM5提供时钟,还要为其他的外设提供时钟;设置这个倍频器可以保证在其他外设使用较低时钟频率时,TIM2—TIM5仍然可以得到较高的时钟频率。2.2

计数器模式TIM2—TIM5可以由向上计数、向下计数、向上向下双向计数.向上计数模式中,计数器从0计数到自动加载值(TIMx_ARR计数器内容),然后重新从0开始计数并且产生一个计数器溢出事件.在向下模式中,计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件.而中央对齐模式(向上/向下计数)是计数器从0开始计数到自动装入的值-1,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数。2.3

编程步骤1.

配置系统时钟;2.

配置NVIC;3。

配置GPIO;4。

配置TIMER;其中,前3项在前面的笔记中已经给出,在此就不再赘述了。第4项配置TIMER有如下配置:(1)

利用TIM_DeInit()函数将Timer设置为默认缺省值;(2)

TIM_InternalClockConfig()选择TIMx来设置内部时钟源;(3)

TIM_Perscaler来设置预分频系数;(4)

TIM_ClockDivision来设置时钟分割;(5)

TIM_CounterMode来设置计数器模式;(6)

TIM_Period来设置自动装入的值(7)

TIM_ARRPerloadConfig()来设置是否使用预装载缓冲器(8)

TIM_ITConfig()来开启TIMx的中断其中(3)-(6)步骤中的参数由TIM_TimerBaseInitTypeDef结构体给出。步骤(3)中的预分频系数用来确定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_DIV1tDTS=Tck_tim0x00TIM_CKD_DIV2tDTS=2*Tck_tim0x01TIM_CKD_DIV4tDTS=4*Tck_tim0x10数字滤波器(ETR,TIx)是为了将ETR进来的分频后的信号滤波,保证通过信号频率不超过某个限定。步骤(7)中需要禁止使用预装载缓冲器。当预装载缓冲器被禁止时,写入自动装入的值(TIMx_ARR)的数值会直接传送到对应的影子寄存器;如果使能预加载寄存器,则写入ARR的数值会在更新事件时,才会从预加载寄存器传送到对应的影子寄存器。ARM中,有的逻辑寄存器在物理上对应2个寄存器,一个是程序员可以写入或读出的寄存器,称为preloadregister(预装载寄存器),另一个是程序员看不见的、但在操作中真正起作用的寄存器,称为shadowregister(影子寄存器);设计preloadregister和shadowregister的好处是,所有真正需要起作用的寄存器(shadowregister)可以在同一个时间(发生更新事件时)被更新为所对应的preloadregister的内容,这样可以保证多个通道的操作能够准确地同步。如果没有shadowregister,或者preloadregister和shadowregister是直通的,即软件更新preloadregister时,同时更新了shadowregister,因为软件不可能在一个相同的时刻同时更新多个寄存器,结果造成多个通道的时序不能同步,如果再加上其它因素(例如中断),多个通道的时序关系有可能是不可预知的。

3。

程序源代码本例实现的是通过TIM2的定时功能,使得LED灯按照1s的时间间隔来闪烁

#include"stm32f10x_lib.h"

voidRCC_cfg();voidTIMER_cfg();voidNVIC_cfg();voidGPIO_cfg();

intmain(){

RCC_cfg();

NVIC_cfg();

GPIO_cfg();

TIMER_cfg();

//开启定时器2

TIM_Cmd(TIM2,ENABLE);

while(1);}

voidRCC_cfg(){

//定义错误状态变量

ErrorStatusHSEStartUpStatus;

//将RCC寄存器重新设置为默认值

RCC_DeInit();

//打开外部高速时钟晶振

RCC_HSEConfig(RCC_HSE_ON);

//等待外部高速时钟晶振工作

HSEStartUpStatus=RCC_WaitForHSEStartUp();

if(HSEStartUpStatus==SUCCESS)

{

//设置AHB时钟(HCLK)为系统时钟

RCC_HCLKConfig(RCC_SYSCLK_Div1);

//设置高速AHB时钟(APB2)为HCLK时钟

RCC_PCLK2Config(RCC_HCLK_Div1);

//设置低速AHB时钟(APB1)为HCLK的2分频

RCC_PCLK1Config(RCC_HCLK_Div2);

//设置FLASH代码延时

FLASH_SetLatency(FLASH_Latency_2);

//使能预取指缓存

FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

//设置PLL时钟,为HSE的9倍频

8MHz*9=72MHz

RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);

//使能PLL

RCC_PLLCmd(ENABLE);

//等待PLL准备就绪

while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);

//设置PLL为系统时钟源

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

//判断PLL是否是系统时钟

while(RCC_GetSYSCLKSource()!=0x08);

//允许TIM2的时钟

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);

//允许GPIO的时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

voidTIMER_cfg(){

TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;

//重新将Timer设置为缺省值

TIM_DeInit(TIM2);

//采用内部时钟给TIM2提供时钟源

TIM_InternalClockConfig(TIM2);

//预分频系数为36000-1,这样计数器时钟为72MHz/36000=2kHz

TIM_TimeBaseStructure.TIM_Prescaler=36000-1;

//设置时钟分割

TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;

//设置计数器模式为向上计数模式

TIM_TimeBaseStructure。TIM_CounterMode=TIM_CounterMode_Up;

//设置计数溢出大小,每计2000个数就产生一个更新事件

TIM_TimeBaseStructure.TIM_Period=2000-1;

//将配置应用到TIM2中

TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);

//清除溢出中断标志

TIM_ClearFlag(TIM2,TIM_FLAG_Update);

//禁止ARR预装载缓冲器

TIM_ARRPreloadConfig(TIM2,DISABLE);

//开启TIM2的中断

TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);}

voidNVIC_cfg(){

NVIC_InitTypeDefNVIC_InitStructure;

//选择中断分组1

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

//选择TIM2的中断通道

NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQChannel;

//抢占式中断优先级设置为0

NVIC_InitStructure。NVIC_IRQChannelPreemptionPriority=0;

//响应式中断优先级设置为0

NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;

//使能中断

NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;

NVIC_Init(&NVIC_InitStructure);}

voidGPIO_cfg(){

GPIO_InitTypeDefGPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;

//选择引脚5

GPIO_InitStructure。GPIO_Speed=GPIO_Speed_50MHz;//输出频率最大50MHz

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//带上拉电阻输出

GPIO_Init(GPIOB,&GPIO_InitStructure);}在stm32f10x_it。c中,我们找到函数TIM2_IRQHandler(),并向其中添加代码voidTIM2_IRQHandler(void){

u8ReadValue;

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

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

//清除TIM2的中断待处理位

TIM_ClearITPendingBit(TIM2,TIM_FLAG_Update);

//将PB。5管脚输出数值写入ReadValue

ReadValue=GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_5);

if(ReadValue==0)

GPIO_SetBits(GPIOB,GPIO_Pin_5);

}

else

GPIO_ResetBits(GPIOB,GPIO_Pin_5);

}

}STM32学习笔记(5):通用定时器PWM输出1.

TIMER输出PWM基本概念

脉冲宽度调制(PWM),是英文“PulseWidthModulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽度的控制。一般用来控制步进电机的速度等等.STM32的定时器除了TIM6和TIM7之外,其他的定时器都可以用来产生PWM输出,其中高级定时器TIM1和TIM8可以同时产生7路的PWM输出,而通用定时器也能同时产生4路的PWM输出。

1.1

PWM输出模式STM32的PWM输出有两种模式,模式1和模式2,由TIMx_CCMRx寄存器中的OCxM位确定的(“110"为模式1,“111”为模式2)。模式1和模式2的区别如下:110:PWM模式1-在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为有效电平,否则为无效电平;在向下计数时,一旦TIMx_CNT〉TIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电平(OC1REF=1)。111:PWM模式2—在向上计数时,一旦TIMx_CNT〈TIMx_CCR1时通道1为无效电平,否则为有效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为有效电平,否则为无效电平。由此看来,模式1和模式2正好互补,互为相反,所以在运用起来差别也并不太大。而从计数模式上来看,PWM也和TIMx在作定时器时一样,也有向上计数模式、向下计数模式和中心对齐模式,关于3种模式的具体资料,可以查看《STM32参考手册》的“14.3.9PWM模式”一节,在此就不详细赘述了。

1.2

PWM输出管脚PWM的输出管脚是确定好的,具体的引脚功能可以查看《STM32参考手册》的“8.3.7定时器复用功能重映射”一节。在此需要强调的是,不同的TIMx有分配不同的引脚,但是考虑到管脚复用功能,STM32提出了一个重映像的概念,就是说通过设置某一些相关的寄存器,来使得在其他非原始指定的管脚上也能输出PWM。但是这些重映像的管脚也是由参考手册给出的.比如说TIM3的第2个通道,在没有重映像的时候,指定的管脚是PA.7,如果设置部分重映像之后,TIM3_CH2的输出就被映射到PB.5上了,如果设置了完全重映像的话,TIM3_CH2的输出就被映射到PC。7上了。

1.3

PWM输出信号PWM输出的是一个方波信号,信号的频率是由TIMx的时钟频率和TIMx_ARR预分频器所决定的,具体设置方法在前面一个学习笔记中有详细的交代。而输出信号的占空比则是由TIMx_CRRx寄存器确定的。其公式为“占空比=(TIMx_CRRx/TIMx_ARR)*100%”,因此,可以通过向CRR中填入适当的数来输出自己所需的频率和占空比的方波信号。

2。

TIMER输出PWM实现步骤1。

设置RCC时钟;2。

设置GPIO时钟;3.

设置TIMx定时器的相关寄存器;4.

设置TIMx定时器的PWM相关寄存器.

第1步设置RCC时钟已经在前文中给出了详细的代码,在此就不再多说了。需要注意的是通用定时器TIMx是由APB1提供时钟,而GPIO则是由APB2提供时钟。注意,如果需要对PWM的输出进行重映像的话,还需要开启引脚复用时钟AFIO.第2步设置GPIO时钟时,GPIO模式应该设置为复用推挽输出GPIO_Mode_AF_PP,如果需要引脚重映像的话,则需要用GPIO_PinRemapConfig()函数进行设置.第3步设置TIMx定时器的相关寄存器时,和前一篇学习笔记一样,设置好相关的TIMx的时钟和技术模式等等。具体设置参看“TIMER基本定时功能”的学习笔记。第4步设置PWM相关寄存器,首先要设置PWM模式(默认情况下PWM是冻结的),然后设置占空比(根据前面所述公式进行计算),再设置输出比较极性:当设置为High时,输出信号不反相,当设置为Low时,输出信号反相之后再输出。最重要是是要使能TIMx的输出状态和使能TIMx的PWM输出使能。相关设置完成之后,就可以通过TIM_Cmd()来打开TIMx定时器,从而得到PWM输出了。

3。

TIMER输出PWM源代码由于我现在手上的奋斗开发板是将PB。5接到LED上,因此需要使用TIM3的CH2通道,并且要进行引脚重映像.打开TIM3之后,PWM输出,使得LED点亮,通过改变PWM_cfg()中的占空比可以调节LED的亮度。

#include"stm32f10x_lib。h"

voidRCC_cfg();voidGPIO_cfg();voidTIMER_cfg();voidPWM_cfg();//占空比,取值范围为0—100intdutyfactor=50;

intmain(){ﻩintTemp; RCC_cfg();ﻩGPIO_cfg(); TIMER_cfg(); PWM_cfg();

ﻩ//使能TIM3计时器,开始输出PWMﻩTIM_Cmd(TIM3,ENABLE);

ﻩwhile(1);}

voidRCC_cfg(){ﻩ//定义错误状态变量ﻩErrorStatusHSEStartUpStatus; //将RCC寄存器重新设置为默认值 RCC_DeInit();

ﻩ//打开外部高速时钟晶振 RCC_HSEConfig(RCC_HSE_ON);

ﻩ//等待外部高速时钟晶振工作 HSEStartUpStatus=RCC_WaitForHSEStartUp(); if(HSEStartUpStatus==SUCCESS)ﻩ{ﻩﻩ//设置AHB时钟(HCLK)为系统时钟 ﻩRCC_HCLKConfig(RCC_SYSCLK_Div1);

ﻩ //设置高速AHB时钟(APB2)为HCLK时钟 RCC_PCLK2Config(RCC_HCLK_Div1);

ﻩﻩ//设置低速AHB时钟(APB1)为HCLK的2分频 RCC_PCLK1Config(RCC_HCLK_Div2);ﻩ ﻩ//设置FLASH代码延时ﻩ FLASH_SetLatency(FLASH_Latency_2);

ﻩ //使能预取指缓存 ﻩFLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

ﻩ//设置PLL时钟,为HSE的9倍频8MHz*9=72MHz ﻩRCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);

//使能PLLﻩ RCC_PLLCmd(ENABLE);

ﻩﻩ//等待PLL准备就绪ﻩ while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);

ﻩ //设置PLL为系统时钟源ﻩ RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

//判断PLL是否是系统时钟 ﻩwhile(RCC_GetSYSCLKSource()!=0x08);ﻩ}

//开启TIM3的时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //开启GPIOB的时钟和复用功能ﻩRCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);

voidGPIO_cfg(){ﻩGPIO_InitTypeDefGPIO_InitStructure;

//部分映射,将TIM3_CH2映射到PB5// GPIO_PinRemapConfig(GPIO_FullRemap_TIM3,ENABLE);ﻩGPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);

ﻩ//选择引脚5ﻩGPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;ﻩ//输出频率最大50MHz ﻩ ﻩﻩ ﻩGPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //复用推挽输出 ﻩ ﻩﻩ ﻩGPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;ﻩ

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论