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