stm32庫函數學習篇通用定時器輸入捕獲功能

2021-01-11 電子產品世界
實現功能:PA8隨意延時驅動led燈閃爍,並且將PA8用杜邦線連接到PA7口,PA7是通用定時器TIM3的2通道,在TIM3_CH2觸發中斷程序中取反連接到PD2口的led燈,指示中斷程序運行,並且每次進入中斷後改變觸發捕獲的極性。實現兩個led燈會交替閃爍。

本文引用地址:http://www.eepw.com.cn/article/201611/318488.htm

先有必要了解stm32定時器的輸入觸發模塊,如下圖:

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

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

我們可以看到此函數TIM_IT參數的取值範圍如下:

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

也就是說每個通道的捕獲和比較功能是共用一個中斷標誌。

stm32定時器輸入觸發功能其實挺簡單的,與AVR單片機幾乎一樣。就是單片機引腳上一旦出現一個有效邊沿(可以配置為上升、下降或者上升下降均觸發),那麼定時器計數器CNT裡面的值就會被相應的Capture/Compare X Register保存下來。這裡X可以是1,2,3,4任何一個。並且中斷標誌位被置位。但是此時TIM的計數寄存器CNT卻不管這一事件的發生,繼續自己的計數。此功能可以用來測量外部信號的脈寬或者是周期。

對於定時器的時基單元TIM_TimeBaseStructure就不作說明了,在我前面的文章有專門介紹。下面就重點講解輸入觸發單元TIM_ICInitStructure。

首先看次結構體原型的定義如下:

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個成員,5個成員具體作用,我們只要看看3.5版本固件庫的說明就清楚了。

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

說實話這個成員具體作用我沒有深入了解,僅僅知道是作為對輸入信號的濾波作用,估計是讓用戶設定用多少個採樣時鐘來確定最終輸入信號,起到濾波作用,避免高頻信號幹擾,反正不管它了。

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

這個就是觸發邊沿的極性選擇了,取值範圍如下:

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

這個成員是對外部信號進行分頻,也即是設置上圖中的Prescaler,可以設置為1/2/4/8分頻。

uint16_t TIM_ICInitTypeDef::TIM_ICSelection

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

這個成員的作用就必須要對照上面的示意圖才能明白。仔細看上面的圖,可以發現定時器的4個通道並不是完全獨立的,而是1、2一組,3、4一組,同組之間的通道是有聯繫的。也就是可以出現交叉觸發。而TIM_ICSelection就是選擇要不要使用交叉來觸發,如果不明白可以看固件庫的說明文檔,如下是此結構體成員的取值範圍:

#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.

也就是說,根據不同的取值,可以講外部引腳的觸發信號連到內部不同的單元,這樣就使得單片機更加靈活了。

下面是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; //隨意延時led取反,且將PA8作為觸發定時器電平

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; //觸發中斷時,取反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; //先佔優先級0級

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //從優先級3級

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

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

}

void tim3_cfg()

{

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);

TIM_DeInit(TIM3);

TIM_InternalClockConfig(TIM3);

//預分頻係數為36000-1,這樣計數器時鐘為72MHz/36000 = 2kHz

TIM_TimeBaseStructure.TIM_Prescaler = 36000 - 1;

//設置時鐘分割

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

//設置計數器模式為向上計數模

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

//設置計數溢出大小,每計2000個數就產生一個更新事件

TIM_TimeBaseStructure.TIM_Period = 2000 - 1;

//將配置應用到TIM2中

TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);

//禁止ARR預裝載緩衝器

TIM_ARRPreloadConfig(TIM3, DISABLE);

//下面是對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; /*選擇輸入比較濾波器,濾波設置,經歷幾個周期跳變認定波形穩定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外設

}

/

* @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();

}

}

注意定時器3通道2引腳設置為浮空輸入。

下面是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);

//每次進入中斷就改變捕獲觸發方式,且翻轉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);

}

}

}

程序運行後,可以看到板子上兩個led燈交替閃爍。

我並沒有對捕獲值作任何處理,因為我只是測試程序是否能順利進入捕獲中斷。

