起因
一直想通過(guò)定時(shí)器的捕獲通道捕獲 PWM,這種需求是非?;镜摹8鞣N開(kāi)發(fā)板例程也都有,但是精度不怎么樣,能捕獲的頻率也不是很高。對(duì)于高頻和高精度情況下明顯不適用。
有經(jīng)驗(yàn)的工程師會(huì)選擇參考手冊(cè)中介紹的 PWM 輸入捕獲功能,但是該功能有一個(gè)很大的限制:
一個(gè)定時(shí)器有四個(gè)通道,但是只有兩個(gè)通道才可以使用 PWM 輸入捕獲,這極大的限制了可用通道,而在有些需求中,定時(shí)器可用通道當(dāng)然是越多越好。
所以魚鷹一直在苦思冥想一個(gè)高精度的通用的 PWM 輸入捕獲程序。
領(lǐng)悟
一天晚上,魚鷹一邊洗衣,一邊思考,終于靈光一閃,既然編碼器功能可以借助兩組通道完成編碼器,為什么 PWM 輸入捕獲不能使用類似的機(jī)制呢?
手冊(cè)中的 PWM 輸入因?yàn)槭褂昧?從模式 功能,才有上述限制,只要我不使用從模式,僅僅使用兩個(gè)通道的捕獲功能,就可以解除該限制了吧?
所以借助《如何高效的擴(kuò)展定時(shí)/計(jì)數(shù)器?》里面介紹的知識(shí),魚鷹頓悟了……
效果
左邊用邏輯分析儀設(shè)置的輸出參數(shù),右邊通過(guò)捕獲程序捕獲的結(jié)果。
STM32F103,主頻 72 Mhz,定時(shí)器時(shí)鐘頻率 72 MHz。
我們從上圖可以知道,即使輸入 PWM 頻率高達(dá) 1 Mhz,我們的程序還是將其準(zhǔn)確測(cè)量出來(lái)了。
當(dāng)然在占空比計(jì)算方面,因?yàn)槎〞r(shí)器頻率自身的原因,計(jì)算的并不精確,和實(shí)際的誤差比較大,不過(guò)在這么高的頻率下,只是 10% 的誤差,我認(rèn)為還是可以接受的。
而頻率達(dá)到 3 MHz 時(shí),頻率比較接近(4 % 誤差),但是占空比已經(jīng)出現(xiàn)了很大誤差,已經(jīng)不可用了(可能計(jì)算有點(diǎn)問(wèn)題)。
100 K,占空比 5 % 的情況下,頻率測(cè)量誤差 0%,占空比誤差 1%?。?!
優(yōu)缺點(diǎn)
由于時(shí)間與篇幅原因(花了很多時(shí)間做測(cè)試),本篇筆記不會(huì)介紹捕獲原理(魚鷹要寫的話,一定會(huì)盡可能的介紹清楚,所以字?jǐn)?shù)會(huì)比較多,目前時(shí)間不足),主要是想通過(guò)本篇介紹 F103 72Mhz 的情況下所能達(dá)到的極致效果,讓各位在接任務(wù)時(shí)有一個(gè)概念,看是否能簡(jiǎn)單通過(guò) 103 完成功能。
現(xiàn)在簡(jiǎn)單介紹一下魚鷹這個(gè)方案的優(yōu)缺點(diǎn):
優(yōu)點(diǎn):
1、不占用 CPU 資源,使用 DMA 與定時(shí)器捕獲功能完成。 而如果使用中斷的方式,100KHz 下,10 us 就需要進(jìn)入一次中斷,基本不用干其他事情了。一旦中斷被別的代碼短暫禁用,錯(cuò)過(guò)了捕獲,那計(jì)算的結(jié)果可能就有問(wèn)題了。
2、可以分時(shí)使用定時(shí)器的四個(gè)通道,不會(huì)被所謂的從模式所限制,但能達(dá)到和手冊(cè)介紹 PWM 輸入捕獲功能一樣的精度。
3、可以捕獲高頻信號(hào)(MHz),并且精度高。
4、精度和定時(shí)器時(shí)鐘頻率有很大關(guān)系(F1 1/72 us),如果 F4 的芯片,定時(shí)器頻率更高,那么可以達(dá)到更高的精度(可以算優(yōu)點(diǎn),也可以算缺點(diǎn))。
5、因?yàn)椴捎?DMA 傳輸 + 硬件(定時(shí)器)方式,計(jì)算的結(jié)果可以信任,不需要太多的處理(比如濾波)。
6、單個(gè)通道可以達(dá)到很高的捕獲率,甚至可以通過(guò)特定的算法進(jìn)行實(shí)時(shí)捕獲,而對(duì) CPU 本身的影響卻很?。床徽加?CPU 資源實(shí)時(shí)捕獲計(jì)算)。
7、解除STM32定時(shí)器只能捕獲上升沿或下降沿,而不能雙邊沿捕獲的限制。
缺點(diǎn):
1、只能分時(shí)測(cè)量每個(gè)通道的 PWM,不能同時(shí)測(cè)量(如果頻率很高,幾十個(gè)微秒就能切換 一次測(cè)量,問(wèn)題不大)。
2、占用 DMA 傳輸通道,導(dǎo)致對(duì)應(yīng)的通道的外設(shè)不能使用(比如串口)
3、代碼很簡(jiǎn)單,但是很難理解(下面的代碼計(jì)算了所有捕獲,實(shí)際上只要計(jì)算幾個(gè)就行,因?yàn)閿?shù)據(jù)可以信任)。
uint32_t cal_duty_cycle(capture_buff_def *buff, uint32_t size)
{
assert_param(size > CCR_VALUE_BUFF);
for(int i = 0; i < size - 1; i++)
{
cycle_temp[(i << 1)] = buff[i + 1].ccr1 - buff[i].ccr1;
cycle_temp[(i << 1) + 1] = buff[i + 1].ccr2 - buff[i].ccr2;
}
for(int i = 0; i < size - 1; i++)
{
duty_cycle_temp[(i << 1)] = /* cycle_temp[(i << 1)] - */(buff[i].ccr1 - buff[i].ccr2);
duty_cycle_temp[(i << 1) + 1] = /* cycle_temp[(i << 1) + 1] - */(buff[i].ccr1 - buff[i].ccr2);
}
cycle = (1000 * 1000 * 72) / cycle_temp[20];
duty_cycle = duty_cycle_temp[20] * 100 / cycle_temp[20];
return 0;
}
咱們下期再見(jiàn)了!不出意外更新的應(yīng)該就是本篇的續(xù)集了。
來(lái)源:公眾號(hào)【魚鷹談單片機(jī)】
作者:魚鷹Osprey(emOsprey)