STM32定時(shí)器學(xué)習(xí)---基本定時(shí)器

  STM32F1系列的產(chǎn)品,除了互聯(lián)網(wǎng)產(chǎn)品外,工作8個(gè),3種定時(shí)器,其中一種就是基本定時(shí)器。那么STM32單片機(jī)的基本定時(shí)器如何操作以及編程呢?

  下面我們就來(lái)詳細(xì)的了解一下

  STM32F1系列的產(chǎn)品,除了互聯(lián)型產(chǎn)品外,工位8個(gè)定時(shí)器

  TIM6、TIM7:基本定時(shí)器

  TIM2/3/4/5:通用定時(shí)器

  TIM1、TIM8:高級(jí)定時(shí)器

  三種定時(shí)器的區(qū)別:


  基本定時(shí)器TIM6和TIM7各包含一個(gè)16位自動(dòng)裝載計(jì)數(shù)器,由各自的可編程預(yù)分頻器驅(qū)動(dòng)。簡(jiǎn)單的說(shuō)兩個(gè)定時(shí)器是從0計(jì)數(shù)到N(由自動(dòng)裝載計(jì)數(shù)器來(lái)確定N的具體值),然后復(fù)位回0

重新計(jì)數(shù)。每次復(fù)位到0 的時(shí)候可以產(chǎn)生對(duì)應(yīng)的中斷信號(hào),或者產(chǎn)生DMA 請(qǐng)求,還可以觸發(fā)DAC 同步電路。不過(guò)這次筆記不討論觸發(fā)DAC 的問(wèn)題,等寫到DAC

的使用時(shí)在講解如何用這兩定時(shí)器驅(qū)動(dòng)DAC。

  基本定時(shí)器TIM6和TIM7掛載在APB1總線上,在使用之前需要先使能對(duì)應(yīng)的時(shí)鐘信號(hào)。對(duì)應(yīng)的語(yǔ)句如下:

  [cpp] view plaincopy

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE);

  APB1

總線上的時(shí)鐘信號(hào)在進(jìn)入定時(shí)器之后第一件事情是被預(yù)分頻器TIMx_PSC分頻。程序中隨時(shí)都可以更改TIMx_PSC的值,但是TIMx_PSC是有緩沖的,只有發(fā)生了更新事件時(shí)新的預(yù)分頻值才會(huì)生效。

  另外有一點(diǎn)必須要特別注意:如果我們想對(duì) CK_PSC 時(shí)鐘信號(hào)N 分頻的話,TIMx_PSC 中應(yīng)該寫入 M - 1,而不是 M。

  對(duì)應(yīng)的語(yǔ)句如下:

  [cpp] view plaincopy

  TIMx->PSC = M - 1;

  如果我們希望立刻更新預(yù)分頻器也是有辦法的,那就是軟件觸發(fā)一次更新事件。TIM6和TIM7有個(gè)事件產(chǎn)生寄存器(TIMx_EGR)

就是起這個(gè)作用的。TIMx_EGR 只有最低位有用,稱之為 UG 位,向這一位寫入 1 則產(chǎn)生更新事件,定時(shí)器的計(jì)數(shù)器被歸零。

  對(duì)應(yīng)的語(yǔ)句如下:

  [cpp] view plaincopy

  TIMx->EGR = 0x0001;

  自動(dòng)重裝載寄存器TIMx_ARR決定了CNT

計(jì)數(shù)器最高記到多少就會(huì)歸零。自動(dòng)重裝載寄存器也是帶緩存的。如果TIMx_CR1寄存器中的自動(dòng)重裝載預(yù)加載使能位(ARPE)為0,則寫入自動(dòng)重裝載寄存器的值立即起作用。如果ARPE

= 1,則要等到發(fā)生了更新事件后才會(huì)起作用。舉例來(lái)說(shuō),當(dāng)前自動(dòng)重裝載寄存器的值為20000,CNT 計(jì)數(shù)器的值為1000,ARPE =

1,這時(shí)我們向自動(dòng)重裝載寄存器寫個(gè) 5000,CNT 計(jì)數(shù)器記到 5000

時(shí)并不會(huì)歸零,它還要繼續(xù)直到記到20000然后歸零,在歸零的同時(shí)產(chǎn)生計(jì)數(shù)器溢出事件,計(jì)數(shù)器溢出事件可以產(chǎn)生更新事件,之后自動(dòng)重裝載寄存器的值才真的變?yōu)?000了。

  這里出現(xiàn)了兩個(gè)事件:計(jì)數(shù)器溢出事件和更新事件。這兩個(gè)實(shí)際是不同的。每次當(dāng)計(jì)數(shù)器溢出時(shí)都會(huì)產(chǎn)生計(jì)數(shù)器溢出事件,但是不一定產(chǎn)生更新事件。

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

  如果這位被設(shè)置為1,則計(jì)數(shù)器溢出事件不會(huì)產(chǎn)生更新事件。不產(chǎn)生更新事件則預(yù)分頻器的系數(shù)不能被更新,自動(dòng)重裝載寄存器的值也可能不能更新(ARPE =

1)。

  只是產(chǎn)生更新事件是沒(méi)有用的,我們最終需要的是產(chǎn)生中斷或DMA請(qǐng)求。這里先說(shuō)中斷的產(chǎn)生。

  TIM6和TIM7 DMA/中斷使能寄存器(TIMx_DIER) 有一位為UIE。只有這一位為1時(shí)才能產(chǎn)生更新中斷。

  對(duì)應(yīng)的語(yǔ)句如下:

  [cpp] view plaincopy

  TIMx->DIER |= 0x0001;

  TIM6和TIM7狀態(tài)寄存器(TIMx_SR) 中也只有一位是有用的,位于這個(gè)寄存器的最低位,稱之為UIF位。這一位為1

