STM32定時(shí)器編程

一.實(shí)驗(yàn)?zāi)康?/p>

  1. 了解STM32中定時(shí)器的原理。

  2. 掌握在STM32如何實(shí)現(xiàn)精確定時(shí)。

二.實(shí)驗(yàn)要求

  1. 了解STM32中定時(shí)器的原理。

  2. 掌握在STM32如何實(shí)現(xiàn)精確定時(shí)。

  3. 學(xué)習(xí)STM32通用定時(shí)器的編程方式,實(shí)現(xiàn)LED每秒閃爍一次。

三.實(shí)驗(yàn)軟硬件

  1. PC機(jī)一臺(tái)

  2. WINDOWS操作系統(tǒng)

  3. ARM集成開發(fā)環(huán)境

  4. WSN實(shí)驗(yàn)箱

四.實(shí)驗(yàn)步驟

1.定時(shí)器簡介

STM32總共有8個(gè)定時(shí)器,TIM1和TIM8是16位的高級(jí)定時(shí)器,TIM2、TIM3、TIM4、TIM5是通用定時(shí)器。本實(shí)驗(yàn)中使用通用定時(shí)器TIM2,來實(shí)現(xiàn)精確定時(shí)。

通用定時(shí)器是一個(gè)通過可編程預(yù)分頻器驅(qū)動(dòng)的16 位自動(dòng)裝載計(jì)數(shù)器構(gòu)成。這里為了體現(xiàn)其精確定時(shí),用LED燈進(jìn)行觀察實(shí)驗(yàn)現(xiàn)象。如果有條件的實(shí)驗(yàn)室,可以配置示波器來觀察信號(hào)情況。(特別是在做脈沖實(shí)驗(yàn)進(jìn)行波形輸出時(shí))。使用定時(shí)器預(yù)分頻器和RCC 時(shí)鐘控制器預(yù)分頻器,脈沖長度和波形周期可以在幾個(gè)微秒到幾個(gè)毫秒間調(diào)整。

2. 定時(shí)器時(shí)鐘配置

如圖4.20所示,TIMx的有八個(gè),其中TIM1和TIM8掛在APB2總線上,而TIM2-TIM7則掛在APB1總線上。其中TIM1&TIM8稱為高級(jí)控制定時(shí)器(advanced control timer).他們所在的APB2總線也比APB1總線要好。APB2可以工作在72MHz下,而APB1最大是36MHz。

TIM時(shí)鐘配置

圖4.17 TIM時(shí)鐘配置

由圖4.20可知,當(dāng)APB1 的預(yù)分頻系數(shù)為1 時(shí),這個(gè)倍頻器不起作用,定時(shí)器的時(shí)鐘頻率等于APB1 的頻率;當(dāng)APB1的預(yù)分頻系數(shù)為其它數(shù)值(即預(yù)分頻系數(shù)為2、4、8 或16)時(shí),這個(gè)倍頻器起作用,定時(shí)器的時(shí)鐘頻率等于APB1 的頻率兩倍。因?yàn)锳PB1最大為36MHz,而AHB預(yù)分頻輸出的頻率為72MHz,所以APB1預(yù)分頻器進(jìn)行了2分頻,所以定時(shí)器的時(shí)鐘頻率為2倍的APB1的頻率,即72MHz。

3.通用定時(shí)器初始化配置

通用定時(shí)器初始化配置流程為:

3.1 首先進(jìn)行配置一個(gè)TIM_TimeBaseInitTypeDef 的結(jié)構(gòu)體。

例如:TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

3.2 將定時(shí)器TIMx設(shè)置為默認(rèn)值的定時(shí)器。例如:TIM_DeInit(TIM2);

3.3根據(jù)TIM_TimeBaseInitStruct中指定的參數(shù)初始化TIMx的時(shí)間基數(shù)單位 。進(jìn)行如下配置。

a.配置定時(shí)器的周期加載值(TIM_Period)。它設(shè)置了在下一個(gè)更新事件裝入活動(dòng)的自動(dòng)重裝載寄存器周期的值。它的取值必須在0x0000和0xFFFF之間。例如:

