STM32定时器编程

一.实验目的

  1. 了解STM32中定时器的原理。

  2. 掌握在STM32如何实现精确定时。

二.实验要求

  1. 了解STM32中定时器的原理。

  2. 掌握在STM32如何实现精确定时。

  3. 学习STM32通用定时器的编程方式,实现LED每秒闪烁一次。

三.实验软硬件

  1. PC机一台

  2. WINDOWS操作系统

  3. ARM集成开发环境

  4. WSN实验箱

四.实验步骤

1.定时器简介

STM32总共有8个定时器,TIM1和TIM8是16位的高级定时器,TIM2、TIM3、TIM4、TIM5是通用定时器。本实验中使用通用定时器TIM2,来实现精确定时。

通用定时器是一个通过可编程预分频器驱动的16 位自动装载计数器构成。这里为了体现其精确定时,用LED灯进行观察实验现象。如果有条件的实验室,可以配置示波器来观察信号情况。(特别是在做脉冲实验进行波形输出时)。使用定时器预分频器和RCC 时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。

2. 定时器时钟配置

如图4.20所示,TIMx的有八个,其中TIM1和TIM8挂在APB2总线上,而TIM2-TIM7则挂在APB1总线上。其中TIM1&TIM8称为高级控制定时器(advanced control timer).他们所在的APB2总线也比APB1总线要好。APB2可以工作在72MHz下,而APB1最大是36MHz。

TIM时钟配置

图4.17 TIM时钟配置

由图4.20可知,当APB1 的预分频系数为1 时,这个倍频器不起作用,定时器的时钟频率等于APB1 的频率;当APB1的预分频系数为其它数值(即预分频系数为2、4、8 或16)时,这个倍频器起作用,定时器的时钟频率等于APB1 的频率两倍。因为APB1最大为36MHz,而AHB预分频输出的频率为72MHz,所以APB1预分频器进行了2分频,所以定时器的时钟频率为2倍的APB1的频率,即72MHz。

3.通用定时器初始化配置

通用定时器初始化配置流程为:

3.1 首先进行配置一个TIM_TimeBaseInitTypeDef 的结构体。

例如:TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

3.2 将定时器TIMx设置为默认值的定时器。例如:TIM_DeInit(TIM2);

3.3根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 。进行如下配置。

a.配置定时器的周期加载值(TIM_Period)。它设置了在下一个更新事件装入活动的自动重装载寄存器周期的值。它的取值必须在0x0000和0xFFFF之间。例如:

TIM_TimeBaseStructure.TIM_Period=1000;

b.设置定时器时钟预分频值(TIM_Prescaler)。设置了用来作为TIMx时钟频率除数的预分频值。它的取值必须在0x0000和0xFFFF之间。例如:

TIM_TimeBaseStructure.TIM_Prescaler= 71;

c.设置时钟分割。实验中设置为如下,即来自APB1的时钟不分频。

TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;

d.选择定时器的计数方式。这里选择向上计数方式。其从0开始计数,当向上计数值增加到配置的周期加载值时,会触发定时器中断。然后计数值自动清零。

TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;

e.初始化定时器。调用定时器API函数为:TIM_TimeBaseInit();

f.实验中采用中断的方式进行精确定时。所以在初始化定时器时要清除以前的中断标志。调用定时器的中断标志位函数为:TIM_ClearFlag(TIMx, TIM_FLAG_Update);

g.使能定时器中断。调用定时器中断API函数为:

TIM_ITConfig(TIMx,TIM_IT_Update,ENABLE);

h.使能定时器TIM_Cmd(TIMx, ENABLE);

4.NVIC初始化配置

4.1.设置中断名称。本例为TIM2_IRQn。

4.2.中断优先级的设置。

4.3. IRQ通道使能。

4.4. 根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器TIM2.

以上为设置流程。根据以上设置,例如调用相关的API函数如下NVIC中断,具体请参考STM32数据手册。

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;//开TIM2中断

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

5.实现LED(绿灯和红灯)以1s、2s、5s的频率闪烁。其中配置GPIO、TIM的时钟;GPIO设置;定时器中断需要配置NVIC;定时器的初始化;以及定时器中断处理。

注:发生中断时间=(TIM_Prescaler+1)* (TIM_Period+1)/FLK(此处FLK为72MHz)

五.实验报告具体要求

实验报告应包括以下几个部分:

1.实验目的。

2.问题描述。

3.实验详细步骤(包含源码)。

4.实验过程中遇到的问题,及解决办法。

5.实验心得。

实验代码

#include "stm32f10x.h"
#include "stm32f10x_rtc.h"
#include "stm32f10x_tim.h"
#include "misc.h"
#include "core_cm3.h"


void RCC_Configuration(void);
void GPIO_Configuration(void);
void TIM_Configuration(void);
void TIM2_IRQHandler(void);
void NVIC_Configuration(void);

#define GreenLight_On()     GPIO_SetBits(GPIOB,GPIO_Pin_8)
#define GreenLight_Off()    GPIO_ResetBits(GPIOB,GPIO_Pin_8)

#define REDLight_On()       GPIO_SetBits(GPIOB,GPIO_Pin_9)
#define REDLight_Off()      GPIO_ResetBits(GPIOB,GPIO_Pin_9)


