monkey 运行时间怎么计算_基于STM32F103C8T6工控板利用定时器计算某段代码的运行时间...
本人參考了熱心網(wǎng)友分享的一些案例,并增加了一些個(gè)人認(rèn)為比較好的想法,重新整合了一下代碼。
硬件:某寶網(wǎng)上購(gòu)買的STM32F103C8T6工控板,價(jià)格50¥左右;
思路:
1)利用通用定時(shí)器(選擇定時(shí)器2)計(jì)算某段代碼的運(yùn)行時(shí)間;
2)顧名思義,會(huì)基于定時(shí)器2創(chuàng)建兩個(gè)函數(shù)(TIM2_Clock_Start和TIM2_Clock_End)分別控制定時(shí)器2開(kāi)始計(jì)時(shí)和結(jié)束計(jì)時(shí),被測(cè)代碼放在這兩個(gè)代碼的中間;
3)考慮計(jì)時(shí)的精度和最大計(jì)時(shí)長(zhǎng)度,創(chuàng)建變量 u8 OverflowNum_cnt用來(lái)計(jì)算定時(shí)器2溢出中斷的次數(shù),創(chuàng)建變量u16 cnt_value用來(lái)計(jì)算最后一次定時(shí)器2的cnt值;
4)利用USART1實(shí)時(shí)讀取某段代碼的運(yùn)行時(shí)間,并上傳至電腦,便于查看。
這個(gè)工程較為簡(jiǎn)單,主要代碼如下:
1. 定時(shí)器2的初始化配置代碼,注意:初始化后,不使能TIM2!!
/*****************************************************************函數(shù)名稱:TIM2_Init(u16 arr, u16 psc)函數(shù)功能:定時(shí)器2 初始化函數(shù)入口參數(shù):u16 arr:自動(dòng)重裝載值, u16 psc:時(shí)鐘預(yù)分頻數(shù)返回參數(shù):無(wú)開(kāi)發(fā)作者:閑人Ne******************************************************************/void TIM2_Init(u16 arr, u16 psc){ TIM_TimeBaseInitTypeDef TIM_TimeBaseInitTypeStruct; TIM_DeInit(TIM2); // 定時(shí)器 2 復(fù)位 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); // 使能TIM 2 時(shí)鐘 // 定時(shí)器 2 參數(shù)初始化配置 TIM_TimeBaseInitTypeStruct.TIM_Period=arr; TIM_TimeBaseInitTypeStruct.TIM_Prescaler=psc; TIM_TimeBaseInitTypeStruct.TIM_CounterMode=TIM_CounterMode_Up; // 向上計(jì)數(shù)模式 TIM_TimeBaseInitTypeStruct.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitTypeStruct); // 定時(shí)器 3 中斷優(yōu)先級(jí)配置 NVIC_Configuration();}2. 定時(shí)器2開(kāi)始和結(jié)束相關(guān)代碼,注意:引用了2個(gè)放在main.c文件里的變量!!
/*****************************************************************函數(shù)名稱:TIM2_Clock_Start()函數(shù)功能:使能定時(shí)器 2 函數(shù),開(kāi)始計(jì)時(shí)入口參數(shù):無(wú)返回參數(shù):無(wú)開(kāi)發(fā)作者:閑人Ne******************************************************************/extern u8 OverflowNum_cnt; // u8 計(jì)數(shù)器,用來(lái)計(jì)算溢出中斷的次數(shù),初始化值為0000 0000void TIM2_Clock_Start(){ OverflowNum_cnt = 0; TIM2->CNT=0x00; // 將定時(shí)器 2 的計(jì)數(shù)器至零 TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); // 針對(duì)TIM2_DIER寄存器,[0]位,UIE至1,允許更新中斷 TIM_Cmd(TIM2,ENABLE); }/*****************************************************************函數(shù)名稱:u16 TIM2_Clock_End()函數(shù)功能:停止定時(shí)器 2 函數(shù),讀取CNT數(shù)值入口參數(shù):無(wú)返回參數(shù):u16 cnt_value,返回當(dāng)前TIM2_CNT的值開(kāi)發(fā)作者:閑人Ne******************************************************************/extern u16 cnt_value;u16 TIM2_Clock_End(){ cnt_value = TIM2->CNT; TIM_Cmd(TIM2,DISABLE); return cnt_value;}3. 定時(shí)器2的中斷服務(wù)函數(shù),主要目的是每發(fā)生一次溢出中斷,OverflowNum_cnt值+1,如果OverflowNum_cnt值溢出,就報(bào)錯(cuò)。
/************************************************函數(shù)名稱:TIM2_IRQHandler()函數(shù)功能:定時(shí)器2中斷服務(wù)函數(shù)入口參數(shù):無(wú)返回參數(shù):無(wú)開(kāi)發(fā)作者:閑人Ne*************************************************/extern u8 OverflowNum_cnt; // u8 計(jì)數(shù)器,用來(lái)計(jì)算溢出中斷的次數(shù),初始化值為0000 0000 void TIM2_IRQHandler(void){ if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET) // 判斷是否發(fā)生更新中斷 { if(OverflowNum_cnt==0XFF) // 判斷OverflowNum_cnt是否溢出 { printf("錯(cuò)誤:超出最大計(jì)算時(shí)間!"); OverflowNum_cnt = 0; // OverflowNum_cnt置零 } else { OverflowNum_cnt++; } TIM_ClearITPendingBit(TIM2,TIM_IT_Update); // 清除定時(shí)器2中斷標(biāo)志位 }}4. 主函數(shù),這里注意,當(dāng)TIM2_arr = 7199,TIM2_psc = 0,那么TIM2 中斷時(shí)間間隔為0.0001s,又因?yàn)閡8 OverflowNum_cnt最大值為255,所以所創(chuàng)建的定時(shí)器2計(jì)算某段代碼的運(yùn)行時(shí)間上限是0.0001 X 255 = 0.0255s,即25.5ms。如果被測(cè)代碼的實(shí)際運(yùn)行時(shí)間大于25.5ms,那么就不適用了。
/************************************************函數(shù)名稱:int main()函數(shù)功能:主函數(shù)入口入口參數(shù):無(wú)返回參數(shù):int開(kāi)發(fā)作者:閑人Ne*************************************************/u8 OverflowNum_cnt = 0; // 溢出的次數(shù)u16 cnt_value = 0; // 最后一次cnt的數(shù)值u16 TIM2_arr = 7199; u16 TIM2_psc = 0;float TIM2_looptime = 0.0001; // TIM2 中斷時(shí)間間隔,TIM2_looptime=((TIM2_psc+1)/72000000)*(TIM2_arr+1)float TIM2_clock = 0.0000000138888888888; // TIM2 cnt更新周期,TIM2_clock=1/72000000u16 delay_time_ms=10; // 模擬某段代碼的運(yùn)行時(shí)間int main(void){ float CodeRunTime=0; // 計(jì)算某段代碼的運(yùn)行時(shí)間 u8 t=0; // while循環(huán)計(jì)數(shù)用 delay_init(); LED_Init(); My_USART1_Init(); TIM2_Init(TIM2_arr, TIM2_psc); NVIC_Configuration(); while(1) { TIM2_Clock_Start(); delay_ms(delay_time_ms); // 某段代碼的運(yùn)行時(shí)間 cnt_value=TIM2_Clock_End(); CodeRunTime = (float)cnt_value*TIM2_clock+(float)OverflowNum_cnt*TIM2_looptime; t++; if(t==100) { printf("設(shè)定某段代碼的運(yùn)行時(shí)間為:%d毫秒\r\n",delay_time_ms); printf("實(shí)際某段代碼的運(yùn)行時(shí)間為:%f秒\r\n\r\n",CodeRunTime); D1=!D1; //提示系統(tǒng)正在運(yùn)行// t=0; } delay_time_ms=delay_time_ms+1; if(delay_time_ms>20) delay_time_ms=10; }}實(shí)驗(yàn)結(jié)果在串口調(diào)試助手上顯示結(jié)果如下:
經(jīng)驗(yàn)分享為什么要測(cè)試代碼的運(yùn)算時(shí)間?因?yàn)橛袝r(shí)候,程序沒(méi)必要運(yùn)算的非常快,適當(dāng)?shù)慕档瓦\(yùn)算時(shí)間,可以降低功耗。此外,有些功能需要實(shí)時(shí)的、快速的給與反饋,比如自動(dòng)駕駛、無(wú)人機(jī)、主動(dòng)控制這類工作,如果算法很牛逼,但是運(yùn)算一次周期長(zhǎng),那也沒(méi)什么實(shí)際用處。
總結(jié)
以上是生活随笔為你收集整理的monkey 运行时间怎么计算_基于STM32F103C8T6工控板利用定时器计算某段代码的运行时间...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 联想研发出创新铝材“丝绸铝”,今年将有
- 下一篇: 如何定义一个类对象并用next()的方法