TIM_TimeBaseStructure.TIM_Period=1000;

b.設(shè)置定時(shí)器時(shí)鐘預(yù)分頻值(TIM_Prescaler)。設(shè)置了用來作為TIMx時(shí)鐘頻率除數(shù)的預(yù)分頻值。它的取值必須在0x0000和0xFFFF之間。例如:

TIM_TimeBaseStructure.TIM_Prescaler= 71;

c.設(shè)置時(shí)鐘分割。實(shí)驗(yàn)中設(shè)置為如下,即來自APB1的時(shí)鐘不分頻。

TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;

d.選擇定時(shí)器的計(jì)數(shù)方式。這里選擇向上計(jì)數(shù)方式。其從0開始計(jì)數(shù),當(dāng)向上計(jì)數(shù)值增加到配置的周期加載值時(shí),會(huì)觸發(fā)定時(shí)器中斷。然后計(jì)數(shù)值自動(dòng)清零。

TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;

e.初始化定時(shí)器。調(diào)用定時(shí)器API函數(shù)為:TIM_TimeBaseInit();

f.實(shí)驗(yàn)中采用中斷的方式進(jìn)行精確定時(shí)。所以在初始化定時(shí)器時(shí)要清除以前的中斷標(biāo)志。調(diào)用定時(shí)器的中斷標(biāo)志位函數(shù)為:TIM_ClearFlag(TIMx, TIM_FLAG_Update);

g.使能定時(shí)器中斷。調(diào)用定時(shí)器中斷API函數(shù)為:

TIM_ITConfig(TIMx,TIM_IT_Update,ENABLE);

h.使能定時(shí)器TIM_Cmd(TIMx, ENABLE);

4.NVIC初始化配置

4.1.設(shè)置中斷名稱。本例為TIM2_IRQn。

4.2.中斷優(yōu)先級(jí)的設(shè)置。

4.3. IRQ通道使能。

4.4. 根據(jù)NVIC_InitStruct中指定的參數(shù)初始化外設(shè)NVIC寄存器TIM2.

以上為設(shè)置流程。根據(jù)以上設(shè)置,例如調(diào)用相關(guān)的API函數(shù)如下NVIC中斷,具體請(qǐng)參考STM32數(shù)據(jù)手冊(cè)。

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.實(shí)現(xiàn)LED(綠燈和紅燈)以1s、2s、5s的頻率閃爍。其中配置GPIO、TIM的時(shí)鐘;GPIO設(shè)置;定時(shí)器中斷需要配置NVIC;定時(shí)器的初始化;以及定時(shí)器中斷處理。

注:發(fā)生中斷時(shí)間=(TIM_Prescaler+1)* (TIM_Period+1)/FLK(此處FLK為72MHz)

五.實(shí)驗(yàn)報(bào)告具體要求

實(shí)驗(yàn)報(bào)告應(yīng)包括以下幾個(gè)部分:

1.實(shí)驗(yàn)?zāi)康摹?/p>

2.問題描述。

3.實(shí)驗(yàn)詳細(xì)步驟(包含源碼)。

4.實(shí)驗(yàn)過程中遇到的問題,及解決辦法。

5.實(shí)驗(yàn)心得。

實(shí)驗(yàn)代碼

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


/* 
 * 函數(shù)名:main
 * 描述    :主函數(shù)
 * 輸入    :無
 * 輸出    :無       
 */
int main(void)
{
    RCC_Configuration();
        GPIO_Configuration();
            
        NVIC_Configuration();
        TIM_Configuration();
        
    // 等待中斷觸發(fā)   
    while(1);
}





