柚子快報邀請碼778899分享:Stm32的定時器
柚子快報邀請碼778899分享:Stm32的定時器
?定時器分類:
? ? ? ? ①高級定時器(功能最全)(Stm32的TIM1、TIM8)(掛載在APB2總線上)
? ? ? ? ? ? ? ? :通用定時器+重復計數(shù)器、死區(qū)生成、互補輸出、剎車輸入
? ? ? ? ②通用定時器(最常用)(Stm32的TIM2、TIM3、TIM4、TIM5)(掛載在APB1總線上)
? ? ? ? ? ? ? ? :基本定時器+內(nèi)外時鐘源選擇、輸入捕獲、輸出比較、編碼器接口、主從觸發(fā)模式
? ? ? ? ③基本定時器(Stm32的TIM6、TIM7)(掛載在APB1總線上)
? ? ? ? ? ? ? ? :只有定時中斷、DAC功能。也就是最基本的傳感器所用的定時器就是這種
StmF103C8T6的定時器資源:TIM1、TIM2、TIM3、TIM4(1高3通)
Stm定時器的功能:
? ? ? ? ①定時中斷(+內(nèi)外部時鐘源選擇)
? ? ? ? ②輸出比較(PWM—>電機)
? ? ? ? ③輸入捕獲(測輸入的PWM的頻率、占空比)
? ? ? ? ④編碼器接口(?)
? ? ? ? ⑤主從觸發(fā)模式
Stm32定時器的時基單元:
? ? ? ? ①16位的CNT計數(shù)器(CRR,產(chǎn)生一次中斷所需要的計數(shù)值)
? ? ? ? ②16的PSC預分頻器(系統(tǒng)時鐘/預分頻 = 時鐘頻率)
? ? ? ? ②16位的自動重裝計數(shù)器(每次循環(huán)的計數(shù)值)
???????????????????????????????????????????????????????????????????????????(主頻)? ?/? ?(預分頻)? / (計數(shù)器)
2^16 = 65536 ,所以最小中斷頻率Small-Hz是72 000 000 / 65535?/ 65535
所以最大中斷時間是 T = 1 / Hz = 1 /72 000 000 / 65535 / 65535?=?59.650503125 ≈59.65s
級聯(lián):
????????Stm32的定時器可以級聯(lián),也就是A定時器的輸出作為B定時器的輸入。
時鐘信息流向(自己編的名字):
RCC(復位時鐘控制器)—(觸發(fā)控制器)—>PSC預分頻器——>CNT計數(shù)(當CNT==自動重裝計數(shù)器,會產(chǎn)生中斷信號,自動重裝計數(shù)器會重置CNT)
CNT計數(shù)器:
? ? ? ? 向上計數(shù),等于ARR時產(chǎn)生中斷
? ? ? ? 向下計數(shù),等于0是產(chǎn)生中斷
? ? ? ? 中央對齊計數(shù),等于ARR或0時產(chǎn)生中斷
中斷:
????????先經(jīng)過中斷控制(是否開啟/允許中斷),再去向NVIC(中斷通路、優(yōu)先級)
? ? ? ? ①更新中斷:會通向NVIC,在NVIC配置了優(yōu)先級與中斷通路之后,CPU才能響應中斷。
? ? ? ? ②更新事件:
????????????????可以觸發(fā)其他電路的工作,映射到RTGO上,TRGO可以直接連接到某個引腳進行控制。硬件自動化。
????????????????TRGO也可以連接其他定時器,定時器被其他定時器輸入的引腳是ITRx引腳,不同定時器的x值不同(下圖),且不是數(shù)值剛好對應(定時器1對應ITR1)的情況。稱為定時器級聯(lián)。
定時器的部分說明:
? ? ? ? ①基本定時器只能選擇內(nèi)部時鐘
? ? ? ? ②通用和高級定時器可以選擇外部時鐘ERT(),也就是可以讓一個ETR引腳接收方波信號來模擬時鐘的高低電平,但是這需要配置內(nèi)部硬件的<極性選擇><邊沿檢測><預分頻><輸入濾波電路>
? ? ? ? ③輸入的時鐘
? ? ? ? ? ? ? ? ①走ETRF進入觸發(fā)控制器,由此可以配置其作為時基單元的時鐘源。在STM32中被稱為“外部時鐘模式2”,一個實例就是用TIM來計數(shù)外部時鐘的次數(shù)(按鍵當時鐘信號)
? ? ? ? ? ? ? ? ②走TRGI走觸發(fā)控制器,作為觸發(fā)輸入(占用了這個通道),與定時器的從模式有關。當這一路的輸入被作為時鐘信號時,稱為“外部時鐘模式1”(定時器級聯(lián))。
? ? ? ? ? ? ? ? ③兩者輸入都可以作為外部時鐘,區(qū)別是有沒有占用觸發(fā)輸入的通道
外部時鐘的英文簡稱是HSE(High Speed External Clock),內(nèi)部時鐘的英文簡稱是HSI(High Speed Internal Clock)。
????????TI1F_ED連接的是輸入捕獲引腳CH1,ED是邊沿的意思,此路意為輸入的上下邊沿均有效 。編碼器接口左側(cè)的TI1FP1和TI2FP2是連載CH1、CH2的濾波器之后的。
????????CH引腳用于輸入捕獲和測頻率,ITRx用于定時器的級聯(lián),編碼器接口用于讀取正交編碼器的波形
????????內(nèi)部時鐘優(yōu)先72Mhz,外部時鐘優(yōu)先走ETR通路(外部時鐘模式2,方便)
????????TRGO是定時器的主模式輸出
????????捕獲/比較的通道用于輸出PWM驅(qū)動電機(舵機、直流電機)
高級計數(shù)器的部分額外功能
重復次數(shù)計數(shù)器:設定一個值x,每經(jīng)過x個計數(shù)周期才產(chǎn)生一次中斷。類似于再分頻。
DTG:死區(qū)生成電路,防止互補輸出由于硬件限制,驅(qū)動三項無刷電機驅(qū)動橋臂時造成短暫的直通現(xiàn)象,會在開關切換的瞬間生成一定時常的死區(qū),關閉輸出,防止直通
最右側(cè)的輸出的3個引腳由一個(TIMx_CHx)變成了兩個(TIMx_CHx、TIMx_CHxN),可以輸出互補的(極性相反)的PWM波,用于三相無刷電機,因為無刷電機一般需要3路控制,所以圖中第4路沒有多一條輸出。
BRK:剎車輸入。保證電機運行安全,外部產(chǎn)生BRK信號的時候或內(nèi)部時鐘失效,就會切斷輸出,防止意外發(fā)生
緩沖計數(shù)器
(影子寄存器、硬件說明圖的底框加黑就說明該硬件有影子寄存器):
????????在某個計數(shù)周期未完成的時候,如果寫入新的預分頻值,則緩沖計數(shù)器會先記錄寫入的值,在當前的計數(shù)周期完成之后,再把數(shù)值寫入預分頻值,避免中途寫入導致前后計數(shù)頻率不一致誤差問題。兩個沒緩沖計數(shù)器的情況:
? ? ? ? 情況1:原ARR==36,CNT<36,寫入55,則導致當前計數(shù)周期加長;
? ? ? ? 情況2:原ARR==40,CNT<40但>35,寫入35,寫導致當前計數(shù)會從CNT—>FF—>35,而不是直接因為CNT>35而進入下一個計數(shù)周期
????????預分頻器的工作原理:通過一個計數(shù)器在計數(shù)預定分頻值之后輸出一個信號。比如2分頻,那么就是0 1 2 0 1 2 ,并且在2—>0過程中輸出一次信號給CNT,從而CNT得到的值就是分頻過后的
時鐘樹的部分功能說明:
左側(cè)是時鐘來源(什么頻率的時鐘作為輸入源),右側(cè)是時鐘分配(誰需要用什么頻率的時鐘)。
硬件執(zhí)行前都需要先初始化配置時鐘,但是Stm32已經(jīng)完成了這一步操作。
系統(tǒng)時鐘:72MHz?
有四個時鐘震蕩源:
????????8MHz的內(nèi)部高速RC振蕩器
? ? ? ? 4~16MHz的外部高速石英振蕩器(晶振,比內(nèi)部RC穩(wěn)定)
? ? ? ? 32.768KHz的低速晶振(給RTC(實時時鐘)提供時鐘)
? ? ? ? 40KHz內(nèi)部低速RC振蕩器(給看門狗提供時鐘)
兩個高速晶振用于給系統(tǒng)提供時鐘(AHP,APB1,APB2)
Stm32的時鐘配置流程(SystemInit()函數(shù)的配置)
? ? ? ? 先以內(nèi)部高速8Mhz時鐘(RC)啟動,然后啟動外部時鐘,將外部8Mhz時鐘(晶振)進行PLL鎖相環(huán)9倍頻得到72Mhz的時鐘,等到鎖相環(huán)輸出穩(wěn)定后,在將鎖相環(huán)輸出的時鐘作為系統(tǒng)時鐘。從而把系統(tǒng)時鐘改8Mhz——>72MHz。
? ? ? ? 但一旦外部時鐘出了問題,系統(tǒng)就會選擇內(nèi)部8MHz的時鐘作為系統(tǒng)時鐘,72/8=9≈10,這時候程序運行的速度降低。舉例:原先一秒的中斷會變成9秒的中斷
外部時鐘的運行狀態(tài)由CSS檢測,一旦出錯就會更換系統(tǒng)時鐘源。(高級定時器的剎車輸入也有CSS)
外設時鐘使能就是XXX_cmd(XXX,ENABlE)
輸出比較+PWM:
1.大概介紹
????????CCR里的是自行設定的一個值。? ? ? ??
????????比較CNT和CCR(capture/compare registe捕獲/比較寄存器里的值)的值,來設置是輸出高/低,或是翻轉(zhuǎn)。捕獲比較寄存器是兩個功能一起的,看配置要求來啟動其中的一個功能。
? ? ? ? PWM在慣性系物件上使用。通過調(diào)節(jié)輸出的高低電平在一段時間內(nèi)的占比范圍(占空比==高T/周期T),來控制慣性系物件的狀態(tài)。用于LED呼吸燈、直流電機調(diào)速。
? ? ? ? 工作原實現(xiàn):配置CNT和CCR的值,通過比較兩值大小關系來輸出高低電平;
模式1:
? ? ? ? ? ?向上:CNT ? ? ? ? ? ? 向下:CNT>CCR(無效),CNT≤CCR(有效) 模式2: ????????????向上:CNT ? ? ? ? ? ? 向下:CNT>CCR(有效),CNT≤CCR(無效) PWM頻率:計數(shù)器頻率, 即? ?時鐘源頻率 / 預分頻+1 / ARR+1 PWM占空比:CCR/(ARR + 1) PWM分辨率:1/(ARR + 1) (占空比最小變化單位,如1%,0.1%) 注意:不同定時器對應的輸出引腳不同 2.函數(shù)配置: 外設使能——>GPIO初始化——>時基單元初始化——>輸出比較配置——>cmd void PWM_Init(void) { ?? ?/*開啟時鐘*/ ?? ?RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);?? ??? ??? ?//開啟TIM2的時鐘 ?? ?RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);?? ??? ??? ?//開啟GPIOA的時鐘 ?? ? ?? ?/*GPIO初始化*/ ?? ?GPIO_InitTypeDef GPIO_InitStructure; ?? ?GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//受外設控制(定時器、ADC)的都要用復用模式 ?? ?GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; ?? ?GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; ?? ?GPIO_Init(GPIOA, &GPIO_InitStructure);?? ? ?? ? ?? ?/*配置時鐘源*/ ?? ?TIM_InternalClockConfig(TIM2);?? ??? ?//TIM2的時鐘源選擇為為內(nèi)部時鐘(可不寫) ?? ? ?? ?/*時基單元初始化*/ ?? ?TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;?? ??? ??? ??? ?//定義結(jié)構體變量 ?? ?TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; ? ? //時鐘分頻,選擇不分頻 ?? ?TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //計數(shù)器模式,選擇向上計數(shù) ?? ?TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;?? ??? ??? ??? ??? ?//計數(shù)周期,即ARR的值 ?? ?TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;?? ??? ??? ??? ?//預分頻器,即PSC的值 ?? ?TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; ? ? ? ? ? ?//重復計數(shù)器,高級定時器才會用到 ?? ?TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure); ? ? ? ? ? ? //將結(jié)構體變量交給TIM_TimeBaseInit,配置TIM2的時基單元 ?? ? ?? ?/*輸出比較初始化*/ ?? ?TIM_OCInitTypeDef TIM_OCInitStructure;?? ??? ??? ??? ??? ??? ??? ?//定義結(jié)構體變量 ?? ?TIM_OCStructInit(&TIM_OCInitStructure);?? ??? ??? ??? ??? ??? ??? ?//結(jié)構體初始化,防止后續(xù)沒賦值的成員亂值 ?? ?TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;?? ??? ??? ??? ?//輸出比較模式,選擇PWM模式1 ?? ?TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;?? ??? ?//輸出極性,選擇為高,若選擇極性為低,則輸出高低電平取反 ?? ?TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;?? ?//輸出使能 ?? ?TIM_OCInitStructure.TIM_Pulse = 0;?? ??? ??? ??? ??? ??? ??? ??? ?//初始的CCR值 ?? ?TIM_OC1Init(TIM2, &TIM_OCInitStructure);?? ??? ??? ??? ??? ??? ?//將結(jié)構體變量交給TIM_OC1Init,配置TIM2的輸出比較通道1 ?? ? ?? ?/*TIM使能*/ ?? ?TIM_Cmd(TIM2, ENABLE);?? ??? ??? ?//使能TIM2,定時器開始運行 } TIM_SetCompare3(TIM2,Compare);//用于修改第3輸出比較通道的CCR的值,總共有1、2、3個輸出比較CCR寄存器 輸入捕獲和輸出比較的輸入輸出引腳都是公用的,且一次只能啟動一中種功能 輸入捕獲IC(Intput Capture): 1.輸入捕獲的方式有:上升沿觸發(fā)、下降沿觸發(fā)、邊沿觸發(fā)。 ????????以及專門測量PWM的PWMI模式,可以同時測量頻率和占空比。 適合主從模式實現(xiàn)硬件的自動測量PWM 2.以上升沿觸發(fā)為例解釋兩種測量方法: ? ? ? ? (1)測頻法(適合測量高頻。由于是一段固定時間內(nèi)的值,所以結(jié)果是均值,出結(jié)果速度慢):給定一個時間T(常1s),在時間T內(nèi)測量有N次上升沿,然后頻率f = N / T? ? ? ? ? (2)測周法(適合測量低頻。只測量一個周期,所以出結(jié)果得速度取決于輸入頻率,波動較大):在兩個上升沿內(nèi),用標準頻率計N次來計算一個周期的時間T,然后f = 1 / T。 ????????????????兩種理解 ????????????????①先后兩次測量CNT的值得X1,X2; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 若X1 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 若X1>X2,則T = ARR -?X1 +?X2 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 然后得f = 1 / T(這里的時間的頻率f取決于系統(tǒng)主頻f'。) ????????????????②在第一次上升沿時value1 = 0并開始計數(shù),第二次上升沿時value2 = x,記一個數(shù)得時間t = 1 / f',?則期間的總計時間是(value2 -value1)*t,記N = value2 - value1 則兩次上升沿的頻率是 f = 1 /? (N * t)?= f'?/ N。 (假設72Mhz的時鐘源,那么每次計數(shù)的時間是T=1 / 72,000,000?秒,計數(shù)N次就是 Tn = N / 72000000秒),再由f = 1 / T,T? = Tn,得到頻率f = f’ / N。) ? ? ? ? 3.以上兩種測量方法都存在正負1的誤差,即①測量過的上升沿次數(shù)不一定是完整的一個周期,而可能是半個周期,所以會需要取舍;②測量到第2個上升沿的時候,可能標準計數(shù)次數(shù)也不是完整的一個頻率,而是0.xx,這時候也需要取舍。所以兩種測量方法都有誤差,但是要選擇更合適的方法以減少誤差。 ? ? ? ? 4.由此,當(1)和(2)的N相同時,也就是誤差相同,此時的輸入頻率f =?√(f'?/ T)。式子來源: 將(1) (2)得N提出來,N = f * T = f' / f,則f*f = f' /?T,f =?√(f'?/ T)。 當待測頻率fx 3.XOR: 輸入引腳處的三輸入異或門是為三項無刷電機服務的,當三個輸入引腳有任一引腳電平翻轉(zhuǎn)時,異或門輸出的電平翻轉(zhuǎn),通過數(shù)據(jù)選擇器TI1。如果數(shù)據(jù)選擇器選擇了上面的模式,那么輸出的就是三個輸入引腳(TIMx_CH1、CH2、CH3)的異或值,要是選擇了下面的模式,那就是輸出TIMx_CH1得值,三個引腳各輸出各的。 三項無刷電機有3個霍爾傳感器來檢測轉(zhuǎn)子的位置,可以根據(jù)轉(zhuǎn)子的位置進行換相,前三個輸入通道可以接入無刷電機的霍爾傳感器,從而讓定時器 作為無刷電機的接口定時器去驅(qū)動換相電路工作 輸入濾波器可以對輸入的信號進行濾波,減少毛刺信號; 邊沿檢測器可以配置是上升沿檢測、下降沿檢測、邊沿檢測 有兩套濾波+極性選擇; 第一套輸入得到TIF1FP1然后輸入給通道1 第二套經(jīng)過另一套濾波+極性選擇,得到TIF1FP2,輸入給通道2 同理,TI1、2、3、4的輸入都可以經(jīng)過兩套濾波+極性選擇,可以得到兩個輸出結(jié)果進入兩個通道。(1和2交叉、3和4交叉) 這可以實現(xiàn)交叉輸入,靈活切換后續(xù)捕獲電路的輸入 也可以把一個引腳的捕獲輸入給兩個通道,用于PWMI:第一個捕獲通道配置上升沿觸發(fā),捕獲周期,第二個通道配置下降沿觸發(fā),捕獲占空比。兩個通道對一個引腳進行捕獲,就可以獲得周期、占空比 4.輸入捕獲單元的內(nèi)部原理圖解釋 TI1是外部輸入信號,F(xiàn)dts是測周法的參考頻率 而ICF[3:0]指的是TIMx_CCMR1寄存器里的ICF位,可以控制濾波器的參數(shù)。不同x對應的ICF的稱號不同,如TIM1_CCMR1的ICF的名字是IC1F。 如圖說明IC1F,采樣頻率就是測周法的參考頻率,頻率約小,一段時間內(nèi)采樣的個數(shù)N就越大,呂濾波效果就越好。 5.數(shù)字濾波器的工作原理: ????????計數(shù)了N個電平,如果這N個電平都是一樣的,就輸出這N個電平對應的狀態(tài)。比如N個都是低電平,那就輸出低電平)。 ????????如果N個中有不同的,那就維持原先的電平輸出。比如原先輸出高電平,后續(xù)的N個采樣中有N-1個低電平,1個高電平,那就接著輸出高電平,因為這N個采樣中有波動,所以濾波。 ? ? ? ? 不要理解成吃了N個輸入信號才吐一個信號!實際情況是檢測N個信號來判斷是不是要改變輸出信號!如果N個信號內(nèi)有波動,則說明是信號不穩(wěn),就需要維持原狀態(tài)輸出!要是N個信號的狀態(tài)是穩(wěn)的,那就需要轉(zhuǎn)換輸出!但是在檢測的過程中也是在不斷維持原有信號狀態(tài)進行輸出的! ? ? ? ? 而且采樣頻率一般會很高,如果真的有外部輸入信號的頻率和采樣頻率一摸一樣,才可能導致N個信號一直不穩(wěn),但這種情況是不被允許的(應該極力避免的),否則會導致濾波器的輸出信號可能不發(fā)生改變。 ? ? ? ??N可以配置,采樣頻率可以配置。 ? ? ? ? 會導致輸入信號降低頻率的是分頻器。 濾波之后的信號再通過邊沿檢測器來統(tǒng)計上升沿、下降沿或邊沿。 其中CC1P用于使能選擇器的輸出極性,然后輸出TI1FP1,之后通過后續(xù)的捕獲電路。 前文說過每個輸入濾波器和邊沿檢測器都有兩套,所以上圖中少了一套產(chǎn)生由通道1但產(chǎn)生信號TI2FP2并通向通道2的濾波+極性器。 然后通過CC1S控制的數(shù)據(jù)選擇器(選擇是接收TI1FP1還是TI2FP2還是TRC的輸入) ICPS用于配置分頻器(1、2、4、8) CC1E用于控制輸出使失能。開啟使能之后,輸入信號在經(jīng)歷系列電路之后,就可以讓CCR捕獲CNT的值,并且清零CNT。 自動清零CNT:TI1FP1與TIF_ED都可以通向從模式控制器,也就是TI1FP1在觸發(fā)邊沿的時候,還可以觸發(fā)從模式控制,而從模式內(nèi)就有控制CNT清零的電路。也就是CNT清零靠從模式觸發(fā)。 6.主從模式(圖片參考自江協(xié)) 主模式:能夠?qū)⒍〞r器內(nèi)部的信號映射到TRGO(Trigger? Out觸發(fā)輸出),而TRGO可以用來觸發(fā)別的外設 從模式:可以接收自身定時器或者是其他定時器輸出映射到TRGO的信號控制的外設。 觸發(fā)源:TRGO的信號來源,觸發(fā)源選擇就是選擇觸發(fā)從模式的信號源 想要TI1FP1信號觸發(fā)從模式電路實現(xiàn)清零,就需要觸發(fā)源選擇TI1FP1,并且將從模式的操作選怎Reset,就可以實現(xiàn)全自動清零。 7.配置流程(測周法)及補充: (1)配置: 1.非PWM輸入捕獲: ? ? ? ? 外設時鐘—>GPIO—>時基單元—>濾波器、邊沿檢測/極性選擇(上、下、邊沿)—> ? ? ? ? ? ? ? ?① (主從模式)TI1FP1—>觸發(fā)源選擇(選擇TIxFPx)—>從模式功能選擇(Reset) ? ? ? ? ? ? ? ? ②信號輸入通道(直通TI1FP1、交通TI1FP2)—>分頻器—>CCR(CCR記錄當前 CNT的值) ? ? 配置好 后,CCR之后從模式會自動Reset CNT的值。 2.PWM輸入捕獲: ????????外設時鐘—>GPIO—>時基單元—>濾波器、邊沿檢測/極性選擇(上、下、邊沿)—> ? ? ? ? ? ? ? ?① (主從模式)TI1FP1—>觸發(fā)源選擇(選擇TIxFPx)—>從模式功能選擇(Reset) ? ? ? ? ? ? ? ? ②TI1FP1—>輸入信號預分頻器配置—>CCR1(CCR1記錄上升沿CNT的值) ? ? ? ? ? ? ? ? ③TI1FP2—>輸入信號預分頻器配置—>CCR2(CCR1記錄下降沿CNT的值) 配置好后,CCR1會在上升沿記錄CNT的值,并且在第二次及以后記錄后會清零CNT的值,但是CCR2將在下降沿讀取CNT的值,且不會清零CNT的值。由于CCR1第一次記錄CNT的之后會清零CNT的值,所以CCR2記錄的值時0~CNT的值。 記CCR1第二次及以后記錄的CNT值為x,CCR2記錄的為y,則占空比 = y? / x 。 詳細內(nèi)容流程: ①外設時鐘(TIM、GPIO)——》 ②GPIO——》 ③時基單元(ARR、PSC、CNT、計數(shù)模式、分頻、重復計數(shù)器)——》 ④IC(IC通道、濾波器的采樣N、邊沿檢測器極性選擇(上、下、邊沿)、分頻器、信號源(通、交))——》 ⑤從模式(觸發(fā)源、觸發(fā)模式(信號來了干什么:Reset)) (2)配置函數(shù)(來自江協(xié)): //1.測頻率 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為內(nèi)部時鐘,若不調(diào)用此函數(shù),TIM默認也為內(nèi)部時鐘 ?? ? ?? ?/*時基單元初始化*/ ?? ?TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;?? ??? ??? ??? ?//定義結(jié)構體變量 ?? ?TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; ? ? //時鐘分頻,選擇不分頻,此參數(shù)用于配置濾波器時鐘,不影響時基單元功能 ?? ?TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //計數(shù)器模式,選擇向上計數(shù) ?? ?TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1; ? ? ? ? ? ? ? //計數(shù)周期,即ARR的值 ?? ?TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1; ? ? ? ? ? ? ? //預分頻器,即PSC的值 ?? ?TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; ? ? ? ? ? ?//重復計數(shù)器,高級定時器才會用到 ?? ?TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure); ? ? ? ? ? ? //將結(jié)構體變量交給TIM_TimeBaseInit,配置TIM3的時基單元 ?? ? ?? ?/*輸入捕獲初始化*/ ?? ?TIM_ICInitTypeDef TIM_ICInitStructure;?? ??? ??? ??? ??? ??? ??? ?//定義結(jié)構體變量 ?? ?TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;?? ??? ??? ??? ?//選擇配置定時器通道1 ?? ?TIM_ICInitStructure.TIM_ICFilter = 0xF;?? ??? ??? ??? ??? ??? ??? ?//輸入濾波器參數(shù),可以過濾信號抖動 ?? ?TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;?? ??? ?//極性,選擇為上升沿觸發(fā)捕獲 ?? ?TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;?? ??? ??? ?//捕獲預分頻,選擇不分頻,每次信號都觸發(fā)捕獲 ?? ?TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;?? ?//輸入信號交叉,選擇直通,不交叉 ?? ?TIM_ICInit(TIM3, &TIM_ICInitStructure);?? ??? ??? ??? ??? ??? ??? ?//將結(jié)構體變量交給TIM_ICInit,配置TIM3的輸入捕獲通道 ?? ? ?? ?/*選擇觸發(fā)源及從模式*/ ?? ?TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);?? ??? ??? ??? ??? ?//觸發(fā)源選擇TI1FP1 ?? ?TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);?? ??? ??? ??? ??? ?//從模式選擇復位 ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?//即TI1產(chǎn)生上升沿時,會觸發(fā)CNT歸零 ?? ? ?? ?/*TIM使能*/ ?? ?TIM_Cmd(TIM3, ENABLE);?? ??? ??? ?//使能TIM3,定時器開始運行 } //測周法獲取CNT值:其中1 000 000 = 72Mhz? /? 72??(psc)?? //f' =? fc / N uint32_t IC_GetFreq(void) { ?? ?return 1000000 / (TIM_GetCapture1(TIM3) + 1);?? ??? ?//測周法得到頻率fx = fc / N,這里不執(zhí)行+1的操作也可(不+得到的數(shù)值大概率多1) } //2.測頻率+占空比, //方法①在輸入捕獲初始化下面沾上下面的語句。 ?? ?TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;?? ??? ??? ??? ?//選擇配置定時器通道2 ?? ?TIM_ICInitStructure.TIM_ICFilter = 0xF;?? ??? ??? ??? ??? ??? ??? ?//輸入濾波器參數(shù),可以過濾信號抖動 ?? ?TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;?? ??? ?//極性,選擇為上升沿觸發(fā)捕獲 ?? ?TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;?? ??? ??? ?//捕獲預分頻,選擇不分頻,每次信號都觸發(fā)捕獲 ?? ?TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_IndirectTI;?? ?//輸入信號交叉,交叉輸入 方法②將????????TIM_ICInit(TIM3, &TIM_ICInitStructure);?? ????????改為????????TIM_PWMIConfig(TIM3, &TIM_ICInitStructure);?? ??? ??? ??? ??? ??? ? 這是Stm公司寫好的函數(shù),但是只允許是對通道1、2進行配置;不能對3、4進行這樣的配置。 讀取占空比(0~100) uint32_t IC_GetDuty(void) { ?? ?return (TIM_GetCapture2(TIM3) + 1) * 100 / (TIM_GetCapture1(TIM3) + 1);?? ?//占空比Duty = CCR2 / CCR1 * 100,這里不執(zhí)行+1的操作也可 } ???????? (3)補充: ? ? ? ? ①運行時,第一次記錄的CNT的值是未知的,記錄第一次之后就會立即Reset CNT,在第二次記錄CNT的值時,該值對應的就是在系統(tǒng)頻率下,輸入信號的一個周期的時間,。因為第一次記錄之后清零,第二次及以后記錄的值就是從0~>CNT的最新CNT的值。 ? ? ? ? ②要是外部輸入信號的頻率太低,就可能導致CNT的值溢出。所以把ARR的值弄到最大,極可能人為避免這種情況。 ????????舉例就是:第一次記錄到高電平之后CNT被Reset了,但是在等待第二次高電平的時候,在CNT到最高計數(shù)值的期間內(nèi)都等不到第二次高電平,然后CNT的值已經(jīng)超過了ARR的最高上限,這時候定時器的配置會讓CNT從零開始。 ? ? ? ? ③從模式的信號源不是所有定時器都有,如參考自江協(xié)的圖片所示,只有TI1FP1和TI2FP2的信號,沒有TI3FP3和TI4FP4的信號,因此從模式自動清零CNT只能選擇輸入捕獲通道1、2,而不能選擇3、4。對于通道3、4,就只能通過捕獲中斷在中斷內(nèi)部調(diào)用函數(shù)手動清零,但易消耗軟件資源。 ? ? ? ? ④ ????????直通:輸入信號從哪里來就從哪輸入 ????????交通:輸入信號交錯輸入,因為1和2、3和4有交通輸入,也就是1/2的信號可以輸入給2/1... ? ? ? ? ⑤采樣頻率與系統(tǒng)時鐘頻率有關。 ? ? ? ? ⑥占空比是下降沿觸發(fā)的原因: ? ? ? ? ⑦測周法 ????????????????最大檢測頻率 = 72Mhz / ARR。但是當檢測頻率接近72Mhz / ARR時,誤差會越來越大 ????????????????最小檢測頻率 =?72Mhz / PSC / ARR。小于這個頻率的話,CNT的值就會溢出。 ????????????????誤差精度? =?72Mhz / ARR / 最大檢測頻率 ? ? ? ? ? ? ? ? 上述的PSC都是時基單元分頻器的值,而非IC通道分頻器的值。 ? ? ? ? ? ? ? ?對于過高的待測頻率,就應該用測頻法,而不是用測周法了 用PWM驅(qū)動電機,再用編碼器測量電機的速度,然后用PID算法進行閉環(huán)控制,就可以控制小車的移動。電機速度一般比較快,一般用無接觸的霍爾傳感器or光柵測 編碼器接口(Encoder Interface): ? ? ? ? 1.優(yōu)于用外部中斷來計次編碼器轉(zhuǎn)次,防止電機高速轉(zhuǎn)動時,軟件頻繁進入中斷消耗軟件資源。 ? ? ? ? 2.可以接收增量(正交)編碼器的信號,根據(jù)編碼器的旋轉(zhuǎn)方向產(chǎn)生正交信號脈沖,自動控制控制CNT自增或自減,從加減可以測得旋轉(zhuǎn)方向,從數(shù)值變化大小可以測得旋轉(zhuǎn)速度。 ? ? ? ? 3.正交編碼器:兩個相(A、B)的輸入相差剛好90°。 ? ? ? ? ? ? ? ? ①這樣在旋轉(zhuǎn)的時候,根據(jù)旋轉(zhuǎn)方向的不同,就可以知道哪一個端先輸入有效信號,哪一端后輸入有效信號,從而判斷旋轉(zhuǎn)方向。 ? ? ? ? ? ? ? ? ②而在一段時間內(nèi)產(chǎn)生多少個脈沖,就可以計數(shù)多少個脈沖,然后根據(jù)固定時間內(nèi)接受的脈沖數(shù)量,進行一段處理就可以得到速度。 ? ? ? ? 4.每個高級、通用定時器都只有1個編碼器接口;編碼器的兩個相的輸入端分別占用IC的通道1、2,(用到了TI1FP1、TI2FP2;通道3、4不能接編碼器,即CH3、CH3)。需要注意的是,作為編碼器接口的定時器不能啟用其他功能。TI1FP1、TI2FP2見下圖編碼器接口左側(cè)。 ? ? ? ? 5.輸入的信號的流傳: ? ? ? ? ????????CH1、2—>輸入濾波器和邊沿檢測器——>觸發(fā)控制器的編碼器接口——>PSC——>CNT。 ? ? ? ? 其中邊沿檢測器中的極性選擇的可以選擇輸入信號是高電平還是低電平有效,這會導致計數(shù)方向改變。(因為極性選擇是接收到對應極性才輸出高電平,否則輸出低電平。如果選在高極性,那就是接收高電平輸出高電平,接收低電平就輸出低電平;如果選擇低極性有效,那就是接收低電平輸出高電平,接收高電平輸出低電平。個人理解) ????????其中ARR一般配置為最大值65535,用于計數(shù)滿后清零。在這個流程下,72Mhz的內(nèi)部時鐘、時基單元配置的CNT計數(shù)方向(向上、向下、中央對齊)不會被該電路使用。CNT的計數(shù)快慢,計數(shù)加減由編碼器控制 ? ? ? ? ????????補充說明:在編碼器接口的工作模式下,通道1、2的OC也是可以正常工作的。(前提是使能了輸出控制) ? ? ? ? 6.工作模式:三種。第三種的精度最高 ? ? ? ? 這個表的看法是:先選定自己的工作模式,再想所需要兩個輸入的信號高低,然后看右上方的TI1、TI2的上升、下降,然后再找對應工作模式下選定上升/下降列對應的計數(shù)方式,此時相對信號的電平就控制計數(shù)是+還是-。 ? ? ? ? 比如我選在TI1和2上計數(shù),想要知道TI1高、TI2低電平的計數(shù)是什么: ???????? 函數(shù)配置流程: ? ? ? ? 外設時鐘——>GPIO——>時基單元——>IC——編碼器。 ? ? ? ? 其中時基單元的CNT計數(shù)方式、時鐘源選擇即使配置了也不會生效,因為CNT的的計數(shù)由編碼器作為時鐘源控制,而CNT的技術方向由編碼器的旋轉(zhuǎn)方向決定是+還是-。IC的邊沿檢測器的極性選擇將控制旋轉(zhuǎn)編碼器的計數(shù)方向(因為極性選擇將導致輸入信號的高低電平是否翻轉(zhuǎn))。 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); TIM_InternalClockConfig(TIM3); //GPIO GPIO_InitTypeDef GPIOAInitStructure; GPIOAInitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIOAInitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIOAInitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIOAInitStructure); //時基單元 TIM_TimeBaseInitTypeDef InitStructure; InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//時鐘源分頻——編碼器模式下用不到 InitStructure.TIM_CounterMode = TIM_CounterMode_Up;//計數(shù)模式 向上計數(shù)——編碼器模式下用不到 InitStructure.TIM_Period = 65536 - 1;//ARR 自動重裝值 InitStructure.TIM_Prescaler = 1 - 1;//PSC 預分頻 InitStructure.TIM_RepetitionCounter = 0;//重復計數(shù)器-高級定時器:多少個計數(shù)周期算計數(shù)一次 TIM_TimeBaseInit(TIM2,&InitStructure);//結(jié)構體是初始化誰的就是誰Init //IC TIM_ICInitTypeDef ICInitStructure; TIM_ICStructInit(&ICInitStructure);//不完全配置參數(shù)就需要這一步,用結(jié)構體初始化 ICInitStructure.TIM_Channel = TIM_Channel_1 ;//IC的輸入通道 ICInitStructure.TIM_ICFilter = 0xF;//輸入信號濾波器的值 ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_BothEdge;//輸入信號有效邊沿選擇——編碼模式下則對應是否翻轉(zhuǎn)極性——后面可以統(tǒng)一配置,這里可以不配 // ICInitStructure.TIM_ICPrescaler = ;//后半段的輸入信號分頻——編碼器用不到 // ICInitStructure.TIM_ICSelection = ;//后半段的信號通道選擇——編碼器用不到 TIM_ICInit(TIM3,&ICInitStructure); ICInitStructure.TIM_Channel = TIM_Channel_2 ;//IC的輸入通道 ICInitStructure.TIM_ICFilter = 0xF;//輸入信號濾波器的值 ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_BothEdge;//輸入信號有效邊沿選擇——編碼模式下則對應是否翻轉(zhuǎn)極性——后面可以統(tǒng)一配置,這里可以不配 // ICInitStructure.TIM_ICPrescaler = ;//后半段的輸入信號分頻——編碼器用不到 // ICInitStructure.TIM_ICSelection = ;//后半段的信號通道選擇——編碼器用不到 TIM_ICInit(TIM3,&ICInitStructure); //配置編碼器接口 TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);//定時器通道、編碼模式(單計數(shù)、雙計數(shù))、IC1的輸入極性、IC2的輸入極性 TIM_Cmd(TIM3,ENABLE);//TIM使能 獲取編碼器旋轉(zhuǎn)值的函數(shù) TIM_GetCounter(TIM3); 清零編碼值的函數(shù) TIM_SetCounter(TIM3,0); 柚子快報邀請碼778899分享:Stm32的定時器 推薦鏈接
本文內(nèi)容根據(jù)網(wǎng)絡資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉(zhuǎn)載請注明,如有侵權,聯(lián)系刪除。