01、示波器
測量一段程式碼執行時間第一時間想到的當然是示波器了,在測量開始的程式碼前面拉高某個GPIO,在結束測量的位置拉低這個GPIO,直接使用示波器檢視這個GPIO的高電平時間長度即可,就是我們要測量的這段程式碼的執行時間。
那麼直接上示例,為了模擬程式碼執行一段時間,這裡我直接採用之前文章《STM32的四種延時方法》直接延時。
while (1) { GPIO_SetBits(GPIOE,GPIO_Pin_4); //熄滅LED燈 delay_ms(500);//延時500ms GPIO_ResetBits(GPIOE,GPIO_Pin_4);//點亮LED燈 delay_ms(500);//延時500ms }
延時500ms時波形如下
當修改程式碼,延時100ms時
while (1) { GPIO_SetBits(GPIOE,GPIO_Pin_4); //熄滅LED燈 delay_ms(100);//延時100ms GPIO_ResetBits(GPIOE,GPIO_Pin_4);//點亮LED燈 delay_ms(100);//延時100ms }
波形如下
02、定時器測量
定時器不僅僅我們可以實現我們之前講解的《基礎定時功能》《PWM輸出功能》《輸入捕獲功能》《觸控按鍵功能》,還可以用於測量一段程式碼的執行時間。在學習使用定時器測量程式碼執行時間之前,如果對定時器不瞭解的同學先看剛剛提到的定時器的文中,重點文章《STM32基礎定時器簡介》。本篇文章不再講解定時器的基礎功能。
定時器本質上就是向上累加的計數器(如果配置成向上計數時),所以我們在測量開始的程式碼前面讀取定時器的計數器,在結束測量的位置再讀取定時器的計數器,獲得兩次的差值,這樣就可以計算出這段程式碼的執行的時間。這就是簡單的原理,下面直接擼程式碼。
首先配置定時器,這裡我使用定時器3,配置定時器的計數器每增加1,表示100us。並且將溢位值設定為最大。
void TIM_Config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; /* TIM3 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); TIM_TimeBaseStructure.TIM_Period = 0xFFFF-1; TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t) ((SystemCoreClock / 2) / 10000) - 1; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV2; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_Cmd(TIM3, ENABLE); }
測量程式碼執行時間的程式碼如下,這裡進行了防溢位的處理
while (1) { GPIO_SetBits(GPIOE,GPIO_Pin_4); //熄滅LED燈 delay_ms(100);//延時100ms GPIO_ResetBits(GPIOE,GPIO_Pin_4);//點亮LED燈 old_counter = TIM_GetCounter(TIM3); delay_ms(100);//延時100ms couter_current = TIM_GetCounter(TIM3); if(couter_current > old_counter) counter = couter_current - old_counter; else counter = couter_current + 0XFFFF - old_counter; time_ms = counter / 10; }
上述程式碼延時100ms,通過定時器測量結果同樣為100ms,準確無誤。如下所示:
float Time_Difference_ms(void) { static uint32_t old_counter; uint32_t counter,couter_current; couter_current = TIM_GetCounter(TIM3); if(couter_current > old_counter) counter = couter_current - old_counter; else counter = couter_current + 0XFFFF - old_counter; old_counter = couter_current; return (counter / 10); }
這樣就可以實現,測量兩次呼叫這個介面的是時間差,如下,可以準確測得兩次呼叫Time_Difference_ms這個函式的時間差是100ms。