历史上的今天
返回首页

历史上的今天

今天是:2024年11月11日(星期一)

正在发生

2020年11月11日 | STM32通用定时器---基本定时学习

2020-11-11 来源:eefocus

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.普通定时器TIM2-TIM5

2.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开始重新计数。

1..自动装载寄存器部分实际上包含两个寄存器:
自动装载寄存器缓冲寄存器 和 自动装载寄存器影子寄存器
其中自动装载寄存器缓冲寄存器可以有ARPE位控制是否起作用:
ARPE = 0 写"自动装载寄存器"时,数据直接写入到"自动装载寄存器缓冲寄存器"的同时,立即更新到"自动装载寄存器影子寄存器"
ARPE = 1 写"自动装载寄存器"时,数据直接写入到"自动装载寄存器缓冲寄存器"的同时,只有更新事件发生的时候,才更新到"自动装载寄存器影子寄存器"
2.预分频器控制寄存器也分为两部分:
预分频器缓冲寄存器 和 预分频器影子寄存器
当更新事件发生的时候,"预分频器缓冲寄存器"的内容更新到"预分频器影子寄存器中"

3.UDIS位作用:
UDIS = 1 禁止更新事件发生,但是计数器上下益处使,计数器和预分频计数器归0不受影响
UDIS = 0 允许更新事件发生
4.URS位作用:
URS = 1 只有计数器上下溢出才产生更新事件,从而产生中断和DMA请求
URS = 0 计数器上下溢出,软件设置UG位以及从模式控制器产生的更新 都会产生更新事件,从而产生中断和DMA请求

编程步骤
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.     程序源代码

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

 

#include "stm32f10x_lib.h"

 

void RCC_cfg();

void TIMER_cfg();

void NVIC_cfg();

void GPIO_cfg();

 

int main()

{

       RCC_cfg();

       NVIC_cfg();

       GPIO_cfg();

       TIMER_cfg();

 

       //开启定时器2

       TIM_Cmd(TIM2,ENABLE);

 

       while(1);

}

 

void RCC_cfg()

{

      

       //定义错误状态变量

       ErrorStatus HSEStartUpStatus;

      

       //将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);

 

}

 

void TIMER_cfg()

{

       TIM_TimeBaseInitTypeDef TIM_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);

}

 

void NVIC_cfg()

