輸入捕獲模式可以用來測量脈沖寬度或者測量頻率。STM32 的定時器,除了 TIM6 和 TIM7,其他定時器都有輸入捕獲功能。STM32 的輸入捕獲,簡單地說就是通過檢測 TIMx_CHx 上的邊沿信號,在邊沿信號發生跳變(比如上升沿/下降沿)的時候,將當前定時器的值(TIMx_CNT)存放到對應的通道的捕獲/比較寄存器(TIMx_CCRx)中。
1. 相關寄存器介紹
1) 捕獲/比較模式寄存器 (TIMx_CCMRx)
當在輸入捕獲模式下使用的時候,對應上圖的第二行描述,從圖中可以看出,TIMx_CCMR1 明顯是針對 2 個通道的配置,低八位[7:0]用于捕獲/比較通道 1 的控制,而高八位[15:8]則用于捕獲/比較通道 2 的控制。同理,CCMR2 這個寄存器用來控制通道 3 和通道 4。今天的實驗,我們用到的是 TIM5 的捕獲/比較通道 1。
(1)CC1S[1:0],這兩個位用于 CCR1 的通道配置,這里我們設置 CC1S[1:0]=01,也就是配置 IC1 映射在 TI1 上。如果不理解沒有關系,看圖就知道了。
從圖中可以知道,IC1有三個輸入源,分別是TI1,TI2,TRC。
TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; 這是通過庫函數配置,映射到TI1。
頭文件(stm32f10x_tim.h)定義如下:
#define TIM_ICSelection_DirectTI ((uint16_t)0x0001)
#define TIM_ICSelection_IndirectTI ((uint16_t)0x0002)
#define TIM_ICSelection_TRC ((uint16_t)0x0003)
(2)IC1F[3:0]
表格中的f_ck_int 是定時器的輸入頻率(TIMxCLK),f_dts 則是根據 TIMx_CR1 的 CKD[1:0]來確定。
上圖就是TIMx_CR1寄存器。
#define TIM_CKD_DIV1 ((uint16_t)0x0000)
#define TIM_CKD_DIV2 ((uint16_t)0x0100)
#define TIM_CKD_DIV4 ((uint16_t)0x0200)
假定選IC1F[3:0]=0101,即采樣頻率為fDTS/2, N=8;
選CKD[1:0]=01,即 tDTS = 2 × tCK_INT;并假定 fCK_INT=72MHz。
這時可以算出,采樣頻率為72MHz/2/2=18MHz.
1/(18MHz)*8 = 0.4444us = 444.4ns.
因為N=8,所以濾波器可以濾除掉輸入端小于444.4ns的脈沖。
“數字濾波器由一個事件計數器組成,它記錄到N個事件后會產生一個輸出的跳變”,這句話可以這樣理解:
當濾波器連續采樣到N個有效電平時,就輸出這個有效電平。
當濾波器沒有連續采樣到N個有效電平時,再從0開始計數,輸出一直保持上一次輸出的有效電平。
例如:濾波器上一次輸出是高電平,本次連續采樣到(N-1)個高電平,但第N個是個低電平,那么濾波器仍然保持上次輸出的高電平,并重新開始計數,記錄1次低電平,如果其后采樣的(N-1)個也是低電平,此時濾波才輸出低電平,于是一個下降沿才出現在IC1上。
(3)IC1PSC[1:0]
這里的“事件”指的是上升沿或者下降沿,具體是哪個由TIMx_CCER寄存器的CCxP位決定。
2)捕獲/比較使能寄存器:TIMx_CCER
所以,要使能輸入捕獲,必須設置 CC1E=1,而 CC1P 則根據自己的需要來配置(捕獲發生在上升沿還是下降沿)。
3) DMA/中斷使能寄存器(TIMx_DIER)
在實驗中,我們需要允許位0和位1的中斷。
#define TIM_IT_Update ((uint16_t)0x0001)
#define TIM_IT_CC1 ((uint16_t)0x0002)
#define TIM_IT_CC2 ((uint16_t)0x0004)
#define TIM_IT_CC3 ((uint16_t)0x0008)
#define TIM_IT_CC4 ((uint16_t)0x0010)
對應的庫函數是:TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);
4) 捕獲/比較寄存器 (TIMx_CCRx)
該寄存器用來存儲捕獲發生時,TIMx_CNT的值,我們從 TIMx_CCR1 就可以讀出通道 1 捕獲發生時刻的 TIMx_CNT 值,通過兩次捕獲(一次上升沿捕獲,一次下降沿捕獲)的差值,就可以計算出高電平脈沖的寬度。
2. 實驗設計
通過TIM3產生一路PWM(從PB5輸出),把PB5連接到PA0上,PA0和 TIM5_CH1是同一個管腳。利用TIM5_CH1的輸入捕獲功能,測量出PWM的寬度。
3. 參考代碼
[cpp] view plain copy
//TIM5_CH1輸入捕獲配置
void TIM5_Cap_Init(u16 arr,u16 psc)
{
TIM_ICInitTypeDef TIM5_ICInitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); //使能TIM5時鐘
//TIM5的配置
TIM_TimeBaseStructure.TIM_Period = arr; //重裝載值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //分頻系數
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //tDTS = tCK_INT
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上計數
TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);
//TIM5輸入捕獲配置
TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1; //我們用通道1
TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕獲
TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1
TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //無預分頻器
TIM5_ICInitStructure.TIM_ICFilter = 0x00; //IC1F=0000 ,無濾波器
TIM_ICInit(TIM5, &TIM5_ICInitStructure);
//中斷優先級配置
NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);//打開更新中斷和捕獲中斷
TIM_Cmd(TIM5,ENABLE ); //使能定時器5
}
[cpp] view plain copy
#define START 0X01
#define WAIT_RISING 0X02
#define WAIT_FALLING 0X03
u16 TIM5CH1_CAPTURE_VAL; //輸入捕獲值
u32 a[500] = {0}; //存放電平寬度
u32 i = 0; //數組下標
u8 overflow = 0; //記錄定時器更新中斷的次數
u8 state = START;
//定時器5中斷服務程序
void TIM5_IRQHandler(void)
{
if(i<500)
{
if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET)
{
++overflow;
}
if (TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET)//捕獲事件
{
if(state == START) //初始狀態
{
overflow = 0;
TIM_SetCounter(TIM5,0);
state = WAIT_FALLING;
TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling); //設置為下降沿捕獲
}
else if(state == WAIT_RISING) //等待上升沿
{
TIM5CH1_CAPTURE_VAL = TIM_GetCapture1(TIM5);
a[i++] = TIM5CH1_CAPTURE_VAL + overflow*65536;
overflow = 0;
TIM_SetCounter(TIM5,0);
state = WAIT_FALLING;
TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling); //設置為下降沿捕獲
}
else // wait falling
上一篇:深入分析MCU堆棧的作用,以及該如何設置堆棧大小
下一篇:Stm32用寄存器還是庫函數
推薦閱讀最新更新時間:2025-04-24 06:53





