新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > stm32之定時器徹底研究

        stm32之定時器徹底研究

        作者: 時間:2016-11-26 來源:網絡 收藏
        這里介紹兩種方式使用stm32的定時器:直接操作寄存器和使用st的官方的庫文件。
        相比較而言,直接操作定時器比較簡潔,對著寄存器看十分明了。而使用庫文件有一點暈頭轉向。
        (個人觀點)
        程序如下:(以下程序在DX32的例程修改而來,使用的是比較古老的3.0固件庫)
        1、timer.c文件
        #include "STM32Libstm32f10x.h"
        void TIM2_Configuration(void)
        {
        TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
        TIM_OCInitTypeDef TIM_OCInitStructure;
        u16 CCR1_Val = 4000;
        u16 CCR2_Val = 2000;
        u16 CCR3_Val = 1000;
        u16 CCR4_Val = 500;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

        TIM_TimeBaseStructure.TIM_Period = 10000; //計滿值
        TIM_TimeBaseStructure.TIM_Prescaler = 7200-1; //預分頻,此值+1為分頻的除數
        TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; //
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上計數

        TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);


        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Inactive; //輸出比較非主動模式
        TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //極性為正

        TIM_OC1Init(TIM2, &TIM_OCInitStructure);
        TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Disable); //禁止OC1重裝載,其實可以省掉這句,因為默認是4路都不重裝的.


        TIM_OCInitStructure.TIM_Pulse = CCR2_Val;

        TIM_OC2Init(TIM2, &TIM_OCInitStructure);
        TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Disable);


        TIM_OCInitStructure.TIM_Pulse = CCR3_Val;

        TIM_OC3Init(TIM2, &TIM_OCInitStructure);
        TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Disable);


        TIM_OCInitStructure.TIM_Pulse = CCR4_Val;

        TIM_OC4Init(TIM2, &TIM_OCInitStructure);
        TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Disable);


        TIM_ARRPreloadConfig(TIM2, ENABLE);

        TIM_ClearITPendingBit(TIM2, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4|TIM_IT_Update);

        TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4|TIM_IT_Update, ENABLE);



        TIM_Cmd(TIM2, ENABLE);
        }
        void TIM3_Configuration(u16 p,u16 psc)
        {
        RCC->APB1ENR|=1<<1;//TIM3時鐘使能
        //自動裝載寄存器
        TIM3->ARR=p; //設定定時器自動重裝值
        //PSC預分頻寄存器
        TIM3->PSC=psc; //設定定時器的分頻系數
        TIM3->DIER|=1<<0; //允許更新中斷
        TIM3->DIER|=1<<6; //允許觸發中斷
        TIM3->CR1|=0X01; //使能定時器3(這里面包括計數方向為向上計數)
        }
        #if 0
        void TIM4_Configuration(void)
        {
        TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
        TIM_OCInitTypeDef TIM_OCInitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);


        TIM_TimeBaseStructure.TIM_Period = 10000; //計滿值
        TIM_TimeBaseStructure.TIM_Prescaler = 7200-1; //預分頻,此值+1為分頻的除數
        TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; //
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上計數
        TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);



        TIM_ARRPreloadConfig(TIM4, ENABLE);

        TIM_ClearITPendingBit(TIM4, TIM_IT_Update);

        TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);



        TIM_Cmd(TIM4, ENABLE);
        }
        #else
        void TIM_Configuration(u16 p,u16 psc)
        {
        RCC->APB1ENR|=1<<2;//TIM4時鐘使能
        //自動裝載寄存器
        TIM4->ARR=p; //設定定時器自動重裝值
        //PSC預分頻寄存器
        TIM4->PSC=psc; //設定定時器的分頻系數
        TIM4->DIER|=1<<0; //允許更新中斷
        TIM4->DIER|=1<<6; //允許觸發中斷
        TIM4->CR1|=0X01; //使能定時器3(這里面包括計數方向為向上計數)
        }
        #endif
        上程序中,定時器2被配置成多路捕獲模式,定時器3是直接操作寄存器進行配置的。
        定時器4用了兩種配置方式,使用固件庫和直接操作寄存器。可以切換。效果一樣。
        需要注意的是,stm32103RBT6的通用定時器只有2、3、4.(沒有5)
        2、stm32f10x_it.c文件
        unsigned int cnt=0;
        unsigned int flag=0;
        void TIM2_IRQHandler(void)
        {
        if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)
        {

        TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);

        //可添加功能塊......

        }
        else if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET)
        {
        TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);

        //可添加功能塊......
        }
        else if (TIM_GetITStatus(TIM2, TIM_IT_CC3) != RESET)
        {
        TIM_ClearITPendingBit(TIM2, TIM_IT_CC3);

        //可添加功能塊......
        }
        else if (TIM_GetITStatus(TIM2, TIM_IT_CC4) != RESET)
        {
        TIM_ClearITPendingBit(TIM2, TIM_IT_CC4);

        //可添加功能塊......
        }
        if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
        {
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
        //flag=1;//計時滿標志位置位
        //cnt++;//每TIM_Period計時滿變量加一
        }
        }

        void TIM3_IRQHandler(void)
        {
        if(TIM3->SR&0X0001)
        {
        cnt++;
        flag=1;
        }
        TIM3->SR&=~(1<<0);
        }

        void TIM4_IRQHandler(void)
        {
        if(TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
        {
        TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
        cnt++;
        flag=1;
        }
        }
        可以看到,定時器2有多個處理的事件,四個通道的計數溢出和定時器的總溢出。具體事件根據應用來配置。
        另外,以上代碼只是對三個通用定時器進行測試,具體應用根據情況來定。
        3、NVIC.c文件
        #include "STM32Libstm32f10x.h"

        //設置所有的中斷允許
        void NVIC_Configuration(void)
        {
        NVIC_InitTypeDef NVIC_InitStructure;

        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
        NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);

        #if 1

        上一頁 1 2 下一頁

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 略阳县| 乌拉特后旗| 诸城市| 武安市| 双江| 平阴县| 皮山县| 沽源县| 会宁县| 石家庄市| 华蓥市| 宜川县| 乌兰察布市| 巴南区| 上饶市| 泸州市| 韶山市| 三明市| 石柱| 沁源县| 类乌齐县| 米泉市| 巨野县| 黄骅市| 大邑县| 拜泉县| 和静县| 六盘水市| 赣州市| 永昌县| 招远市| 富源县| 灵璧县| 仁怀市| 历史| 盱眙县| 新昌县| 樟树市| 重庆市| 类乌齐县| 塔城市|