標(biāo)志著產(chǎn)生了更新中斷。什么時(shí)候這一位才能為1呢?簡(jiǎn)單的說(shuō)就是產(chǎn)生更新事件這一位會(huì)被置位為1,不過(guò)也有特殊情況,我們知道有兩種情況會(huì)產(chǎn)生更新事件:計(jì)數(shù)器溢出事件和

UG=1。如果TIMx_CR1的URS位被設(shè)為了1,則UG=1 產(chǎn)生的更新事件不會(huì)將UIF位置位1。

  一般來(lái)說(shuō)我們都不希望UG=1時(shí)產(chǎn)生中斷,所以多數(shù)時(shí)間我們會(huì)設(shè)置URS位為1。

  對(duì)應(yīng)的語(yǔ)句如下:

  [cpp] view plaincopy

  TIMx->CR1 |= 0x0004;

  下面是一個(gè)例子程序,使用TIM6,產(chǎn)生一個(gè)5Hz的定時(shí)中斷。時(shí)鐘頻率為72MHz。

  [cpp] view plaincopy

  void TIM6_Init(void)

  {

  NVIC_InitTypeDef NVIC_InitStructure;

  NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);

  TIM6->PSC = 7200 - 1; // 分頻之后的時(shí)鐘頻率為10KHz

  TIM6->ARR = 2000 - 1; // 5Hz 定時(shí)頻率

  TIM6->CR1 = 0x0004 + 0x0001; // URS = 1 CEN = 1

  TIM6->DIER = 0x0001; // 使能更新中斷

  }

  void TIM6_IRQHandler(void)

  {

  LED_Flash(GPIO_LED2);

  TIM6->SR=0x0000;//清標(biāo)志位

  }

  還可以完全用STM32F10x Standard Peripherals Firmware Library 來(lái)寫這個(gè)程序。下面用TIM7

實(shí)現(xiàn)類似的功能。

  [cpp] view plaincopy

  void TIM7_Init(void)

  {

  TIM_TimeBaseInitTypeDef TIM7_TimeBaseStructure;

  NVIC_InitTypeDef NVIC_InitStructure;

  NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

  NVIC_Init(&NVIC_InitStructure);

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE);

//RCC_APB1Periph_TIM7

  TIM_TimeBaseStructInit(&TIM7_TimeBaseStructure);

  TIM7_TimeBaseStructure.TIM_Prescaler = 36000 - 1; // 分頻之后的時(shí)鐘頻率為2KHz

  TIM7_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

  TIM7_TimeBaseStructure.TIM_Period = 400 - 1; // 5Hz 定時(shí)頻率

  TIM7_TimeBaseStructure.TIM_ClockDivision = 0;

  TIM_TimeBaseInit(TIM7, &TIM7_TimeBaseStructure);

  TIM_UpdateRequestConfig(TIM7, TIM_UpdateSource_Regular);

  TIM_Cmd(TIM7, ENABLE);

  TIM_ITConfig(TIM7, TIM_IT_Update, ENABLE);

  }

  void TIM7_IRQHandler(void)

  {

  if(TIM_GetITStatus(TIM7, TIM_IT_Update)== SET)

  {

  LED_Flash(GPIO_LED3);

  TIM_ClearITPendingBit(TIM7 , TIM_FLAG_Update);

  }

  }

  程序?qū)懲炅耍@里說(shuō)幾點(diǎn)注意事項(xiàng)。

  (1)在對(duì)TIMx 進(jìn)行設(shè)置之前一定要打開(kāi)APB1總線上對(duì)應(yīng)的時(shí)鐘,否則所有的設(shè)置都不起作用。

  (2)一定要設(shè)置NVIC,因?yàn)槟J(rèn)情況下這些外設(shè)的中斷都是被禁用的。

  stm32相關(guān)的學(xué)習(xí)資料

  (stm32 USART串口應(yīng)用)

  http://www.makeru.com.cn/live/1392_1164.html?s=45051

  (定時(shí)器)

  http://www.makeru.com.cn/live/1392_1199.html?s=45051

  STM32定時(shí)器深藏不露的絕技

  http://www.makeru.com.cn/live/3523_1495.html?s=45051

  stm32 如何用DMA搬運(yùn)數(shù)據(jù)

  http://www.makeru.com.cn/live/detail/1484.html?s=45051

  (STM32中斷系統(tǒng))

  http://www.makeru.com.cn/live/1392_1124.html?s=45051

  (時(shí)鐘系統(tǒng))

  http://www.makeru.com.cn/live/1392_1082.html?s=45051

  STM32中斷系統(tǒng)

  http://www.makeru.com.cn/live/3523_1745.html?s=45051

  STM32可以這樣玩

  http://www.makeru.com.cn/live/4034_1460.html?s=45051

?著作權(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),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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