一、簡介:
1.名稱:
IC,輸入捕獲
2.電路:
如圖為通用定時器框圖,下半部分的左半模塊,與輸出比較部分共用捕獲/比較寄存器與引腳。
3.功能:
當通道輸入引腳出現電平跳變時,當前CNT的值,寫入CCR中。
4.框圖:
信號先進入濾波器,其中ICF寄存器為濾波器參數,數值越大,濾波效果越好
隨后進入邊沿檢測器,用于檢測上升沿和下降沿,隨后CC1P寄存器,可控制極性。
隨后信號來到一個數據選擇器,可選擇輸出到捕獲/比較寄存器1的信號來自通道1還是通道2,實際上,輸入通道1.2與寄存器1.2是交叉的,即通道1的信號可以同時傳給寄存器1和2,通道2也可以。
寄存器ICPS位,用于控制分頻器,CC1E位,用于控制輸出使能或失能。
主從觸發模式:注意到TI1FP1信號,可以鏈接到從模式控制器,接下來介紹。
5.主從觸發模式:
主模式:定時器信號,通過TRGO引腳,控制其他外設。
從模式:外來信號,通過TRGI引腳,控制定時器。
二、頻率測量方法:
1.測頻法:在閘門時間T內,對上升沿計次為N,f = N/T,適用高頻信號
2.測周法,在兩個上升沿內,以標準頻率fc計次,得到N,f = fc/N,適用低頻信號
三、實戰:頻率測量
1.思路:
運用測周法測頻率,讓CNT以一定頻率計數,當上升沿到來后,CNT的數值記錄到CCR中,隨后將CNT清零(使用主從觸發模式,觸發源選擇TI1FP1,從模式選擇Reset功能)。
CCR的值,就是N,CNT的時鐘頻率,就是fc,f = fc/N。
2.功能圖:
3.代碼:IC.c
用PA0輸出PWM信號,用PA6(定時器3的通道1)做輸入捕獲。
#include "stm32f10x.h" // Device header/*** 函 數:輸入捕獲初始化* 參 數:無* 返 回 值:無*/
void IC_Init(void)
{/*開啟時鐘*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //開啟TIM3的時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //開啟GPIOA的時鐘/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure); //將PA6引腳初始化為上拉輸入/*配置時鐘源*/TIM_InternalClockConfig(TIM3); //選擇TIM3為內部時鐘,若不調用此函數,TIM默認也為內部時鐘/*時基單元初始化*/TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; //定義結構體變量TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //時鐘分頻,選擇不分頻,此參數用于配置濾波器時鐘,不影響時基單元功能TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //計數器模式,選擇向上計數TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1; //計數周期,即ARR的值,越大越好TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1; //預分頻器,即PSC的值,此處1MHzTIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重復計數器,高級定時器才會用到TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure); //將結構體變量交給TIM_TimeBaseInit,配置TIM3的時基單元/*輸入捕獲初始化*/TIM_ICInitTypeDef TIM_ICInitStructure; //定義結構體變量TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; //選擇配置定時器通道1TIM_ICInitStructure.TIM_ICFilter = 0xF; //輸入濾波器參數,可以過濾信號抖動TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //極性,選擇為上升沿觸發捕獲TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //捕獲預分頻,選擇不分頻,每次信號都觸發捕獲TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //輸入信號交叉,選擇直通,不交叉TIM_ICInit(TIM3, &TIM_ICInitStructure); //將結構體變量交給TIM_ICInit,配置TIM3的輸入捕獲通道/*選擇觸發源及從模式*/TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1); //觸發源選擇TI1FP1TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset); //從模式選擇復位//即TI1產生上升沿時,會觸發CNT歸零/*TIM使能*/TIM_Cmd(TIM3, ENABLE); //使能TIM3,定時器開始運行
}/*** 函 數:獲取輸入捕獲的頻率* 參 數:無* 返 回 值:捕獲得到的頻率*/
uint32_t IC_GetFreq(void)
{return 1000000 / (TIM_GetCapture1(TIM3) + 1); //測周法得到頻率fx = fc / N,這里不執行+1的操作也可
}
四、實戰:占空比測量
1.PWMI模式:
兩個通道,同時捕獲一個引腳,一個配置為上升沿觸發, 另一個配置為下降沿觸發,即可同時測量頻率與占空比,占空比=CCR1/CCR2。
2.功能圖:
3.代碼:新IC.c
#include "stm32f10x.h" // Device header/*** 函 數:輸入捕獲初始化* 參 數:無* 返 回 值:無*/
void IC_Init(void)
{/*開啟時鐘*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //開啟TIM3的時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //開啟GPIOA的時鐘/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure); //將PA6引腳初始化為上拉輸入/*配置時鐘源*/TIM_InternalClockConfig(TIM3); //選擇TIM3為內部時鐘,若不調用此函數,TIM默認也為內部時鐘/*時基單元初始化*/TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; //定義結構體變量TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //時鐘分頻,選擇不分頻,此參數用于配置濾波器時鐘,不影響時基單元功能TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //計數器模式,選擇向上計數TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1; //計數周期,即ARR的值TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1; //預分頻器,即PSC的值TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重復計數器,高級定時器才會用到TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure); //將結構體變量交給TIM_TimeBaseInit,配置TIM3的時基單元/*PWMI模式初始化*/TIM_ICInitTypeDef TIM_ICInitStructure; //定義結構體變量TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; //選擇配置定時器通道1TIM_ICInitStructure.TIM_ICFilter = 0xF; //輸入濾波器參數,可以過濾信號抖動TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //極性,選擇為上升沿觸發捕獲TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //捕獲預分頻,選擇不分頻,每次信號都觸發捕獲TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //輸入信號交叉,選擇直通,不交叉TIM_PWMIConfig(TIM3, &TIM_ICInitStructure); //將結構體變量交給TIM_PWMIConfig,配置TIM3的輸入捕獲通道//此函數同時會把另一個通道配置為相反的配置,實現PWMI模式/*選擇觸發源及從模式*/TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1); //觸發源選擇TI1FP1TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset); //從模式選擇復位//即TI1產生上升沿時,會觸發CNT歸零/*TIM使能*/TIM_Cmd(TIM3, ENABLE); //使能TIM3,定時器開始運行
}/*** 函 數:獲取輸入捕獲的頻率* 參 數:無* 返 回 值:捕獲得到的頻率*/
uint32_t IC_GetFreq(void)
{return 1000000 / (TIM_GetCapture1(TIM3) + 1); //測周法得到頻率fx = fc / N,這里不執行+1的操作也可
}/*** 函 數:獲取輸入捕獲的占空比* 參 數:無* 返 回 值:捕獲得到的占空比*/
uint32_t IC_GetDuty(void)
{return (TIM_GetCapture2(TIM3) + 1) * 100 / (TIM_GetCapture1(TIM3) + 1); //占空比Duty = CCR2 / CCR1 * 100,這里不執行+1的操作也可
}