目錄
一、知識點(diǎn)
1、IC(Input Capture)輸入捕獲
2、通用定時(shí)器結(jié)構(gòu)
(1)輸出比較的執(zhí)行邏輯
(2)四個(gè)輸入捕獲和輸出比較通道
(3)輸入捕獲的執(zhí)行流程和輸出比較的區(qū)別
(4)輸入捕獲的作用
(5)輸入捕獲通道
(6)PWMI模式:同時(shí)測量頻率和占空比
(7)主從觸發(fā)模式:實(shí)現(xiàn)硬件全自動測量
3、測頻法和測周法測量頻率
(1)測頻法和測周法的原理
(2)測頻法和測周法的選擇
(3)測頻法和測周法的比較
(4)測頻法和測周法的實(shí)現(xiàn)
4、主從觸發(fā)模式
5、結(jié)構(gòu)
(1)捕獲輸出基本結(jié)構(gòu)
(2)PWMI基本結(jié)構(gòu)
二、輸入捕獲模式測頻率
1、原理圖
2、改變PWM頻率
3、單獨(dú)修改PSC的函數(shù)
4、設(shè)置1000HZ,占空比為50%
5、工作步驟
6、CCR
7、 代碼
(1)IC.c
(2)mian.c
三、PWMI模式頻率占空比1、IC.c中不一樣的地方
2、IC.c
3、main.c
四、知識點(diǎn)
測頻率的性能
一、知識點(diǎn)
?TIM輸入捕獲模式:
1、輸入捕獲模式測頻率占空比信號源:產(chǎn)生一個(gè)頻率和占空比可調(diào)的波形
無信號發(fā)生器的情況:先用PWM模塊,在PA0端口輸出一個(gè)頻率和占空比可調(diào)的波形,把PA0和PA6連在一起,PA6為輸入波形,這樣就是測量自己PWM模塊產(chǎn)生波形的頻率
在顯示屏上顯示PA6的頻率
2、PWMI模式測頻率吧占空比
1、IC(Input Capture)輸入捕獲
輸入捕獲模式下,當(dāng)通道輸入引腳出現(xiàn)指定電平跳變時(shí),當(dāng)前CNT的值將被鎖存到CCR中(即把當(dāng)前CNT的值讀出來,寫入到CCR中)
2、通用定時(shí)器結(jié)構(gòu)
(1)輸出比較的執(zhí)行邏輯
????????根據(jù)CNT和CCR的關(guān)系,從通道引腳輸出高低電平
(2)四個(gè)輸入捕獲和輸出比較通道
????????共用4個(gè)CCR寄存器,其CH1到CH4也是共用的,故對于同一個(gè)定時(shí)器,輸入捕獲和輸出比較,只能使用一個(gè),不能同時(shí)使用
(3)輸入捕獲的執(zhí)行流程和輸出比較的區(qū)別
????????輸出比較:引腳是輸出端口,根據(jù)CNT和CCR的大小關(guān)系來執(zhí)行輸出動作
????????輸入捕獲:引腳是輸入端口,接收到輸入信號,執(zhí)行CNT鎖存到CCR的動作
(4)輸入捕獲的作用
????????測量PWM波形的頻率、占空比、脈沖間隔(和頻率差不多意思)、電平持續(xù)時(shí)間(和占空比差不多意思)等參數(shù)
(5)輸入捕獲通道
????????每個(gè)高級定時(shí)器和通用定時(shí)器都擁有4個(gè)輸入捕獲通道,且高級和通用定時(shí)器都沒有什么區(qū)別,基本定時(shí)器沒有輸入捕獲的功能
(6)PWMI模式:同時(shí)測量頻率和占空比
????????PWMI模式是PWM的輸入模式,專門為測量PWM頻率和占空比設(shè)計(jì)的。
(7)主從觸發(fā)模式:實(shí)現(xiàn)硬件全自動測量
注意:(6)、(7)結(jié)合起來,測量頻率占空比就是硬件全自動執(zhí)行,軟件不需要進(jìn)行任何干預(yù),也不需要進(jìn)中斷,需要測量時(shí)直接讀取CCR寄存器的值即可,方便+減輕軟件的壓力
3、測頻法和測周法測量頻率
(1)測頻法和測周法的原理
測頻率法:定義一個(gè)T,如1s,在1s的時(shí)間內(nèi),有多少個(gè)周期,就是多少HZ
測周法:周期的倒數(shù)就是頻率,測出一個(gè)周期的時(shí)間,再取倒數(shù),就是頻率(測量時(shí)間的方法:定時(shí)器計(jì)次,使用一個(gè)已知頻率fc的計(jì)次時(shí)鐘,來驅(qū)動計(jì)數(shù)器,從一個(gè)上升沿開始計(jì),計(jì)數(shù)器從0開始,一直計(jì)到下一個(gè)上升沿,停止,計(jì)一個(gè)數(shù)的時(shí)間是1/fc,計(jì)N個(gè)數(shù),時(shí)間就是N/fc,N/fc就是周期,再取一個(gè)倒數(shù),就得到公式fx=fc/N)
中界頻率:測頻率法的N=測周法的N,兩者誤差相等。
(2)測頻法和測周法的選擇
此時(shí),當(dāng)待測信號小于中界頻率時(shí),用測周法,當(dāng)大于中界頻率時(shí),用測頻法
(3)測頻法和測周法的比較
測頻法適合高頻信號(因?yàn)槿鬘很小,誤差會很大),若閘門時(shí)間選為1s,那么每隔1s才能出結(jié)果,結(jié)果比較慢
測周法適合測量低頻信號(周期比較長,計(jì)次就會比較多,有助于減少誤差),測一個(gè)周期就能出現(xiàn)結(jié)果,而一般待測信號頻率都比較大,故結(jié)果更新較快
(4)測頻法和測周法的實(shí)現(xiàn)
a、測頻法的思路:之前的對射式紅外傳感器計(jì)次計(jì)次,每來一個(gè)上升沿計(jì)次1,再用有一個(gè)定時(shí)器,每隔1s中斷,再中斷中,每隔1s取一次計(jì)次值,同時(shí)清0計(jì)次,為下一次做準(zhǔn)備,這樣每次讀取的計(jì)次值就是頻率
定時(shí)器外部時(shí)鐘也同理,每隔1s取一次計(jì)次,就能實(shí)現(xiàn)
b、測周法:測量兩個(gè)上升沿的時(shí)間(見本次代碼)
4、主從觸發(fā)模式
- 主從觸發(fā)模式就是主模式、從模式、觸發(fā)源選擇三個(gè)的簡稱
- 主模式:可以將定時(shí)器內(nèi)部的信號,映射到TRGO引腳,用于觸發(fā)別的外設(shè)?
- 從模式:接受其他外設(shè)或者自身外設(shè)的一些信號,用于控制自身定時(shí)器的運(yùn)行,也就是被別的信號控制
- 觸發(fā)源選擇:選擇從模式的觸發(fā)信號源,可以認(rèn)為是從模式的一部分,選擇指定的一個(gè)信號,得到TRGI,TRGI可以取觸發(fā)從模式,從模式可以在上述右圖列表中,選擇一項(xiàng)操作來自動執(zhí)行
?若想讓TI1FP1信號自動觸發(fā)CNT清零,觸發(fā)源一個(gè)選擇TI1FP1,從模式選擇執(zhí)行Reset的操作,這樣TI1FP1信號就可以自動觸發(fā)從模式,從模式自動清零CNT,實(shí)現(xiàn)硬件全自動測量
5、結(jié)構(gòu)
(1)捕獲輸出基本結(jié)構(gòu)
- 只使用一個(gè)通道
- 時(shí)基單元:CNT(測周法用來計(jì)數(shù)計(jì)時(shí))會在預(yù)分頻之后的時(shí)鐘驅(qū)動下,不斷自增 。經(jīng)過預(yù)分頻后時(shí)鐘頻率會驅(qū)動CNT的標(biāo)準(zhǔn)頻率fc,標(biāo)準(zhǔn)頻率=72M/預(yù)分頻系數(shù)
- 輸入捕獲通道1的GPIO口輸入方波信號,經(jīng)過濾波器和邊沿檢測,選擇TI1FP1為上升沿觸發(fā),選擇直連的通道,分頻器選擇不分頻,當(dāng)TI1FP1出現(xiàn)上升沿后,,CNT的當(dāng)前計(jì)數(shù)值轉(zhuǎn)運(yùn)到CCR1中,同時(shí)觸發(fā)源選擇,選中TI1FP1為觸發(fā)信號,從模式選擇復(fù)位操作,這樣TI1FP1的上升沿,也會通過觸發(fā)源選擇——從模式RESRT這條路去觸發(fā)CNT清零
- 順序:先轉(zhuǎn)運(yùn)CNT的值到CCR中,再觸發(fā)從模式給CNT清零,或者是非阻塞的同時(shí)轉(zhuǎn)移,CNT的值轉(zhuǎn)移到CCR,同時(shí)0轉(zhuǎn)移到CNT中去(先捕獲,在清零)
- CCR1值為N,fc/N就可以得到頻率
- 頻率過低,CNT(最大65535)可能會溢出?
(2)PWMI基本結(jié)構(gòu)
占空比:CCR2/CCR1?
二、輸入捕獲模式測頻率
1、原理圖
2、改變PWM頻率
? PWM 頻率: ? Freq = CK_PSC / (PSC + 1) / (ARR + 1)? PWM 占空比: ? Duty = CCR / (ARR + 1)? PWM 分辨率: ? Reso = 1 / (ARR + 1)CK_PSC為72M,PSC為預(yù)分頻器,ARR為自動重裝器,CCR為捕獲/比較器改變PSC和ARR都可以調(diào)節(jié)頻率,但改變ARR調(diào)節(jié)頻率會影響到占空比,所以選擇PSC調(diào)節(jié)頻率
??? TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;?? ??? ?//ARR
?? ?TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;?? ??? ?//PSC
?? ?TIM_OCInitStructure.TIM_Pulse = 0;?? ??? ?//CCR
這代碼中,因?yàn)锳RR=100,所以CCR的值為占空比(該電平在周期的比例)
?3、單獨(dú)修改PSC的函數(shù)
void PWM_SetPrescaler(uint16_t Prescaler)
{
//第三個(gè)參數(shù)指定定時(shí)器預(yù)分屏器的重裝模式
//第一個(gè) TIM_PSCReloadMode_Update,預(yù)分頻器在更新事件重裝//等待周期結(jié)束
// 第二個(gè)TIM_PSCReloadMode_Immediate預(yù)分頻器立即重裝//可能一個(gè)周期沒結(jié)束就切換
TIM_PrescalerConfig(TIM2, Prescaler, TIM_PSCReloadMode_Immediate);
}
4、設(shè)置1000HZ,占空比為50%
PWM_SetPrescaler(720 - 1); //Freq = 72M / (PSC + 1) / 100 //1000hz
PWM_SetCompare1(50); //Duty = CCR / 100 //占空比為50%
5、工作步驟
- 第一步:RCC開啟時(shí)鐘,打開GPIO和TMI的時(shí)鐘
- 第二步:GPIO初始化,配置成輸入模式,一般選擇上拉輸入或者浮空輸入模式
- 第三步:配置時(shí)基單元,讓CNT計(jì)數(shù)器在內(nèi)部時(shí)鐘的驅(qū)動下自增運(yùn)行
- 第四步:配置輸入捕獲單元,包括濾波器、級聯(lián)、直聯(lián)通道還是交叉通道、分頻器等參數(shù),用結(jié)構(gòu)體統(tǒng)一進(jìn)行配置
- 第五步:選擇重模式的觸發(fā)源,觸發(fā)源選擇為TI1FP1(此處調(diào)用一個(gè)庫函數(shù),給個(gè)參數(shù)即可)
- 第六步:選擇觸發(fā)之后執(zhí)行的操作:執(zhí)行RESET操作(調(diào)用庫函數(shù))
- 最后,調(diào)用TIM_CMD函數(shù)開啟定時(shí)器
想要獲取一個(gè)周期的頻率時(shí),直接讀取CCR計(jì)算器,然后按照fc除N計(jì)算即可(fc,標(biāo)準(zhǔn)頻率=72M/預(yù)分頻系數(shù))
6、CCR
輸入捕獲模式下:CCR是只讀的,要用GetCapture讀出文章來源:http://www.zghlxwxcb.cn/news/detail-549699.html
輸出比較模式下:CCR是只寫的,要用SetCompare1文章來源地址http://www.zghlxwxcb.cn/news/detail-549699.html
7、 代碼
(1)IC.c
#include "stm32f10x.h" // Device header
void IC_Init(void)
{
//TIM3
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//PA6
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_InternalClockConfig(TIM3);//TIM3
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上計(jì)數(shù)
TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1; //ARR最好大一些,防止溢出
TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1; //PSC這個(gè)值決定了測周法的標(biāo)準(zhǔn)頻率fc=1M
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);//TIM3
//第四步:配置輸入捕獲單元
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;//選擇通道1
TIM_ICInitStructure.TIM_ICFilter = 0xF;//數(shù)越大,濾波效果越好,濾波器計(jì)次不會改變信號原有的頻率,一般濾波器的采樣頻率會遠(yuǎn)高于信號頻率
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;//上升沿觸發(fā)
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;//分頻器對信號本身進(jìn)行計(jì)次,會改變頻率。此處不分頻
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//直連通道
TIM_ICInit(TIM3, &TIM_ICInitStructure);
//第五步:選擇重模式的觸發(fā)源
TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);
//選擇觸發(fā)之后執(zhí)行的操作
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
//使能
TIM_Cmd(TIM3, ENABLE);
}
uint32_t IC_GetFreq(void)
{
//fc除N(fc,標(biāo)準(zhǔn)頻率=72M/預(yù)分頻系數(shù))
return 1000000 / (TIM_GetCapture1(TIM3) + 1);
}
(2)mian.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"
#include "IC.h"
int main(void)
{
OLED_Init();
PWM_Init();
IC_Init();
OLED_ShowString(1, 1, "Freq:00000Hz");
PWM_SetPrescaler(720 - 1); //Freq = 72M / (PSC + 1) / 100 //1000hz
PWM_SetCompare1(50); //Duty = CCR / 100 //占空比為50%
while (1)
{
OLED_ShowNum(1, 6, IC_GetFreq(), 5);
}
}
三、PWMI模式頻率占空比 1、IC.c中不一樣的地方
//該函數(shù)會自動把剩下的一個(gè)通道初始化成相反的配置,第一個(gè)是通道1,直連、上升沿
//第二個(gè)是通道2,交叉、下降沿
TIM_PWMIConfig(TIM3, &TIM_ICInitStructure);
uint32_t IC_GetDuty(void)
{
return (TIM_GetCapture2(TIM3) + 1) * 100 / (TIM_GetCapture1(TIM3) + 1);
}
2、IC.c
#include "stm32f10x.h" // Device header
void IC_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
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);
TIM_InternalClockConfig(TIM3);
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_ICInitTypeDef TIM_ICInitStructure;
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
TIM_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;
//該函數(shù)會自動把剩下的一個(gè)通道初始化成相反的配置,第一個(gè)是通道1,直連、上升沿
//第二個(gè)是通道2,交叉、下降沿
TIM_PWMIConfig(TIM3, &TIM_ICInitStructure);
TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
TIM_Cmd(TIM3, ENABLE);
}
uint32_t IC_GetFreq(void)
{
return 1000000 / (TIM_GetCapture1(TIM3) + 1);
}
uint32_t IC_GetDuty(void)
{
return (TIM_GetCapture2(TIM3) + 1) * 100 / (TIM_GetCapture1(TIM3) + 1);
}
3、main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"
#include "IC.h"
int main(void)
{
OLED_Init();
PWM_Init();
IC_Init();
OLED_ShowString(1, 1, "Freq:00000Hz");
OLED_ShowString(2, 1, "Duty:00%");
PWM_SetPrescaler(720 - 1); //Freq = 72M / (PSC + 1) / 100
PWM_SetCompare1(50); //Duty = CCR / 100
while (1)
{
OLED_ShowNum(1, 6, IC_GetFreq(), 5);
OLED_ShowNum(2, 6, IC_GetDuty(), 2);
}
}
四、知識點(diǎn)
測頻率的性能
- 測頻率的范圍:目前給標(biāo)準(zhǔn)頻率1MHZ時(shí),計(jì)數(shù)器最大只能到65535,所以測量的最低頻率是1M/65535,大概是15HZ,若頻率再低,則溢出,此時(shí)可以增大預(yù)分屏,就可以使得標(biāo)準(zhǔn)頻率更低
- 測量的最高頻率沒有上限,但是頻率越大,誤差越大。如果非要找一個(gè)頻率上限,就是1MHZ,因?yàn)槌^標(biāo)準(zhǔn)頻率,時(shí)誤差非常大
- 如果要求誤差等于1/1,000時(shí),頻率為上限,則這個(gè)上限就是1兆除1,000=1,000HZ
- 如果要求誤差可以到1%,那頻率上限就是1MHZ除100=10KHZ
- 如果想提高頻率的上限,就要把PSC給降低一些,提高標(biāo)準(zhǔn)頻率,上限制就會提高
- 若要更高的頻率,則用測頻法
到了這里,關(guān)于11、江科大stm32視頻學(xué)習(xí)筆記——輸入捕獲模式測頻率、PWMI模式測頻率占空比的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!