/* 
 * 函数名:main
 * 描述    :主函数
 * 输入    :无
 * 输出    :无       
 */
int main(void)
{
    RCC_Configuration();
        GPIO_Configuration();
            
        NVIC_Configuration();
        TIM_Configuration();
        
    // 等待中断触发   
    while(1);
}





void RCC_Configuration(void)
{
    ErrorStatus HSEStartUpStatus;
    //编程习惯,用于异常处理

    SystemInit();   //初始化微控制系统
    RCC_DeInit();   //将RCC时钟控制器设为默认状态
    
    
    //使能外部晶振
    RCC_HSEConfig(RCC_HSE_ON);
    
    //等待外部晶振稳定
    /*这一步是必须的,不稳定的时钟无法为
    外设如GPIO、UART、ADC等提供服务*/
    HSEStartUpStatus = RCC_WaitForHSEStartUp();
    
    
    //如果外部晶振启动成功,则进行下一步操作
    if(HSEStartUpStatus==SUCCESS)
    {
        //设置HCLK(AHB时钟)=SYSCLK=72
        RCC_HCLKConfig(RCC_SYSCLK_Div1);

        //PCLK1(APB1) = HCLK/2=36MHZ
        RCC_PCLK1Config(RCC_HCLK_Div2);

        //PCLK2(APB2) = HCLK=72MHZ
        RCC_PCLK2Config(RCC_HCLK_Div1);
       
        //FLASH时序控制
        //推荐值:SYSCLK = 0~24MHz   Latency=0
        //        SYSCLK = 24~48MHz  Latency=1
        //        SYSCLK = 48~72MHz  Latency=2
        //开启FLASH预取指令功能
        FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
        
        FLASH_SetLatency(FLASH_Latency_2);

        //PLL设置 SYSCLK/1 * 9 = 8/1*6 = 9MHz
        RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
        
        //启动PLL
        RCC_PLLCmd(ENABLE);
        
        //等待PLL稳定
        while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){};
        
        //系统时钟SYSCLK来自PLL输出
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
        
        //切换时钟后等待系统时钟稳定
        while(RCC_GetSYSCLKSource()!=0x08){};
          
    }      
     
        //启动GPIO
    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB,ENABLE);
    //启动TIM2
    RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM2,ENABLE);
   
}


void GPIO_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

}


// TIM 配置
void TIM_Configuration(void)
{
        void TIM_TimeBaseInit(TIM_TypeDef*TIMx,
        TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct); //前面指是哪个TIM,后面指TimeBaseInitStruct结构体指针。

         

        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;   //定义TIM初始化类型结构体变量
        
        TIM_DeInit(TIM2);

        TIM_TimeBaseStructure.TIM_Period = 9999;   //设置自动重载计数周期值

        TIM_TimeBaseStructure.TIM_Prescaler =7199;   //设置分频系数
        //设置用来作为TIMx时钟频率除数的预分频值  10Khz的计数频率  
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分频因子

        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //设置为向上计数方式

        TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
  
        TIM_ARRPreloadConfig(TIM2, ENABLE);                       //允许自动重装载寄存器(ARR)
        TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);                 //允许TIM2溢出中断
        
        TIM_Cmd(TIM2, ENABLE);                                 //TIM2开启时钟
                
}


// TIM2 中断处理
void TIM2_IRQHandler(void)
{
        int i, j;
        TIM_ClearITPendingBit(TIM2, TIM_FLAG_Update);  
                //清除TIMx的中断待处理位:TIM 中断源
            REDLight_On();
        for(i = 0; i < 999; i++)
            for(j = 0; j < 999; j++);
        REDLight_Off();
}
//注意这里清除中断源,不然无法正确切换模式ON||OFF
// NVIC 配置
void NVIC_Configuration(void)
{
        NVIC_InitTypeDef NVIC_InitStructure;
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;//开TIM2中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
}

按照公式计算得到的单位是秒!
https://www.cnblogs.com/sankye/archive/2012/05/05/2484711.html
http://www.51hei.com/stm32/4261.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,271评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,725评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,252评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,634评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,549评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,985评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,471评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,128评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,257评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,233评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,235评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,940评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,528评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,623评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,858评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,245评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,790评论 2 339

推荐阅读更多精彩内容

  • 姓名:周崇杰 学号:16040120059 专业:机械设计制造及其自动化 转载自:http://blog.csd...
    CJbaby阅读 1,042评论 0 0
  • 首先让我们来看一下关于控制定时器中断的文件timer.c中的源码: 前两行是头文件的声明,这里我们不去理会,我们今...
    Jane_123阅读 11,164评论 0 5
  • STM32F1 的通用定时器是一个通过可编程预分频器(PSC,16位,1~65535)驱动的 16 位自动装载计数...
    X_xxieRiemann阅读 1,401评论 0 4
  • 周一小组空巴学习在三楼多功能厅举行,感谢学委的精心组织和策划,会上家人们都积极发言,各抒己见,书中讲到,以...
    徐绍刚阅读 263评论 0 0
  • 1、人生在世,就是相互亏欠。 他欠她一段陪伴,她欠他一个抱歉。 那就不还了呗。若是两不相欠,各自相欢,那还有什么理...
    大写的Z小姐姐阅读 602评论 1 2