上面理论一通,再来点调试技巧。我们需要知道这个函数到底耗时不?
最简单可以使用使用GPIO来计算,将MCU的功耗和IO引脚关联起来分析 不仅可以计算时间还可以计算功耗。
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if (htim == &htim2) {
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); // GPIO 引脚置高
// 中断任务
AD7682_Read_4_ADC_Value(ADC_Value_u16_inter);
IIR_50HZ_Norch_Filter(...);
applyIIRFilter(...);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); // GPIO 引脚置低
}
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if (htim == &htim2) {
uint32_t start_time = __HAL_TIM_GET_COUNTER(&htim3); // 获取定时器开始计数值
// 中断任务
AD7682_Read_4_ADC_Value(ADC_Value_u16_inter);
IIR_50HZ_Norch_Filter(...);
applyIIRFilter(...);
uint32_t end_time = __HAL_TIM_GET_COUNTER(&htim3); // 获取定时器结束计数值
uint32_t elapsed_ticks = (end_time >= start_time) ?
(end_time - start_time) :
((htim3.Init.Period - start_time) + end_time + 1);
float elapsed_time = elapsed_ticks * (1.0f / HAL_RCC_GetPCLK1Freq()); // 转换为秒
}
}
一作差就可以了
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if (htim == &htim2) {
uint32_t start_time = SysTick->VAL; // 记录开始时间
// 中断任务
AD7682_Read_4_ADC_Value(ADC_Value_u16_inter);
IIR_50HZ_Norch_Filter(...);
applyIIRFilter(...);
uint32_t end_time = SysTick->VAL; // 记录结束时间
uint32_t elapsed_ticks = (start_time >= end_time) ?
(start_time - end_time) :
(SysTick->LOAD - end_time + start_time);
float elapsed_time = elapsed_ticks * (1.0f / HAL_RCC_GetSysClockFreq()); // 转换为秒
}
}
还有自带的调试内核,这个时比较高级的技巧,值得重点学习。
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if (htim == &htim2) {
DWT->CYCCNT = 0; // 重置 DWT 计数器
uint32_t start_cycles = DWT->CYCCNT; // 开始时计数值
// 中断任务
AD7682_Read_4_ADC_Value(ADC_Value_u16_inter);
IIR_50HZ_Norch_Filter(...);
applyIIRFilter(...);
uint32_t end_cycles = DWT->CYCCNT; // 结束时计数值
uint32_t elapsed_cycles = end_cycles - start_cycles;
float elapsed_time = elapsed_cycles * (1.0f / SystemCoreClock); // 转换为秒
}
}
其实Keli有个调试组件,Event Recorder
有这个功能,更简单,加个代码就行
在CMSIS里面打开
然后重定向
其实也是使用的DWT
再说吧
安富莱有着详细的教程。代码,三分写,气氛调,不是啥好活。