相關焦點

  • STM32定時器捕獲PWM脈衝頻率
    一、概念理解PWM輸入捕獲模式是輸入捕獲模式的特例,自己理解如下1. 每個定時器有四個輸入捕獲通道IC1、IC2、IC3、IC4。且IC1 IC2一組,IC3 IC4一組。並且可是設置管腳和寄存器的對應關係。2. 同一個TIx輸入映射了兩個ICx信號。3.
  • 基於STM32定時器的紅外遙控數據接收設計原理
    2、定時器計數和輸入捕獲 定時器就是按照一個特定的頻率對計數值進行加一或減一操作,當數值溢出時則產生一個標誌或中斷。 定時器的輸入捕獲就是可以測量輸入信號的脈衝寬度。 本次就是通過普通計數和輸入捕獲的結合來實現的。
  • 如何採用STM32中的控制定時器Tim1實現計數器功能
    STM32中的高級控制定時器(Tim1)是由一個16位的自動裝載計數器組成,它由一個可編程預分頻器驅動。 用途在於:測量輸入信號的脈衝寬度(輸入捕獲),或者產生輸出波形(輸出比較,PWM,嵌入死區時間的互補PWM等)。 使用定時器預分頻器和RCC時鐘控制預分頻器,可以實現脈衝寬度和波形周期從幾個微秒到幾個毫秒的調節。
  • STM32 定時器的4通道計數器應用
    通用定時器確實比較強悍,功能極多我也比較暈此為在不牽扯PWM與DMA下像C51那樣計數點燈。本文引用地址:http://www.eepw.com.cn/article/201611/317176.htm當然你要配置一些IO口作為點燈用這裡就不詳細說了。
  • STM32F1通用定時器配置步驟(使用HAL庫)
    ; //時鐘分頻uint8_t TIM_RepetitionCounter; //重複計數器} TIM_TimeBaseInitTypeDef;了解結構體成員功能後,就可以進行配置,例如:TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_Period
  • STM32學習筆記——使用函數庫編程控制GPIO口輸出
    看了網上許多人的代碼以及各類開發板所帶的例程,大多數使用的都是官方發布的函數庫來編程,通過查詢後發現,使用函數庫來編程可以簡化開發過程,並不需要追溯到各個寄存器,通過查看庫手冊,新手也可以快速應用STM32,因此
  • 一個定時器生成多路PWM波形的原理和方法
    這個學習筆記就用SysTick 定時器來實現走馬燈的功能。SysTick 定時器非常簡答,只有四個寄存器。這四個寄存器的含義在《Cortex-M3權威指南》那本書中講的非常的清楚,這裡不複述了,下面只講講在STM32上SysTick有什麼特殊之處。
  • avr單片機和stm32區別與優缺點分析
    avr的片內RAM的地址區間為 0~00DF(AT90S2313) 和0060~025F(AT90S8515、AT90S8535),它們佔用的是數據空間的地址,這些片內RAM僅僅是用來存儲數據的,通常不具備通用寄 存器的功能。當程序複雜時,通用寄存器R0~R31就顯得不夠用;而51系列的通用寄存器多達128個(為avr的4倍),編程時就不會有這種感覺。
  • STM32 高級定時器-PWM簡單使用
    高級定時器與通用定時器比較類似,下面是一個TIM1 的PWM 程序,TIM1是STM32唯一的高級定時器。共有4個通道有 死區有互補。本文引用地址:http://www.eepw.com.cn/article/201612/325215.htm先是配置IO腳: GPIO_InitTypeDef GPIO_InitStructure; /* PA8設置為功能腳(PWM) */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  • 怎麼學習STM32單片機?看老司機是怎麼說的!
    本文引用地址:http://www.eepw.com.cn/article/201705/359058.htm  我不是說STM32不好,而是這種為了學習單片機而去學習單片機的思路不對。  你問,如何系統地入門學習stm32?  本身就是一個錯誤的問題。
  • 基於STM32的新型角度測量系統設計
    更重要的是STM32F107的定時器除了TIM6和TIM7,都有輸入捕獲功能。3.1 輸入捕獲功能應用於角度測量的工作原理以 TIM2定時器實現輸入捕獲功能為例。TIM2有4個獨立通道,通過檢測TIM2_CH1通道上的邊沿信號,在邊沿信號發生跳變(比如上升沿/下降沿)的 時候,將當前定時器的值存放到TIM2_CH1的捕獲/比較寄存器裡面,完成一次捕獲。
  • stm32f407之高級定時器 死區互補PWM(操作寄存器)
    高級定時器的功能有很多,這裡只介紹死區互補PWM輸出功能。其實死區互補PWM跟通用定時器的PWM配置差異不大,只是需要設置多CCER寄存器中的幾個位以及剎車與死區寄存器BDTR。對寄存器的具體描述請參考數據手冊。配置步驟:1.     使能相關時鐘。2.
  • LPC1114/LPC11U14和LPC1343對比學習(四)定時器
    這三種晶片都有2個16位的定時器和2個32位的定時器。這4個定時器的功能都非常強大,不在是像8051一樣,只有定時與計數功能。除了這兩個強大的功能外,還添加了匹配輸出,捕獲輸入,PWM輸出等。在這裡我們只學習它們最基本的定時功能,對於其他功能就不作介紹。
  • STM32 串口功能 庫函數 詳解和DMA 串口高級運用(轉載)
    硬體怎麼連接出發,當然對於stm32還要熟悉庫函數的功能具起來rs232和485電平的區別硬體外圍晶片,波特率(反映傳一位的時間),起始位和停止位,數據寬度,校驗,硬體流控制,相應連接電腦時的接口怎麼樣的。配置,使用函數,中斷,查詢並結合通信協議才算了解了串口使用。
  • STM32第七章-脈衝寬度調製
    另外 CC4S 用於設置通道的方向(輸入/輸出)默認設置為00,就是設置通道作為輸出使用。捕獲/比較使能寄存器見名知意,當然是使能TIM3定時器的啊。使CC4E置位為1就可以了。捕獲/比較寄存器該寄存器總共有 4 個,對應 4 個通道 CH1~4。我們使用的是通道3。在輸出模式下,該寄存器的值與 CNT 的值比較,根據比較結果產生相應動作。
  • 使用Python從頭開始實現深度學習庫
    為此,可能需要將核心實現單元隱藏在幾個抽象層後面,這使得難以理解深度學習庫所基於的基本底層原理。因此,本文的目的是提供有關深度學習庫構建塊的見解。我們首先了解一些深度學習的背景知識,以了解功能要求,然後使用NumPy在python中使用一個簡單而完整的庫,該庫能夠端到端訓練神經網絡模型(非常簡單的類型)。在此過程中,我們將學習深度學習框架的各個組成部分。該庫不到100行代碼,因此應該很容易遵循。
  • STM32四種庫對比:寄存器、標準外設庫、HAL、LL
    https://www.st.com/en/embedded-software/stm32snippets.html (公號不支持外連結,請複製連結到瀏覽器打開) 相信學習過STM32的朋友,對標準外設庫都不陌生,是一組外圍設備的C語言代碼集合。
  • 用ULN2003驅動24BYJ48步進電機時,怎麼接stm32單片機比較好?
    stm32單片機是一種高性能、低成本、低功耗的單片機,可以說很多應用場合都會用到,特別是對於大型系統,像電源、充電樁、交互機、電機驅動、PLC、逆變器、印表機、掃描儀、警報系統、視頻電話、 HVAC 等。那麼對於如何用STM32驅動步進電機呢?
  • MSP430 定時器輸出PWM波形
    定時器的PWM輸出有有8種模式:輸出模式0  輸出模式:輸出信號OUTx由每個捕獲/比較模塊的控制寄存器CCTLx中的OUTx位定義,並在寫入該寄存器後立即更新。最終位OUTx直通。 輸出模式1 置位模式:輸出信號在TAR等於CCRx時置位,並保持置位到定時器復位或選擇另一種輸出模式為止。
  • 單片機中各種周期的關係與定時器原理
    四個獨立的通道可以用於:  (1)輸入捕獲  (2)輸出比較  (3)產生PWM(邊緣或中心對齊模式)  (4)單脈衝輸出  配置為16位標準定時器時,它與TIMX定時器具有相同的功能。配置為16位PWM發生器時,它具有全調製能力(0~100%)。