新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 九九的STM32筆記(一)TIM模塊定時器向上溢出 &am

        九九的STM32筆記(一)TIM模塊定時器向上溢出 &am

        作者: 時間:2016-11-23 來源:網絡 收藏
        首先我們必須肯定ST公司的實力,也承認STM32的確是一款非常不錯的Cortex-M3核單片機,但是,他的手冊實在是讓人覺得無法理解,尤其是其中
        TIM模塊,沒有條理可言,看了兩天幾乎還是不知所云,讓人很是郁悶。同時配套的固件庫的說明也很難和手冊上的寄存器對應起來,研究起來非常費勁!功能
        強大倒是真的,但至少也應該配套一個讓人看的明白的說明吧~~


          兩天時間研究了STM32定時器的最最基礎的部分,把定時器最基礎的兩個功能實現了,余下的功能有待繼續學習。

          首先有一點需要注意:FWLib固件庫目前的最新版應該是V2.0.x,V1.0.x版本固件庫中,TIM1模塊被獨立出來,調用的函數與其他定時器不同;在V2.0系列版本中,取消了TIM1.h,所有的TIM模塊統一調用TIM.h即可。網絡上流傳的各種代碼有許多是基于v1版本的固件庫,在移植到v2版本固件庫時,需要做些修改。本文的所有程序都是基于V2.0固件庫。




          以下是定時器向上溢出示例代碼:




        C語言:TIM1模塊產生向上溢出事件

        //Step1.時鐘設置:啟動TIM1


        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);



        //Step2.中斷NVIC設置:允許中斷,設置優先級


        NVIC_InitStructure.NVIC_IRQChannel =
        TIM1_UP_IRQChannel;
        //更新事件

        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0;
        //搶占優先級0

        NVIC_InitStructure.NVIC_IRQChannelSubPriority =1;
        //響應優先級1

        NVIC_InitStructure.NVIC_IRQChannelCmd =
        ENABLE;
        //允許中斷

        NVIC_Init(&NVIC_InitStructure);
        //寫入設置



        //Step3.TIM1模塊設置


        void
        TIM_Configuration(void)

        {

        TIM_TimeBaseInitTypeDef TIM_BaseInitStructure;

        TIM_OCInitTypeDef TIM_OCInitStructure;





        //TIM1
        使用內部時鐘

        //TIM_InternalClockConfig(TIM1);




        //TIM1基本設置


        //設置預分頻器分頻系數71,即APB2=72M,
        TIM1_CLK=72/72=1MHz

        //TIM_Period(TIM1_ARR)=1000,計數器向上計數到1000后產生更新事件,計數值歸零


        //向上計數模

        //TIM_RepetitionCounter(TIM1_RCR)=0,每次向上溢出都產生更新事件


        TIM_BaseInitStructure.TIM_Period =1000;

        TIM_BaseInitStructure.TIM_Prescaler =71;

        TIM_BaseInitStructure.TIM_ClockDivision =0;

        TIM_BaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;

        TIM_BaseInitStructure.TIM_RepetitionCounter =0;

        TIM_TimeBaseInit(TIM1,
        &TIM_BaseInitStructure);



        //清中斷,以免一啟用中斷后立即產生中斷


        TIM_ClearFlag(TIM1, TIM_FLAG_Update);

        //使能TIM1中斷源


        TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);



        //TIM1總開關:開啟


        TIM_Cmd(TIM1, ENABLE);

        }



        //Step4.中斷服務子程序:


        void
        TIM1_UP_IRQHandler(void)

        {

        GPIOC->ODR ^= (1<<4);
        //閃燈

        TIM_ClearITPendingBit(TIM1, TIM_FLAG_Update);//清中斷

        }



          下面是輸出比較功能實現TIM1_CH1管腳輸出指定頻率的脈沖:




        C語言:TIM1模塊實現輸出比較,自動翻轉并觸發中斷

        //Step1.啟動TIM1,同時還要注意給相應功能管腳啟動時鐘


        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);



        //Step2.
        PA.8口設置為TIM1的OC1輸出口


        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;

        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

        GPIO_Init(GPIOA, &GPIO_InitStructure);



        //Step3.使能TIM1的輸出比較匹配中斷


        NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQChannel;

        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =1;

        NVIC_InitStructure.NVIC_IRQChannelSubPriority =1;

        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

        NVIC_Init(&NVIC_InitStructure);



        //Step4.
        TIM模塊設置


        void
        TIM_Configuration(void)

        {


        TIM_TimeBaseInitTypeDef TIM_BaseInitStructure;


        TIM_OCInitTypeDef TIM_OCInitStructure;





        //TIM1基本計數器設置



        TIM_BaseInitStructure.TIM_Period =0xffff;
        //這里必須是65535



        TIM_BaseInitStructure.TIM_Prescaler =71;
        //預分頻71,即72分頻,得1M



        TIM_BaseInitStructure.TIM_ClockDivision =0;


        TIM_BaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;


        TIM_BaseInitStructure.TIM_RepetitionCounter =0;


        TIM_TimeBaseInit(TIM1,
        &TIM_BaseInitStructure);



        //TIM1_OC1模塊設置



        TIM_OCStructInit(&
        TIM_OCInitStructure);


        TIM_OCInitStructure.TIM_OCMode =
        TIM_OCMode_Toggle;
        //管腳輸出模式:翻轉



        TIM_OCInitStructure.TIM_Pulse =2000;
        //翻轉周期:2000個脈沖



        TIM_OCInitStructure.TIM_OutputState =
        TIM_OutputState_Enable;
        //使能TIM1_CH1通道



        TIM_OCInitStructure.TIM_OCPolarity =
        TIM_OCPolarity_High;
        //輸出為正邏輯


        TIM_OC1Init(TIM1,
        &TIM_OCInitStructure);
        //寫入配置



        //清中斷


        TIM_ClearFlag(TIM1, TIM_FLAG_CC1);



        //TIM1中斷源設置,開啟相應通道的捕捉比較中斷



        TIM_ITConfig(TIM1, TIM_IT_CC1, ENABLE);



        //TIM1開啟


        TIM_Cmd(TIM1, ENABLE);

        //通道輸出使能


        TIM_CtrlPWMOutputs(TIM1, ENABLE);

        }



        Step5.中斷服務子程序


        void
        TIM1_CC_IRQHandler(void)

        {

        u16
        capture;

        if(TIM_GetITStatus(TIM1,
        TIM_IT_CC1) == SET)

        {


        TIM_ClearITPendingBit(TIM1, TIM_IT_CC1 );


        capture = TIM_GetCapture1(TIM1);


        TIM_SetCompare1(TIM1, capture +2000);


        //這里解釋下:


        //將TIM1_CCR1的值增加2000,使得下一個TIM事件也需要2000個脈沖,



        //另一種方式是清零脈沖計數器



        //TIM_SetCounter(TIM2,0x0000);


        }

        }



          關于TIM的操作,要注意的是STM32處理器因為低功耗的需要,各模塊需要分別獨立開啟時鐘,所以,一定不要忘記給用到的模塊和管腳使能時鐘,因為這個原因,浪費了我好多時間阿~~!



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 伊宁市| 合山市| 石屏县| 海林市| 新密市| 北宁市| 合川市| 新蔡县| 从江县| 永平县| 股票| 厦门市| 西平县| 广饶县| 青田县| 铅山县| 茶陵县| 灵武市| 古蔺县| 玉门市| 华蓥市| 海盐县| 乌审旗| 涿州市| 西安市| 胶州市| 宽城| 卢氏县| 安国市| 福建省| 太仓市| 江口县| 云和县| 海阳市| 乡城县| 金阳县| 洱源县| 玉树县| 溧阳市| 会同县| 东方市|