成人免费无码不卡毛片,亚洲AⅤ无码精品一区二区三区,国产尤物精品视频,久久精品日本亚洲,欧美成人一区三区无码乱码A片,中文字日产幕码一区二区色哟哟,亞洲日韓中文字幕網AV

  • 正文
  • 推薦器件
  • 相關(guān)推薦
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

在KEIL中勾選微庫后,延時(shí)函數(shù)為什么不準(zhǔn)了?

2024/08/03
4885
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

最近一工程師向我反饋了一個(gè)問題,他使用ARM Cortex-M0+的MCU,在使用延時(shí)函數(shù)std_delayms延時(shí)1s時(shí),如果勾選了KEIL中的Use MicroLIB會(huì)導(dǎo)致延時(shí)有5%的計(jì)時(shí)偏差,不勾選的話誤差只有1%。

首先進(jìn)行問題的復(fù)現(xiàn),在程序中while(1)里調(diào)用std_delayms(1000),通過串口發(fā)送一個(gè)字符,在上位機(jī)上進(jìn)行接收,可以清楚的看到勾選微庫之后誤差確實(shí)明顯增大,每次偏差大約為50ms。

這個(gè)現(xiàn)象看著比較奇怪,剛開始時(shí)也困擾了我,那么到底是什么原因呢?

首先要看延時(shí)函數(shù)是如何實(shí)現(xiàn)的,

std_delayms函數(shù)是通過systick定時(shí)器來實(shí)現(xiàn),采用的是阻塞的方式,實(shí)現(xiàn)代碼如下:

/*** @brief  us級(jí)延時(shí)函數(shù)(阻塞模式)* @param  count 計(jì)數(shù)周期* @note   延時(shí)函數(shù)最大值受限于SysTick重載值寄存器的最大值0xFFFFFF(16777216)* @note   該函數(shù)為weak函數(shù),用戶可選擇其他定時(shí)器重新定義實(shí)現(xiàn)該函數(shù)* @retval 無*/__weak void std_delayus(uint32_t count){    count = STD_DELAY_US * count;
    count = count > 16777216 ? 16777216 : count;    SysTick->LOAD = count - 1;    SysTick->VAL = 0;    while(!((SysTick->CTRL >> 16) & 0x1));}
/*** @brief  us級(jí)延時(shí)函數(shù)(阻塞模式)* @param  count 計(jì)數(shù)周期* @note   延時(shí)函數(shù)最大值受限于SysTick重載值寄存器的最大值0xFFFFFF(16777216)* @note   該函數(shù)為weak函數(shù),用戶可選擇其他定時(shí)器重新定義實(shí)現(xiàn)該函數(shù)* @retval 無*/__weak void std_delayus(uint32_t count){    count = STD_DELAY_US * count;
    count = count > 16777216 ? 16777216 : count;    SysTick->LOAD = count - 1;    SysTick->VAL = 0;    while(!((SysTick->CTRL >> 16) & 0x1));}
#define?STD_DELAY_US??????????????(SystemCoreClock/1000000)????????????/**<?STD中用于計(jì)時(shí)的基礎(chǔ)值,與計(jì)時(shí)周期有關(guān)?*/?

看起來似乎沒什么問題,就是調(diào)用1000次std_delayus(1000)函數(shù),std_delayus(1000)一次延時(shí)1ms,累計(jì)實(shí)現(xiàn)1s的延時(shí)。

勾選MicroLIB與否肯定不會(huì)影響systick計(jì)數(shù)器本身的計(jì)時(shí),那么唯一能影響的就是其它為數(shù)不多的幾條賦值語句了。

最后定位到是SystemCoreClock/1000000 這個(gè)除法運(yùn)算導(dǎo)致的,使用微庫后會(huì)讓除法運(yùn)算執(zhí)行的更慢。

我們測(cè)一下執(zhí)行一次除法運(yùn)算需要的時(shí)間。本次測(cè)試中,系統(tǒng)時(shí)鐘為8Mhz,通過GPIO翻轉(zhuǎn)的方式來測(cè)

LED1_OFF();divide_test(1);LED1_ON();
int divide_test(uint32_t loop ){????uint32_t?count;    while(loop--)    {        count = SystemCoreClock/1000000;????}?????    return count;}

可以看到勾選微庫后,執(zhí)行時(shí)間為49us

不勾選微庫,執(zhí)行時(shí)間為9us

兩者足足相差了好幾倍,勾選微庫后,執(zhí)行1000次除法運(yùn)算時(shí)間大約就是50ms,正好和之前的現(xiàn)象就對(duì)應(yīng)上了。

