新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > STM32F10x 學習筆記10(基本定時器)

        STM32F10x 學習筆記10(基本定時器)

        作者: 時間:2016-11-20 來源:網絡 收藏
        大容量的STM32F101xx、STM32F103xx系列和互聯型產品中包含了兩個基本定時器,TIM6和TIM7。這兩個定時器功能非常簡單,基本上和SysTick定時器相當。

        但是我在使用的時候確是費了一番周折才調試通過,所以還是應該將這兩個定時器的使用方法好好的寫一寫。

        本文引用地址:http://www.104case.com/article/201611/318846.htm

        基本定時器TIM6和TIM7各包含一個16位自動裝載計數器,由各自的可編程分頻器驅動。簡單的說兩個定時器是從0計數到N(由自動裝載計數器來確定N的具體值),然后復位回0重新計數。每次復位到0的時候可以產生對應的中斷信號,或者產生DMA請求,還可以觸發DAC同步電路。不過這次筆記不討論觸發DAC的問題,等寫到DAC的使用時在講解如何用這兩定時器驅動DAC。

        基本定時器TIM6和TIM7掛載在APB1總線上,在使用之前需要先使能對應的時鐘信號。對應的語句如下:

        1. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE);
        2. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7,ENABLE);

        APB1總線上的時鐘信號在進入定時器之后第一件事情是被預分頻器TIMx_PSC分頻。程序中隨時都可以更改TIMx_PSC的值,但是TIMx_PSC是有緩沖的,只有發生了更新事件時新的預分頻值才會生效。

        另外有一點必須要特別注意:如果我們想對CK_PSC時鐘信號N分頻的話,TIMx_PSC中應該寫入M-1,而不是M。

        對應的語句如下:

        1. TIMx->PSC=M-1;

        如果我們希望立刻更新預分頻器也是有辦法的,那就是軟件觸發一次更新事件。TIM6和TIM7有個事件產生寄存器(TIMx_EGR)就是起這個作用的。TIMx_EGR只有最低位有用,稱之為UG位,向這一位寫入1則產生更新事件,定時器的計數器被歸零。

        對應的語句如下:

        1. TIMx->EGR=0x0001;

        自動重裝載寄存器TIMx_ARR決定了CNT計數器最高記到多少就會歸零。自動重裝載寄存器也是帶緩存的。如果TIMx_CR1寄存器中的自動重裝載預加載使能位(ARPE)為0,則寫入自動重裝載寄存器的值立即起作用。如果ARPE=1,則要等到發生了更新事件后才會起作用。舉例來說,當前自動重裝載寄存器的值為20000,CNT計數器的值為1000,ARPE=1,這時我們向自動重裝載寄存器寫個5000,CNT計數器記到5000時并不會歸零,它還要繼續直到記到20000然后歸零,在歸零的同時產生計數器溢出事件,計數器溢出事件可以產生更新事件,之后自動重裝載寄存器的值才真的變為5000了。

        這里出現了兩個事件:計數器溢出事件和更新事件。這兩個實際是不同的。每次當計數器溢出時都會產生計數器溢出事件,但是不一定產生更新事件。

        TIM6和TIM7控制寄存器1(TIMx_CR1)有一位UDIS:禁止更新(Updatedisable)位。

        如果這位被設置為1,則計數器溢出事件不會產生更新事件。不產生更新事件則預分頻器的系數不能被更新,自動重裝載寄存器的值也可能不能更新(ARPE=1)。

        只是產生更新事件是沒有用的,我們最終需要的是產生中斷或DMA請求。這里先說中斷的產生。

        TIM6和TIM7DMA/中斷使能寄存器(TIMx_DIER)有一位為UIE。只有這一位為1時才能產生更新中斷。

        對應的語句如下:

        1. TIMx->DIER|=0x0001;

        TIM6和TIM7狀態寄存器(TIMx_SR)中也只有一位是有用的,位于這個寄存器的最低位,稱之為UIF位。這一位為1標志著產生了更新中斷。什么時候這一位才能為1呢?簡單的說就是產生更新事件這一位會被置位為1,不過也有特殊情況,我們知道有兩種情況會產生更新事件:計數器溢出事件和UG=1。如果TIMx_CR1的URS位被設為了1,則UG=1產生的更新事件不會將UIF位置位1。

        一般來說我們都不希望UG=1時產生中斷,所以多數時間我們會設置URS位為1。

        對應的語句如下:

        1. TIMx->CR1|=0x0004;

        下面是一個例子程序,使用TIM6,產生一個5Hz的定時中斷。時鐘頻率為72MHz。

        1. voidTIM6_Init(void)
        2. {
        3. NVIC_InitTypeDefNVIC_InitStructure;
        4. NVIC_InitStructure.NVIC_IRQChannel=TIM6_IRQn;
        5. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
        6. NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
        7. NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
        8. NVIC_Init(&NVIC_InitStructure);
        9. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE);
        10. TIM6->PSC=7200-1;//分頻之后的時鐘頻率為10KHz
        11. TIM6->ARR=2000-1;//5Hz定時頻率
        12. TIM6->CR1=0x0004+0x0001;//URS=1CEN=1
        13. TIM6->DIER=0x0001;//使能更新中斷
        14. }
        15. voidTIM6_IRQHandler(void)
        16. {
        17. LED_Flash(GPIO_LED2);
        18. TIM6->SR=0x0000;//清標志位
        19. }

        還可以完全用STM32F10xStandardPeripheralsFirmwareLibrary來寫這個程序。下面用TIM7實現類似的功能。

        1. voidTIM7_Init(void)
        2. {
        3. TIM_TimeBaseInitTypeDefTIM7_TimeBaseStructure;
        4. NVIC_InitTypeDefNVIC_InitStructure;
        5. NVIC_InitStructure.NVIC_IRQChannel=TIM7_IRQn;
        6. NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
        7. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
        8. NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
        9. NVIC_Init(&NVIC_InitStructure);
        10. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7,ENABLE);//RCC_APB1Periph_TIM7
        11. TIM_TimeBaseStructInit(&TIM7_TimeBaseStructure);
        12. TIM7_TimeBaseStructure.TIM_Prescaler=36000-1;//分頻之后的時鐘頻率為2KHz
        13. TIM7_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
        14. TIM7_TimeBaseStructure.TIM_Period=400-1;//5Hz定時頻率
        15. TIM7_TimeBaseStructure.TIM_ClockDivision=0;
        16. TIM_TimeBaseInit(TIM7,&TIM7_TimeBaseStructure);
        17. TIM_UpdateRequestConfig(TIM7,TIM_UpdateSource_Regular);
        18. TIM_Cmd(TIM7,ENABLE);
        19. TIM_ITConfig(TIM7,TIM_IT_Update,ENABLE);
        20. }
        21. voidTIM7_IRQHandler(void)
        22. {
        23. if(TIM_GetITStatus(TIM7,TIM_IT_Update)==SET)
        24. {
        25. LED_Flash(GPIO_LED3);
        26. TIM_ClearITPendingBit(TIM7,TIM_FLAG_Update);
        27. }
        28. }

        程序寫完了,這里說幾點注意事項。

        (1)在對TIMx 進行設置之前一定要打開APB1總線上對應的時鐘,否則所有的設置都不起作用。

        (2)一定要設置NVIC,因為默認情況下這些外設的中斷都是被禁用的。


        評論


        技術專區

        關閉
        主站蜘蛛池模板: 安远县| 巴东县| 综艺| 菏泽市| 保山市| 连云港市| 大同县| 来凤县| 康定县| 翁牛特旗| 邵武市| 定日县| 莎车县| 桐庐县| 诏安县| 平和县| 临猗县| 七台河市| 阿尔山市| 元氏县| 平定县| 大姚县| 鲁山县| 双鸭山市| 漳平市| 西盟| 沂源县| 图木舒克市| 右玉县| 泌阳县| 敦煌市| 郯城县| 新源县| 勃利县| 榕江县| 平泉县| 芮城县| 兖州市| 南阳市| 庐江县| 罗平县|