設計資源 培訓 開發板 精華推薦
- PCAL6534EV 34位通用IO Arduino? Shield擴展板
- 使用 LT3045IDD PGFB 禁用且無反向輸入保護的典型應用
- 最小的麥金塔-天氣時鐘
- 濕敏傳感器(設計方案+原理圖+程序+芯片資料)
- LTC3829EUHF 演示板、3 相、同步穩壓器和差分放大器
- DC1893A、LT3697EMSE 演示板,8V = VIN = 35V,VOUT = 5V,2.4A
- OP213ESZ-REEL 超低噪聲、單電源儀表放大器的典型應用
- FRDM-KL27Z: 面向Kinetis? KL17和KL27 MCU的Freedom?開發平臺
- L7806C 可調輸出穩壓器的典型應用(7 至 30 V)
- KITFS84AUTEVM: FS84 QFN48EP Safety SBC編程板
- Factorial 汽車尺寸固態電池 FEST 獲 Stellantis 聯合驗證:375Wh/kg 能量密度
- 英特爾代工業務醞釀逆襲,18A 制程獲英偉達等巨頭青睞
- 今年車展,那些正在崛起的中國芯片
- 高通攜手中國“汽車朋友圈”亮相2025上海車展: 加速駕駛輔助普惠,推動艙駕創新升級
- 工業市場正在快速回暖,德州儀器如何重塑電力電子市場?
- 特斯拉:美國交付的Model Y/3電池包已實現100%美國生產
- 地平線與博世深化合作,攜手為多家車企提供輔助駕駛產品
- 強化中國市場戰略布局,德州儀器正靈活應對全球關稅挑戰
- Molex莫仕通過本地合作和創新加強支持中國汽車行業
- 貿澤開售Texas Instruments適用于高分辨率AR HUD的 全新DLP4620S-Q1 0.46"汽車數字微鏡器件