如果想讓定時(shí)更加準(zhǔn)確,可以不使用除法,這樣誤差會(huì)更小,實(shí)測(cè)只有幾個(gè)ms的偏差。

原始代碼,每次調(diào)用std_delayus函數(shù)都進(jìn)行一次除法運(yùn)算是為了保證系統(tǒng)主頻會(huì)發(fā)生變化時(shí)依然能正確計(jì)時(shí),實(shí)際使用中在已知特定主頻的情況下,可以不用每次都進(jìn)行除法運(yùn)算,只在主頻變化的情況下更新一次即可。

MicroLib 和 standard C library的主要區(qū)別有:

來源于:[MicroLib MDK-ARM Library (keil.com)](https://www.keil.com/arm/microlib.asp#:~:text=The primary differences between MicroLib,using the ARM standard library.)

MicroLIB更加詳細(xì)的介紹,大家可以在KEIL的Help里查看:

上面提到MicroLIB雖然減少code size,但是有些函數(shù)會(huì)執(zhí)行的更慢,這次遇到的問題恰恰就對(duì)應(yīng)這一條。這其實(shí)對(duì)應(yīng)的用時(shí)間換空間的概念,對(duì)于某些運(yùn)算,MicroLIB執(zhí)行時(shí)間變長(zhǎng)了,換回的好處是空間占用更小。實(shí)際使用中需要在空間和時(shí)間上做一定的取舍。

ARM Cortex-M0+沒有硬件除法器,除法是相對(duì)復(fù)雜的操作,相比加法、減法和乘法,需要更多的CPU周期才能完成。

測(cè)試一段代碼所需要的CPU周期,這里墻裂推薦傻孩子的超級(jí)嵌入式系統(tǒng)“性能/時(shí)間”工具箱perf_counter,在Github上已開源https://github.com/GorgonMeducer/perf_counter.git ,我在這里用上了,可以很方便的測(cè)試。具體使用大家可以參考他的【喂到嘴邊了的模塊】超級(jí)嵌入式系統(tǒng)“性能/時(shí)間”工具箱

比如測(cè)試這個(gè)函數(shù)的CPU周期數(shù),直接這么調(diào)用就行

??__cycleof__()?{??  divide_test(1);????}

使用微庫時(shí),可以看到占用了414個(gè)CPU周期,對(duì)應(yīng)時(shí)間414/8000000=51.7us

而不用微庫時(shí),可以看到占用了96個(gè)CPU周期,對(duì)應(yīng)時(shí)間96/8000000=12us

所以就是這個(gè)問題的完整分析,希望對(duì)大家有所幫助。

推薦器件

更多器件
器件型號(hào) 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊(cè) ECAD模型 風(fēng)險(xiǎn)等級(jí) 參考價(jià)格 更多信息
MOC3063SM 1 Isocom Components Triac Output Optocoupler With Zero CRSVR, 1-Element, 5300V Isolation, ROHS COMPLIANT, SURFACE MOUNT PACKAGE-6
$1.15 查看
SC32S-7PF20PPM 1 ABLIC Inc Parallel - Fundamental Quartz Crystal, 0.032768MHz Nom, LEAD FREE, SMD, 2 PIN
$0.61 查看
LTC6994IS6-1#TRMPBF 1 Analog Devices Inc LTC6994IS6-1#TRMPBF

ECAD模型

下載ECAD模型
$4.83 查看

相關(guān)推薦

登錄即可解鎖
  • 海量技術(shù)文章
  • 設(shè)計(jì)資源下載
  • 產(chǎn)業(yè)鏈客戶資源
  • 寫文章/發(fā)需求
立即登錄

TopSemic,讓芯片使用更簡(jiǎn)單。 專注分享:嵌入式,單片機(jī),STM32,ARM,RTOS,Linux, 軟硬件,半導(dǎo)體,電子技術(shù)等相關(guān)內(nèi)容。

上思县| 饶平县| 明溪县| 北宁市| 车险| 富裕县| 玉山县| 繁峙县| 犍为县| 琼海市| 张家港市| 宜兰市| 安福县| 巴彦淖尔市| 吴旗县| 聊城市| 嘉祥县| 宁阳县| 岫岩| 石河子市| 建瓯市| 台山市| 盐亭县| 崇文区| 娄烦县| 白水县| 吉林省| 安丘市| 五指山市| 洞口县| 嘉义市| 黄骅市| 旬阳县| 宁城县| 庆城县| 黔西县| 宁化县| 平乐县| 镇赉县| 平乡县| 维西|