<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > stm32庫(kù)函數(shù)學(xué)習(xí)篇通用定時(shí)器輸入捕獲功能

          stm32庫(kù)函數(shù)學(xué)習(xí)篇通用定時(shí)器輸入捕獲功能

          作者: 時(shí)間:2016-11-19 來(lái)源:網(wǎng)絡(luò) 收藏
          實(shí)現(xiàn)功能:PA8隨意延時(shí)驅(qū)動(dòng)led燈閃爍,并且將PA8用杜邦線連接到PA7口,PA7是通用定時(shí)器TIM3的2通道,在TIM3_CH2觸發(fā)中斷程序中取反連接到PD2口的led燈,指示中斷程序運(yùn)行,并且每次進(jìn)入中斷后改變觸發(fā)捕獲的極性。實(shí)現(xiàn)兩個(gè)led燈會(huì)交替閃爍。

          本文引用地址:http://www.ex-cimer.com/article/201611/318488.htm

          先有必要了解stm32定時(shí)器的輸入觸發(fā)模塊,如下圖:

          需要注意的是,一眼望去一個(gè)定時(shí)器似乎有8個(gè)通道,左邊四個(gè),右邊四個(gè),但其實(shí)左邊和右邊是共用相同的IO引腳,所以名稱標(biāo)注是一模一樣。也就是說(shuō),每個(gè)通用定時(shí)器都只有四個(gè)獨(dú)立通道,當(dāng)某一通道作為了輸入觸發(fā)功能那就不能再作為輸出匹配功能。這一點(diǎn)我們也可以從其他地方找到印證。比如TIM_ITConfig()函數(shù)中如下:

          void TIM_ITConfig

          (

          TIM_TypeDef *

          TIMx,

          uint16_t

          TIM_IT,

          FunctionalState

          NewState

          )

          Enables or disables the specified TIM interrupts.

          Parameters:

          TIMx,:

          where x can be 1 to 17 to select the TIMx peripheral.

          TIM_IT,:

          specifies the TIM interrupts sources to be enabled or disabled. This parameter can be any combination of the following values:

          TIM_IT_Update: TIM update Interrupt source TIM_IT_CC1: TIM Capture Compare 1 Interrupt source TIM_IT_CC2: TIM Capture Compare 2 Interrupt source TIM_IT_CC3: TIM Capture Compare 3 Interrupt source TIM_IT_CC4: TIM Capture Compare 4 Interrupt source TIM_IT_COM: TIM Commutation Interrupt source TIM_IT_Trigger: TIM Trigger Interrupt source TIM_IT_Break: TIM Break Interrupt source

          我們可以看到此函數(shù)TIM_IT參數(shù)的取值范圍如下:

          TIM_IT_Update: TIM update Interrupt source

          TIM_IT_CC1: TIM Capture Compare 1 Interrupt source

          TIM_IT_CC2: TIM Capture Compare 2 Interrupt source

          TIM_IT_CC3: TIM Capture Compare 3 Interrupt source

          TIM_IT_CC4: TIM Capture Compare 4 Interrupt source

          TIM_IT_COM: TIM Commutation Interrupt source

          TIM_IT_Trigger: TIM Trigger Interrupt source

          TIM_IT_Break: TIM Break Interrupt source

          也就是說(shuō)每個(gè)通道的捕獲和比較功能是共用一個(gè)中斷標(biāo)志。

          stm32定時(shí)器輸入觸發(fā)功能其實(shí)挺簡(jiǎn)單的,與AVR單片機(jī)幾乎一樣。就是單片機(jī)引腳上一旦出現(xiàn)一個(gè)有效邊沿(可以配置為上升、下降或者上升下降均觸發(fā)),那么定時(shí)器計(jì)數(shù)器CNT里面的值就會(huì)被相應(yīng)的Capture/Compare X Register保存下來(lái)。這里X可以是1,2,3,4任何一個(gè)。并且中斷標(biāo)志位被置位。但是此時(shí)TIM的計(jì)數(shù)寄存器CNT卻不管這一事件的發(fā)生,繼續(xù)自己的計(jì)數(shù)。此功能可以用來(lái)測(cè)量外部信號(hào)的脈寬或者是周期。

          對(duì)于定時(shí)器的時(shí)基單元TIM_TimeBaseStructure就不作說(shuō)明了,在我前面的文章有專門介紹。下面就重點(diǎn)講解輸入觸發(fā)單元TIM_ICInitStructure。

          首先看次結(jié)構(gòu)體原型的定義如下:

          typedef struct
          {
           uint16_t TIM_Channel; /*!< Specifies the TIM channel.
           This parameter can be a value of @ref TIM_Channel */
           uint16_t TIM_ICPolarity; /*!< Specifies the active edge of the input signal.
          This parameter can be a value of @ref TIM_Input_Capture_Polarity */
           uint16_t TIM_ICSelection; /*!< Specifies the input.
           This parameter can be a value of @ref TIM_Input_Capture_Selection */
           uint16_t TIM_ICPrescaler; /*!< Specifies the Input Capture Prescaler.
          This parameter can be a value of @ref TIM_Input_Capture_Prescaler */
           uint16_t TIM_ICFilter; /*!< Specifies the input capture filter.
          This parameter can be a number between 0x0 and 0xF */
          } TIM_ICInitTypeDef;

          它一共有5個(gè)成員,5個(gè)成員具體作用,我們只要看看3.5版本固件庫(kù)的說(shuō)明就清楚了。

          uint16_t TIM_ICInitTypeDef::TIM_Channel

          Specifies the TIM channel. This parameter can be a value of TIM_Channel

          其中TIM_Channel的取值范圍如下:

          TIM_Channel_1.

          TIM_Channel_2

          TIM_Channel_3

          TIM_Channel_4

          uint16_t TIM_ICInitTypeDef::TIM_ICFilter

          Specifies the input capture filter. This parameter can be a number between 0x0 and 0xF

          說(shuō)實(shí)話這個(gè)成員具體作用我沒(méi)有深入了解,僅僅知道是作為對(duì)輸入信號(hào)的濾波作用,估計(jì)是讓用戶設(shè)定用多少個(gè)采樣時(shí)鐘來(lái)確定最終輸入信號(hào),起到濾波作用,避免高頻信號(hào)干擾,反正不管它了。

          uint16_t TIM_ICInitTypeDef::TIM_ICPolarity

          Specifies the active edge of the input signal. This parameter can be a value of TIM_Input_Capture_Polarity

          這個(gè)就是觸發(fā)邊沿的極性選擇了,取值范圍如下:

          TIM_ICPolarity_BothEdge

          TIM_ICPolarity_Rising

          TIM_ICPolarity_Falling

          uint16_t TIM_ICInitTypeDef::TIM_ICPrescaler

          Specifies the Input Capture Prescaler. This parameter can be a value of TIM_Input_Capture_Prescaler

          這個(gè)成員是對(duì)外部信號(hào)進(jìn)行分頻,也即是設(shè)置上圖中的Prescaler,可以設(shè)置為1/2/4/8分頻。

          uint16_t TIM_ICInitTypeDef::TIM_ICSelection

          Specifies the input. This parameter can be a value of TIM_Input_Capture_Selection

          這個(gè)成員的作用就必須要對(duì)照上面的示意圖才能明白。仔細(xì)看上面的圖,可以發(fā)現(xiàn)定時(shí)器的4個(gè)通道并不是完全獨(dú)立的,而是1、2一組,3、4一組,同組之間的通道是有聯(lián)系的。也就是可以出現(xiàn)交叉觸發(fā)。而TIM_ICSelection就是選擇要不要使用交叉來(lái)觸發(fā),如果不明白可以看固件庫(kù)的說(shuō)明文檔,如下是此結(jié)構(gòu)體成員的取值范圍:

          #define TIM_ICSelection_DirectTI((uint16_t)0x0001)

          TIM Input 1, 2, 3 or 4 is selected to be connected to IC1, IC2, IC3 or IC4, respectively

          #define TIM_ICSelection_IndirectTI((uint16_t)0x0002)

          TIM Input 1, 2, 3 or 4 is selected to be connected to IC2, IC1, IC4 or IC3, respectively.

          #define TIM_ICSelection_TRC((uint16_t)0x0003)

          TIM Input 1, 2, 3 or 4 is selected to be connected to TRC.

          也就是說(shuō),根據(jù)不同的取值,可以講外部引腳的觸發(fā)信號(hào)連到內(nèi)部不同的單元,這樣就使得單片機(jī)更加靈活了。

          下面是main.c文件

          #include "stm32f10x.h"

          GPIO_InitTypeDef GPIO_InitStructure;

          TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

          TIM_ICInitTypeDef TIM_ICInitStructure;

          NVIC_InitTypeDef NVIC_InitStructure;

          void delay()

          {

          u32 i,j;

          for(i=0;i<1000;i++)

          for(j=0;j<5000;j++)

          ;

          }

          void rcc_cfg()

          {

          ;

          }

          void gpio_cfg()

          {

          RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOA, ENABLE);

          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //隨意延時(shí)led取反,且將PA8作為觸發(fā)定時(shí)器電平

          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;

          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

          GPIO_Init(GPIOA, &GPIO_InitStructure);

          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //觸發(fā)中斷時(shí),取反PD2

          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

          GPIO_Init(GPIOD, &GPIO_InitStructure);

          /* TIM3 channel 2 pin (PA.07) configuration */

          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;

          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

          GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_FLOATING;

          GPIO_Init(GPIOA, &GPIO_InitStructure);

          }

          void nvic_cfg()

          {

          NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

          /* Enable the TIM3 global Interrupt */

          NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中斷

          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占優(yōu)先級(jí)0級(jí)

          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //從優(yōu)先級(jí)3級(jí)

          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能

          NVIC_Init(&NVIC_InitStructure); //根據(jù)NVIC_InitStruct中指定的參數(shù)初始化外設(shè)NVIC寄存器

          }

          void tim3_cfg()

          {

          RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);

          TIM_DeInit(TIM3);

          TIM_InternalClockConfig(TIM3);

          //預(yù)分頻系數(shù)為36000-1,這樣計(jì)數(shù)器時(shí)鐘為72MHz/36000 = 2kHz

          TIM_TimeBaseStructure.TIM_Prescaler = 36000 - 1;

          //設(shè)置時(shí)鐘分割

          TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

          //設(shè)置計(jì)數(shù)器模式為向上計(jì)數(shù)模

          TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

          //設(shè)置計(jì)數(shù)溢出大小,每計(jì)2000個(gè)數(shù)就產(chǎn)生一個(gè)更新事件

          TIM_TimeBaseStructure.TIM_Period = 2000 - 1;

          //將配置應(yīng)用到TIM2中

          TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);

          //禁止ARR預(yù)裝載緩沖器

          TIM_ARRPreloadConfig(TIM3, DISABLE);

          //下面是對(duì)TIM_ICInitStructure的配置

          TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;

          TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;

          TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;

          TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;

          TIM_ICInitStructure.TIM_ICFilter = 0x0; /*選擇輸入比較濾波器,濾波設(shè)置,經(jīng)歷幾個(gè)周期跳變認(rèn)定波形穩(wěn)定0x0~0xF*/

          TIM_ICInit(TIM3, &TIM_ICInitStructure);

          //開啟TIM2的中斷

          TIM_ClearFlag(TIM3, TIM_IT_CC2);

          TIM_ITConfig(TIM3,TIM_IT_CC2,ENABLE);

          TIM_Cmd(TIM3, ENABLE); //使能TIMx外設(shè)

          }

          /

          * @brief Main program.

          * @param None

          * @retval None

          */

          int main(void)

          {

          rcc_cfg();

          gpio_cfg();

          nvic_cfg();

          tim3_cfg();

          while (1)

          {

          /* Set PA8 */

          GPIO_WriteBit(GPIOA, GPIO_Pin_8, Bit_SET);

          delay();

          /* Reset PA8 */

          GPIO_WriteBit(GPIOA, GPIO_Pin_8, Bit_RESET);

          delay();

          }

          }

          注意定時(shí)器3通道2引腳設(shè)置為浮空輸入。

          下面是stm32f10x_it.c文件

          #include "stm32f10x_it.h"

          u8 flag=0;

          extern TIM_ICInitTypeDef TIM_ICInitStructure;

          void TIM3_IRQHandler(void)

          {

          if(TIM_GetITStatus(TIM3, TIM_IT_CC2) == SET)

          {

          /* Clear TIM3 Capture compare interrupt pending bit */

          TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);

          //每次進(jìn)入中斷就改變捕獲觸發(fā)方式,且翻轉(zhuǎn)PD2的電平

          if(flag==0)

          {

          flag=1;

          TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;

          TIM_ICInit(TIM3, &TIM_ICInitStructure);

          GPIO_WriteBit(GPIOD, GPIO_Pin_2, Bit_RESET);

          }

          else

          {

          flag=0;

          TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;

          TIM_ICInit(TIM3, &TIM_ICInitStructure);

          GPIO_WriteBit(GPIOD, GPIO_Pin_2, Bit_SET);

          }

          }

          }

          程序運(yùn)行后,可以看到板子上兩個(gè)led燈交替閃爍。

          我并沒(méi)有對(duì)捕獲值作任何處理,因?yàn)槲抑皇菧y(cè)試程序是否能順利進(jìn)入捕獲中斷。



          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();