void RCC_Configuration(void)
{
    ErrorStatus HSEStartUpStatus;
    //編程習(xí)慣,用于異常處理

    SystemInit();   //初始化微控制系統(tǒng)
    RCC_DeInit();   //將RCC時(shí)鐘控制器設(shè)為默認(rèn)狀態(tài)
    
    
    //使能外部晶振
    RCC_HSEConfig(RCC_HSE_ON);
    
    //等待外部晶振穩(wěn)定
    /*這一步是必須的,不穩(wěn)定的時(shí)鐘無法為
    外設(shè)如GPIO、UART、ADC等提供服務(wù)*/
    HSEStartUpStatus = RCC_WaitForHSEStartUp();
    
    
    //如果外部晶振啟動(dòng)成功,則進(jìn)行下一步操作
    if(HSEStartUpStatus==SUCCESS)
    {
        //設(shè)置HCLK(AHB時(shí)鐘)=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時(shí)序控制
        //推薦值:SYSCLK = 0~24MHz   Latency=0
        //        SYSCLK = 24~48MHz  Latency=1
        //        SYSCLK = 48~72MHz  Latency=2
        //開啟FLASH預(yù)取指令功能
        FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
        
        FLASH_SetLatency(FLASH_Latency_2);

        //PLL設(shè)置 SYSCLK/1 * 9 = 8/1*6 = 9MHz
        RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
        
        //啟動(dòng)PLL
        RCC_PLLCmd(ENABLE);
        
        //等待PLL穩(wěn)定
        while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){};
        
        //系統(tǒng)時(shí)鐘SYSCLK來自PLL輸出
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
        
        //切換時(shí)鐘后等待系統(tǒng)時(shí)鐘穩(wěn)定
        while(RCC_GetSYSCLKSource()!=0x08){};
          
    }      
     
        //啟動(dòng)GPIO
    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB,ENABLE);
    //啟動(dòng)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); //前面指是哪個(gè)TIM,后面指TimeBaseInitStruct結(jié)構(gòu)體指針。

         

        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;   //定義TIM初始化類型結(jié)構(gòu)體變量
        
        TIM_DeInit(TIM2);

        TIM_TimeBaseStructure.TIM_Period = 9999;   //設(shè)置自動(dòng)重載計(jì)數(shù)周期值

        TIM_TimeBaseStructure.TIM_Prescaler =7199;   //設(shè)置分頻系數(shù)
        //設(shè)置用來作為TIMx時(shí)鐘頻率除數(shù)的預(yù)分頻值  10Khz的計(jì)數(shù)頻率  
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //設(shè)置時(shí)鐘分頻因子

        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //設(shè)置為向上計(jì)數(shù)方式

        TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
  
        TIM_ARRPreloadConfig(TIM2, ENABLE);                       //允許自動(dòng)重裝載寄存器(ARR)
        TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);                 //允許TIM2溢出中斷
        
        TIM_Cmd(TIM2, ENABLE);                                 //TIM2開啟時(shí)鐘
                
}


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

按照公式計(jì)算得到的單位是秒!
https://www.cnblogs.com/sankye/archive/2012/05/05/2484711.html
http://www.51hei.com/stm32/4261.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 姓名:周崇杰 學(xué)號(hào):16040120059 專業(yè):機(jī)械設(shè)計(jì)制造及其自動(dòng)化 轉(zhuǎn)載自:http://blog.csd...
    CJbaby閱讀 1,152評(píng)論 0 0
  • 首先讓我們來看一下關(guān)于控制定時(shí)器中斷的文件timer.c中的源碼: 前兩行是頭文件的聲明,這里我們不去理會(huì),我們今...
    Jane_123閱讀 11,566評(píng)論 0 5
  • STM32F1 的通用定時(shí)器是一個(gè)通過可編程預(yù)分頻器(PSC,16位,1~65535)驅(qū)動(dòng)的 16 位自動(dòng)裝載計(jì)數(shù)...
    X_xxieRiemann閱讀 1,543評(píng)論 0 4
  • 周一小組空巴學(xué)習(xí)在三樓多功能廳舉行,感謝學(xué)委的精心組織和策劃,會(huì)上家人們都積極發(fā)言,各抒己見,書中講到,以...
    徐紹剛閱讀 295評(píng)論 0 0
  • 1、人生在世,就是相互虧欠。 他欠她一段陪伴,她欠他一個(gè)抱歉。 那就不還了唄。若是兩不相欠,各自相歡,那還有什么理...
    大寫的Z小姐姐閱讀 686評(píng)論 1 2

友情鏈接更多精彩內(nèi)容