最近一個(gè)工程師問(wèn)我MCU的最高翻轉(zhuǎn)速度能夠到多少?這個(gè)話題我多年前就聽(tīng)過(guò),不過(guò)一直沒(méi)有實(shí)際去測(cè)試過(guò),這次正好借此問(wèn)題實(shí)際測(cè)試了一番,發(fā)現(xiàn)里面還藏了不少的知識(shí)。
本次測(cè)試選取了目前市面上性價(jià)比極高的3款32位ARM Cortex-M0/M0+內(nèi)核MCU,分別是靈動(dòng)微MM32G0001、普冉PY32F002B、芯源CW32L010,價(jià)格都在5毛錢(qián)以內(nèi)!
首先測(cè)試的是靈動(dòng)微的MM32G0001 MCU,該MCU基于ARM Cortex-M0內(nèi)核,最高工作頻率可達(dá) 48MHz。系統(tǒng)架構(gòu)圖如下:
可以看到GPIO模塊位于AHB 總線上,AHB總線的最高速率為48Mhz。GPIO翻轉(zhuǎn)就是高低電平變換,執(zhí)行一條電平控制的STR匯編指令是2個(gè)指令周期,所以理論上該MCU GPIO最大的翻轉(zhuǎn)速率是48Mhz/(2+2)=12Mhz。下面我們來(lái)看看實(shí)測(cè)情況,
測(cè)試代碼基于靈動(dòng)微官網(wǎng)提供的:LibSamples_MM32G0001_V0.10.2SamplesLibSamplesGPIOGPIO_LED_Toggle例程。
該示例時(shí)鐘配置的就是48Mhz。我們進(jìn)行以下幾個(gè)實(shí)驗(yàn):
實(shí)驗(yàn)1:原始代碼做如下修改,注釋掉不相關(guān)代碼,while(1)里只保留一個(gè)GPIO翻轉(zhuǎn)函數(shù)。
測(cè)試結(jié)果只有289Khz。
實(shí)驗(yàn)2:把優(yōu)化等級(jí)從0開(kāi)到最高:
測(cè)試結(jié)果是333Khz。
以上2個(gè)實(shí)驗(yàn)測(cè)出來(lái)的速率遠(yuǎn)低于理論值,主要是和函數(shù)調(diào)用有關(guān)系,占用了很多額外的時(shí)間。
實(shí)驗(yàn)3:這次直接改為操作寄存器的方式實(shí)現(xiàn),為保證測(cè)試一致性,優(yōu)化等級(jí)還是調(diào)整回0。
測(cè)出來(lái)的結(jié)果是4Mhz,速率明顯提升。
可是為什么低電平時(shí)間要比高電平時(shí)間多了那么多呢。經(jīng)過(guò)分析可知是while(1)循環(huán)占用了額外的時(shí)間。
實(shí)驗(yàn)4:在實(shí)驗(yàn)3的基礎(chǔ)上改進(jìn)一下,while(1)多增加幾條重復(fù)的語(yǔ)句。
測(cè)試翻轉(zhuǎn)期間的速率為12Mhz,這樣就達(dá)到了理論上的最大速率。
第二個(gè)測(cè)試的是普冉的PY32F002B MCU,該MCU基于ARM Cortex-M0+內(nèi)核,最高主頻24MHz。系統(tǒng)架構(gòu)圖如下:
可以看到這個(gè)MCU的GPIO是直接掛到內(nèi)核上,它具備單周期快速翻轉(zhuǎn)的能力。單周期GPIO是ARM Cortex-M0+內(nèi)核所特有支持的一個(gè)功能,M0內(nèi)核MCU沒(méi)有此功能。所以該款MCU GPIO翻轉(zhuǎn)最大速率理論值為:24Mhz/(1+1)=12Mhz。下面我們來(lái)看下實(shí)際測(cè)試結(jié)果。
PY32F002B_Firmware_V1.1.0ProjectsPY32F002B-STKExample_LLGPIOGPIO_FastIO直接提供了測(cè)試?yán)?,什么都不用改,下載進(jìn)去就可以測(cè)試,
可以看到IO翻轉(zhuǎn)速率確實(shí)達(dá)到了12Mhz。
C:Userswangwx1Desktop普冉12Mhz.jpg
雖然PY32F002B最高主頻相比MM32G0001只有其一半,但是因?yàn)槠渲苯訏煸趦?nèi)核上,具備單周期翻轉(zhuǎn)能力,所以兩者的最高IO翻轉(zhuǎn)速率都是12Mhz。
最后再來(lái)看芯源的CW32L010 MCU,這顆MCU也是Cortex-M0+內(nèi)核,但是其GPIO并沒(méi)有像PY32F002B直接掛在內(nèi)核上,而是掛在AHB總線上。該MCU最高主頻也是48Mhz。
有了上述測(cè)試基礎(chǔ),你是不是能夠猜到該MCU的最大翻轉(zhuǎn)速率了,你可能會(huì)認(rèn)為和靈動(dòng)微G0001一樣也是12Mhz。事實(shí)果真如此嗎?
我們基于CW32L010_StandardPeripheralLib_V1.0.2ExamplesGPIOgpio_blink做了簡(jiǎn)單修改,該例子默認(rèn)跑的是4Mhz主頻,將其修改為48Mhz
實(shí)際測(cè)試結(jié)果只有8Mhz,這是什么原因呢?我們可以看到低電平時(shí)間是2個(gè)指令周期,但是高電平時(shí)間卻是4個(gè)指令周期。
這是因?yàn)镕lash讀等待所導(dǎo)致的,當(dāng)主頻大于24Mhz之后,需要插入1個(gè)等待周期,所以無(wú)法保證每個(gè)翻轉(zhuǎn)都能達(dá)到2個(gè)指令周期。
我們可以再做一個(gè)測(cè)試,將其主頻降低為24Mhz,可以看到此時(shí)GPIO翻轉(zhuǎn)速率可以達(dá)到6Mhz,這是因?yàn)闆](méi)有flash讀等待周期了。
最后再做一個(gè)測(cè)試,把上述翻轉(zhuǎn)GPIO的代碼做一點(diǎn)修改,上述用了BSRR、BRR寄存器來(lái)實(shí)現(xiàn)置位和清零,如果使用ODR寄存器會(huì)有什么效果呢?
可以看到,翻轉(zhuǎn)速率直接只有4Mhz。
通過(guò)匯編代碼可以看到,多了一條MOVS指令,該指令需要1個(gè)指令周期,所有最高翻轉(zhuǎn)速率為24Mhz/(3+3)=4Mhz
除了置位/清零寄存器、輸出數(shù)據(jù)寄存器實(shí)現(xiàn)GPIO翻轉(zhuǎn)外,有的MCU還有翻轉(zhuǎn)寄存器,比如CW32L010有,MM32G0001和PY32F002B沒(méi)有,直接用這一個(gè)寄存器就可以實(shí)現(xiàn)IO翻轉(zhuǎn),實(shí)測(cè)這個(gè)效果和BSRR/BRR一樣。
由此可見(jiàn),影響MCU GPIO翻轉(zhuǎn)速度的因素有很多,包括系統(tǒng)主頻、是否支持單周期翻轉(zhuǎn)、Flash讀等待、翻轉(zhuǎn)語(yǔ)句寫(xiě)法、編譯器優(yōu)化等級(jí)等多個(gè)因素。
最后再留一個(gè)問(wèn)題供大家思考,為什么芯源CW32L010和靈動(dòng)微MM32G0001同樣都是跑48Mhz最高主頻,芯源CW32L010無(wú)法達(dá)到理論值12Mhz但是靈動(dòng)微MM32G0001卻可以達(dá)到呢?歡迎評(píng)論區(qū)留言。
關(guān)注我們,掃碼加入嵌入式交流群: