## 1. 单片机代码运行时间测量方法综述 在嵌入式系统开发中准确测量代码段的执行时间是性能优化和实时性验证的关键环节。本文将详细介绍两种基于STM32平台的实用测量方法并分析其实现原理与工程适用性。 ### 1.1 测量需求分析 典型测量场景包括 - 验证延时函数精度如us级延时 - 评估关键代码段执行效率 - 检测循环周期时间 - 验证中断服务程序执行时间 ## 2. 示波器辅助测量法 ### 2.1 硬件设计原理 通过GPIO电平变化标记被测代码段的起止点 1. 代码段起始GPIO输出高电平 2. 代码段结束GPIO输出低电平 3. 示波器捕获高电平持续时间即为代码执行时间 #### 2.1.1 GPIO配置实现 c // gpio.h #define LOW 0 #define HIGH 1 void GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOB, GPIO_InitStructure); }2.2 SysTick定时器实现采用1μs定时精度的SysTick作为时间基准// systick.h #define SYSTICKPERIOD 0.000001 #define SYSTICKFREQUENCY (1/SYSTICKPERIOD) uint32_t SysTick_Init(void) { if(SysTick_Config(SystemCoreClock / SYSTICKFREQUENCY)){ return 1; } SysTick-CTRL ~(SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk); return 0; } void Delay_us(uint32_t nTime) { SysTick-VAL 0; SysTick-CTRL | SysTick_CTRL_ENABLE_Msk; for(; nTime 0; nTime--){ while(!(SysTick-CTRL SysTick_CTRL_COUNTFLAG_Msk)); } SysTick-CTRL ~SysTick_CTRL_ENABLE_Msk; }2.3 测试验证主函数测试逻辑int main(void) { GPIO_Config(); SysTick_Init(); while(1){ GPIO_SetBits(GPIOB,GPIO_Pin_0); // 测试起点 Delay_us(10); GPIO_ResetBits(GPIOB,GPIO_Pin_0); // 测试终点 Delay_us(100); } }实测数据对比设定值(μs)实测值(μs)误差率12.2120%1011.414%100101-1021-2%3. 定时器直接测量法3.1 TIM2定时器配置采用72MHz时钟实现1μs定时精度void TIM2_Init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_TimeBaseStructure.TIM_Period SystemCoreClock/SYSTICKFREQUENCY - 1; TIM_TimeBaseStructure.TIM_Prescaler 0; TIM_TimeBaseStructure.TIM_CounterMode TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, TIM_TimeBaseStructure); TIM_ARRPreloadConfig(TIM2, ENABLE); }3.2 时间测量实现通过捕获定时器计数值计算执行时间void Delay_us(uint32_t nTime) { TIM2-CNT 0; TIM_Cmd(TIM2, ENABLE); for(; nTime 0; nTime--){ while(!TIM_GetFlagStatus(TIM2, TIM_FLAG_Update)); TIM_ClearFlag(TIM2, TIM_FLAG_Update); } TIM_Cmd(TIM2, DISABLE); }3.3 调试接口验证通过Watch窗口观察计数值TimingVarTypeDef Time; int main(void) { TIM2_Init(); SysTick_Time_Init(Time); while(1){ SysTick_Time_Start(); Delay_us(1000); SysTick_Time_Stop(); } }计算示例计数值 0x119B8 (72120) 时钟周期 1/72MHz 执行时间 72120 * (1/72,000,000) 1.001ms4. 方法对比与工程选择4.1 性能参数对比指标示波器法定时器法最大测量范围受示波器限制59.65秒(32位)测量精度1μs级1μs级系统侵入性低中调试便利性需硬件设备纯软件实现4.2 工程选择建议快速验证场景优先选择示波器法硬件改动小仅需1个GPIO不占用定时器资源实时可视化结果长期监测场景考虑定时器法适合无示波器环境可集成到最终产品中支持自动化测试5. 精度优化建议消除测量系统误差GPIO操作耗时补偿约0.5μs中断延迟影响评估多次测量取平均值临界条件处理测量超长代码段时切换定时器分频关键代码段测量时关闭全局中断扩展应用结合DMA实现无干扰测量使用TRACE接口实现非侵入式测量
STM32代码执行时间测量方法与优化
发布时间:2026/5/18 0:33:41
## 1. 单片机代码运行时间测量方法综述 在嵌入式系统开发中准确测量代码段的执行时间是性能优化和实时性验证的关键环节。本文将详细介绍两种基于STM32平台的实用测量方法并分析其实现原理与工程适用性。 ### 1.1 测量需求分析 典型测量场景包括 - 验证延时函数精度如us级延时 - 评估关键代码段执行效率 - 检测循环周期时间 - 验证中断服务程序执行时间 ## 2. 示波器辅助测量法 ### 2.1 硬件设计原理 通过GPIO电平变化标记被测代码段的起止点 1. 代码段起始GPIO输出高电平 2. 代码段结束GPIO输出低电平 3. 示波器捕获高电平持续时间即为代码执行时间 #### 2.1.1 GPIO配置实现 c // gpio.h #define LOW 0 #define HIGH 1 void GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOB, GPIO_InitStructure); }2.2 SysTick定时器实现采用1μs定时精度的SysTick作为时间基准// systick.h #define SYSTICKPERIOD 0.000001 #define SYSTICKFREQUENCY (1/SYSTICKPERIOD) uint32_t SysTick_Init(void) { if(SysTick_Config(SystemCoreClock / SYSTICKFREQUENCY)){ return 1; } SysTick-CTRL ~(SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk); return 0; } void Delay_us(uint32_t nTime) { SysTick-VAL 0; SysTick-CTRL | SysTick_CTRL_ENABLE_Msk; for(; nTime 0; nTime--){ while(!(SysTick-CTRL SysTick_CTRL_COUNTFLAG_Msk)); } SysTick-CTRL ~SysTick_CTRL_ENABLE_Msk; }2.3 测试验证主函数测试逻辑int main(void) { GPIO_Config(); SysTick_Init(); while(1){ GPIO_SetBits(GPIOB,GPIO_Pin_0); // 测试起点 Delay_us(10); GPIO_ResetBits(GPIOB,GPIO_Pin_0); // 测试终点 Delay_us(100); } }实测数据对比设定值(μs)实测值(μs)误差率12.2120%1011.414%100101-1021-2%3. 定时器直接测量法3.1 TIM2定时器配置采用72MHz时钟实现1μs定时精度void TIM2_Init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_TimeBaseStructure.TIM_Period SystemCoreClock/SYSTICKFREQUENCY - 1; TIM_TimeBaseStructure.TIM_Prescaler 0; TIM_TimeBaseStructure.TIM_CounterMode TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, TIM_TimeBaseStructure); TIM_ARRPreloadConfig(TIM2, ENABLE); }3.2 时间测量实现通过捕获定时器计数值计算执行时间void Delay_us(uint32_t nTime) { TIM2-CNT 0; TIM_Cmd(TIM2, ENABLE); for(; nTime 0; nTime--){ while(!TIM_GetFlagStatus(TIM2, TIM_FLAG_Update)); TIM_ClearFlag(TIM2, TIM_FLAG_Update); } TIM_Cmd(TIM2, DISABLE); }3.3 调试接口验证通过Watch窗口观察计数值TimingVarTypeDef Time; int main(void) { TIM2_Init(); SysTick_Time_Init(Time); while(1){ SysTick_Time_Start(); Delay_us(1000); SysTick_Time_Stop(); } }计算示例计数值 0x119B8 (72120) 时钟周期 1/72MHz 执行时间 72120 * (1/72,000,000) 1.001ms4. 方法对比与工程选择4.1 性能参数对比指标示波器法定时器法最大测量范围受示波器限制59.65秒(32位)测量精度1μs级1μs级系统侵入性低中调试便利性需硬件设备纯软件实现4.2 工程选择建议快速验证场景优先选择示波器法硬件改动小仅需1个GPIO不占用定时器资源实时可视化结果长期监测场景考虑定时器法适合无示波器环境可集成到最终产品中支持自动化测试5. 精度优化建议消除测量系统误差GPIO操作耗时补偿约0.5μs中断延迟影响评估多次测量取平均值临界条件处理测量超长代码段时切换定时器分频关键代码段测量时关闭全局中断扩展应用结合DMA实现无干扰测量使用TRACE接口实现非侵入式测量