大家好,我正在尝试测量完成执行一个功能所用的时间。我不能使用定时器,因为它会给系统增加一些延迟。我的另一个选择是使用 GPIO 引脚。
为此,我
在函数的开头设置一个引脚
在函数末尾重置一个引脚
然后我使用示波器测量引脚的开关时间。
为了在没有太多延迟的情况下打开和关闭 GPIO,我使用了汇编代码来确保仅使用几条指令来启用和禁用 GPIO。
- void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) //called every 4 us.
- {
- __asm__ volatile (
- //turn on GPIO E2
- "LDR R1, =0x40021014;"
- "LDR R0, [R1];"
- "ORR.W R0, #0x0004;" //only set pin 2
- "STR R0, [R1];" //write data to memory
- //write data to data memory
- "LDR R3, =0xD0007260;"
- "LDR R2, [R3];"
- "LDR R2,=0xFF000000;"
- "STR R2, [R3];" //write data to memory
- //turn off GPIO E2
- //"LDR R5, =0x40021014;"
- //"LDR R4, [R5];"
- "AND.W R0, #0xFFFFFFFB;" //only clear pin 2
- "STR R0, [R1];" //write data to memory
- );
- }
然而生成的代码看起来像下图...
使用此生成的代码,示波器的 GPIO 引脚产生了一个宽度不同的脉冲,如下图所示

从我上面的汇编代码来看,脉冲宽度应该或多或少相同,因为我每个周期运行相同数量的指令。但我不知道为什么我不能让编译器遵循我在 C 程序中编写的汇编代码。
最终,我试图实现一个非常轻的代码来打开/关闭 gpio 引脚,以便我可以准确地测量一个函数所花费的时间。我试图实现的代码如下所示
- void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) //called every 4 us.
- {
- //read GPIO E ODR address
- __asm__ (
- "LDR R1, =0x40021014;"
- "LDR R0, [R1];"
- );
- //Turn on GPIO E2
- __asm__ (
- "ORR.W R0, #0x0004;" //only set pin 2
- "STR R0, [R1];" //write data to memory
- );
- //example function
- BSP_LCD_DrawPixel(120, 60, LCD_COLOR_BLACK);
- // Turn off GPIO E2
- __asm__ (
- "AND.W R0, #0xFFFFFFFB;" //only clear pin 2
- "STR R0, [R1];" //write data to memory
- );
- }
最后,我的编译器设置为 Optimization Fast,我使用的是 Atollic Truestudio。系统中只有一个中断,即 ADC 转换完成。
如果您需要任何其他信息,请告诉我。谢谢阅读!
EDIT1:有谁知道为什么编译后的汇编代码与我的内联汇编代码不同?我希望这部分汇编代码不要被编译器优化触及/修改,同时仍然使用优化速度选项。