{

       NVIC_InitTypeDef NVIC_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;

推荐阅读

史海拾趣

骅讯(Cmedia)公司的发展小趣事

为了进一步提升品牌影响力和市场竞争力,骅讯积极寻求与知名品牌的合作。通过与音频市场上的主要品牌建立合作关系,骅讯成功将其先进的音频技术应用于各种音频产品中,为消费者带来了更为优质的音频体验。这种合作模式不仅促进了骅讯技术的推广和应用,也为其带来了更为广阔的市场空间。

DMS Electronic Components, Inc公司的发展小趣事

DMS自创立之初,就致力于电子元器件的技术创新。公司投入大量研发资源,成功开发出一系列高性能、低成本的电子元器件,这些产品迅速在市场上获得了认可。随着技术的不断进步,DMS不断推出新产品,满足了客户日益增长的需求,逐渐在电子行业中树立了技术领先的形象。

厦门法拉(faratronic)公司的发展小趣事

随着电子技术的飞速发展,FMI公司紧跟时代步伐,不断研发新技术和新产品。在1992年,FMI成功将频率管理扩展到OEM市场,进一步拓宽了其业务范围。这一举措不仅增强了公司的市场竞争力,还为公司带来了更多的商业机会。通过为计算机外设、工业仪器、局域网/广域网等多个领域提供定制化的频率控制解决方案,FMI逐渐成为了行业内的佼佼者。

FINDER公司的发展小趣事

FMI公司成立于1971年,作为标准通信公司的受控供应商,公司自成立之初便专注于为通信市场提供快速交货和严格公差的石英晶体及晶体振荡器。在成立初期,FMI面临着市场竞争激烈和技术挑战的双重压力,但公司凭借其卓越的产品质量和快速响应客户需求的能力,逐渐在行业中站稳脚跟。通过不断的技术创新和产品优化,FMI逐渐扩大了其市场份额,为后续的快速发展奠定了坚实基础。

Amerace Electronic Components公司的发展小趣事

为了确保产品质量和客户满意度,Amerace Electronic Components公司建立了严格的质量管理体系。公司引进了先进的生产设备和技术,并对生产过程进行严格的监控和管理。同时,Amerace还注重员工培训和技能提升,确保员工具备高度的专业素养和责任意识。这些措施使得Amerace的产品质量得到了有效保障,赢得了客户的信任和支持。

Bud Industries公司的发展小趣事

为了确保产品质量和客户满意度,Amerace Electronic Components公司建立了严格的质量管理体系。公司引进了先进的生产设备和技术,并对生产过程进行严格的监控和管理。同时,Amerace还注重员工培训和技能提升,确保员工具备高度的专业素养和责任意识。这些措施使得Amerace的产品质量得到了有效保障,赢得了客户的信任和支持。

问答坊 | AI 解惑

DS1302的问题

我在做一个基于单片机的电子万年历设计,其中用到了DS1302,因为之前没学过,所以不太懂,老师给了一个阳历程序流程图,看不太懂,希望高手可以帮我解释一下这个流程图,谢谢大家!…

查看全部问答>

可察言观色的车载机器人

好像很早前就有个一个概念,现在用在了车载上。 AIDA将具备察言观色的能力,能够根据面部表情以及其它线索读懂驾驶者的心情 如果驾驶者心情不好,它甚至还会表现出很同情的样子。 AIDA能够根据路况报道为驾驶者寻找最理想的回家路线 ...…

查看全部问答>

移植网卡驱动 读DM9000 ID的问题 有做过的进来帮忙看看

读出的ID总不对       平台2440  DM9000  接片选4 #define BSP_BASE_REG_PA_DM9000_IOBASE           0x20000300 DNW输出如下:      ...…

查看全部问答>

巴山工作室,为您解决技术难题和提供技术服务.

   巴山工作室有非常强大软硬件技术力量,能为您或您的企业解决一些复杂技术难题,    同时也您企业减少一些不必要的人力成本.        巴山工作室有非常强大软硬件技术力量,能为您或您的企业解决一些复 ...…

查看全部问答>

程序启动时的图片加载问题

我现在是在EVC下做一个简单的对话框程序,程序是在2440XP开发板上运行,系统是WinCE5.0 这个程序就是一个基于对话框的程序,首先我给对话框设置一张背景图片,然后还在对话框上加了一些CBitmapButton和CStatic这些控件我都把它们的背景设置成一些 ...…

查看全部问答>

一个开发板的样本驱动程序 用下面的编译参数直接编译,出现以下错误

[root@localhost turner]# arm-linux-gcc -D__KERNEL__ -I/opt/FriendlyARM/SBC2410/kernel/include -Wall -Wstrict-prototypes -Wno-trigraphs -Os -mapcs -fno-strict-aliasing -fno-common -fno-common -pipe -mapcs-32 -march=armv4 -mtu ...…

查看全部问答>

侃侃我的成果

本人长期从事单片机开发应用,积累了一定的经验。本人将毕生研究心得集成了文字,放在我的博客里,希望大家光临指导,并给点意见。我的博客地址;http://blog.mcuol.com/user/Article/500.html…

查看全部问答>

请教香版:关于USBCustom_HID中显示ST的问题

香版:您好! 我在使用Custom_Hid的时候,发现其需要安装驱动,但其启动好像是PC系统自带,这倒没有什么问题。 问题是,在第一次插入PC的时候,会提示ST等信息。而作为我们设计的产品,希望能提示公司自己的ID或者什么都不显示。不知道这样 ...…

查看全部问答>

【求助】远程通信问题

    各位大哥大姐:    小弟最近在设计方案,涉及到两块板子的通信问题。 要求两块板的电源,地完全隔离;能够进行数据通信,通信距离在10米至30米。 小弟我苦思几天,通信不过就如下几种: 232,485,CAN,红外。但好像这 ...…

查看全部问答>

【设计工具】Quartus中FFT模块中文说明

Altera FFT兆核函数2.0.0版简介一.FFT兆核函数简介Altera FFT兆核函数2.0.0版是一个高性能、参数化快速傅立叶变换(FFT)处理器,对Altera Stratix II、Stratix GX、Stratix以及Cyclone器件系列已经进行了设计优化。FFT兆核函数可以完成高性能复数FFT ...…

查看全部问答>