新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > STM32 學習筆記_TIME定時器詳解1

        STM32 學習筆記_TIME定時器詳解1

        作者: 時間:2016-11-26 來源:網絡 收藏


        基本的基時單元就是上面提及的這幾個,下面看看3.0庫是如何實習的基本使用。

        TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;


        TIM_DeInit(TIM2); //重新將Timer設置為缺省值

        TIM_InternalClockConfig(TIM2); //采用內部時鐘給TIM2提供時鐘源
        TIM_TimeBaseStructure.TIM_Prescaler = 36000 - 1; //預分頻系數為36000-1,這樣計數器時鐘為72MHz/36000 = 2kHz
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //設置時鐘分割
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //設置計數器模式為向上計數模式
        TIM_TimeBaseStructure.TIM_Period = 2000 - 1; //設置計數溢出大小,每計2000個數就產生一個更新事件
        TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure); //將配置應用到TIM2中
        TIM_ClearFlag(TIM2, TIM_FLAG_Update); //清除溢出中斷標志

        TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); //開啟TIM2的中斷
        以上是一個最基本的定時器配置的代碼,載自網上被轉載無數次的地方……
        中斷函數自己按照需求寫,這里不多說。
        在庫中的初始化函數和初始化數據類型有3類,TIM_TimeBaseInitTypeDef、TIM_OCInitTypeDef、TIM_ICInitTypeDef
        與基時參數相關的數據類型是TIM_TimeBaseInitTypeDef

        typedef struct
        {
        uint16_t TIM_Prescaler;

        uint16_t TIM_CounterMode;

        uint16_t TIM_Period;

        uint16_t TIM_ClockDivision;

        uint8_t TIM_RepetitionCounter;
        } TIM_TimeBaseInitTypeDef;
        以上是從庫stm32f10x_tim.h中截取的代碼,整體的數據結構可以中這段注釋中得知,不懂E文的要么翻字典要么翻庫函數中文翻譯
        版本(當然這個是2.0的庫,有部分會和3.0后的版本很不相同),這部分的數據類型還是很一樣的,不多說。
        接著就是TIM_TimeBaseInit()這個函數了,在stm32f10x_tim.c的224行中

        void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct)
        {
        uint16_t tmpcr1 = 0;


        assert_param(IS_TIM_ALL_PERIPH(TIMx));
        assert_param(IS_TIM_COUNTER_MODE(TIM_TimeBaseInitStruct->TIM_CounterMode));
        assert_param(IS_TIM_CKD_DIV(TIM_TimeBaseInitStruct->TIM_ClockDivision));

        tmpcr1 = TIMx->CR1;

        if((TIMx == TIM1) || (TIMx == TIM8)|| (TIMx == TIM2) || (TIMx == TIM3)||
        (TIMx == TIM4) || (TIMx == TIM5))
        {

        tmpcr1 &= (uint16_t)(~((uint16_t)(TIM_CR1_DIR | TIM_CR1_CMS)));
        tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_CounterMode;
        }

        if((TIMx != TIM6) && (TIMx != TIM7))
        {

        tmpcr1 &= (uint16_t)(~((uint16_t)TIM_CR1_CKD));
        tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_ClockDivision;
        }

        TIMx->CR1 = tmpcr1;


        TIMx->ARR = TIM_TimeBaseInitStruct->TIM_Period ;


        TIMx->PSC = TIM_TimeBaseInitStruct->TIM_Prescaler;

        if ((TIMx == TIM1) || (TIMx == TIM8)|| (TIMx == TIM15)|| (TIMx == TIM16) || (TIMx == TIM17))
        {

        TIMx->RCR = TIM_TimeBaseInitStruct->TIM_RepetitionCounter;
        }


        TIMx->EGR = TIM_PSCReloadMode_Immediate;
        }
        可以看3.0后的函數里把所有的TIMx都加入一個函數里面做判斷了,不需要和2.0的區分TIM1和TIM 兩類函數,比較其基本操作都一樣無非就是多了一個兩個寄存器而已。
        程序中可以看到這一段:

        if((TIMx == TIM1) || (TIMx == TIM8)|| (TIMx == TIM2) || (TIMx == TIM3)||
        (TIMx == TIM4) || (TIMx == TIM5))
        {
        ?
        tmpcr1 &= (uint16_t)(~((uint16_t)(TIM_CR1_DIR | TIM_CR1_CMS)));
        tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_CounterMode;
        }
        if((TIMx != TIM6) && (TIMx != TIM7))
        {

        tmpcr1 &= (uint16_t)(~((uint16_t)TIM_CR1_CKD));
        tmpcr1 |= (uint32_t)TIM_TimeBaseInitStruct->TIM_ClockDivision;
        }
        TIMx->CR1 = tmpcr1;
        高級定時器和通用定時器擁有向上計數、向下技術、向上/向下模式,三種,而基本計時器只有向上計數一種,因此TIM6和TIM7木有的設置計數模式,tmpcr1首先裝入了控制寄存器CR1d 值,然后把其中DIR(位4)和CMS(位6:5)清除,然后或運算上載入數據結構中的值,這里代碼再跳轉到stm32f10x_tim.h中第362行
        #define TIM_CounterMode_Up ((uint16_t)0x0000)
        #define TIM_CounterMode_Down ((uint16_t)0x0010)
        #define TIM_CounterMode_CenterAligned1 ((uint16_t)0x0020)
        #define TIM_CounterMode_CenterAligned2 ((uint16_t)0x0040)
        #define TIM_CounterMode_CenterAligned3 ((uint16_t)0x0060) 定義的是TIM_CounterMode的幾種情況,即控制計數器向上
        技術或向下計數,或是向上向下交替計數,當設置的是交替計數的情況DIR位為只讀。
        TIM_ClockDivision為時鐘分配因子,其中有 0、2x、4x ,在AHB低時鐘時為提高定時精度而實用的倍頻器,位于CR1寄存器中的位9:8。這段程序便配置好了CR1寄存器,然后再看下面的程序。載入了PSC寄存器和ARR寄存器值,如果是高級定時器還有RCR寄存器值,在這一步便基本配置得差不多了,但還是發現函數最后還有一句 TIMx->EGR = TIM_PSCReloadMode_Immediate; 這里在事件寄存器中做了一次軟件的事件更新觸發使得其UG位置1。
        #define TIM_PSCReloadMode_Immediate ((uint16_t)0x0001)

        上一頁 1 2 下一頁

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 眉山市| 类乌齐县| 思茅市| 安康市| 内黄县| 祥云县| 梨树县| 松滋市| 彰化县| 台中县| 高唐县| 神农架林区| 武山县| 松阳县| 阿尔山市| 五华县| 嘉善县| 鄂托克前旗| 上饶县| 昌江| 盐亭县| 宜阳县| 荃湾区| 四会市| 阿克苏市| 万山特区| 绥宁县| 车险| 南京市| 潼南县| 建昌县| 邵阳县| 宣威市| 观塘区| 三门峡市| 宜君县| 屯门区| 称多县| 宣威市| 城口县| 曲阜市|