我的 STM32 到底跑多快?
我在 STM32F103RB 的开发板上, 写如下代码:
uint32_t x = 0x009CF260, y;
while (1) {
if (--x ==0) {
x = 0x009CF260;
y = 1;
if(GPIOA->IDR & 1) y <<= 16;
GPIOA->BSRR = y;
}
}
为什么 x = 0x009CF260? 这是推算出来的, 目的是1秒钟翻转一次 PA0.
怎么推算的呢?
if (SysTick_Config(SystemFrequency / 8)) { while(1);}
设定 1/8 秒一次 SysTick 中断. 由调试器读取寄存器的值.
0x008961ae,0x0075c362,0x00622516...
0x00139E4C,0x00139E4C...
0x00139E4C * 8 = 0x009CF260
那么在 0x00139E4C 个循环里, 到底执行了多少条指令呢? 看下面的编译结果
;;;72 while (1) {
;;;73 if (--x ==0) {
;;;74 x = 0x009CF260;
;;;75 y = 1;
;;;76 if(GPIOA->IDR & 1) y <<= 16;
000070 4909 LDR r1,|L1.152|
000072 4625 MOV r5,r4 ;53
000074 f44f3280 MOV r2,#0x10000
000078 e000 B |L1.124|
|L1.122|
00007a e7fe B |L1.122|
|L1.124|
00007c 1e64 SUBS r4,r4,#1 ;73
00007e d1fd BNE |L1.124|
000080 f8d13808 LDR r3,[r1,#0x808]
000084 462c MOV r4,r5 ;74
000086 2001 MOVS r0,#1 ;75
000088 07db LSLS r3,r3,#31
00008a d000 BEQ |L1.142|
00008c 4610 MOV r0,r2
|L1.142|
;;;77 GPIOA->BSRR = y;
00008e f8c10810 STR r0,[r1,#0x810]
000092 e7f3 B |L1.124|
;;;78 }
;;;79 }
;;;80 }
分析: 从上面的编译结果, 可以看到, 变量 x 被分配给寄存器 R4,
在标号 |L1.124| 后面两条指令, 就执行了 减1 不为零, 再循环的任务.
也就是说, 1 秒钟, 就执行了 0x009CF260 = 10285664 个循环.
通过 SysTick_Config 函数, 可以肯定, 现在的执行频率是 72MHz.
据此推算, 这两条指令的循环需要 7 个周期,
也就是说, 后面的分支跳转指令需要 6 个周期? 有这么慢?
我的 JLINK V8 没有告诉我! |