最近一个工程师问我 MCU 的最高翻转速度能够到多少?这个话题我多年前就听过,不过一直没有实际去测试过,这次正好借此问题实际测试了一番,发现里面还藏了不少的知识。
本次测试选取了目前市面上性价比极高的 3 款 32 位 ARM Cortex-M0/M0+内核 MCU,分别是灵动微 MM32G0001、普冉 PY32F002B、芯源 CW32L010,价格都在 5 毛钱以内!
首先测试的是灵动微的 MM32G0001 MCU,该 MCU 基于 ARM Cortex-M0 内核,最高工作频率可达 48MHz。系统架构图如下:
可以看到 GPIO 模块位于 AHB 总线上,AHB 总线的最高速率为 48Mhz。GPIO 翻转就是高低电平变换,执行一条电平控制的 STR 汇编指令是 2 个指令周期,所以理论上该 MCU GPIO 最大的翻转速率是 48Mhz/(2+2)=12Mhz。下面我们来看看实测情况,
测试代码基于灵动微官网提供的:LibSamples_MM32G0001_V0.10.2\Samples\LibSamples\GPIO\GPIO_LED_Toggle 例程。
该示例时钟配置的就是 48Mhz。我们进行以下几个实验:
实验 1:原始代码做如下修改,注释掉不相关代码,while(1)里只保留一个 GPIO 翻转函数。
测试结果只有 289Khz。
实验 2:把优化等级从 0 开到最高:
测试结果是 333Khz。
以上 2 个实验测出来的速率远低于理论值,主要是和函数调用有关系,占用了很多额外的时间。
实验 3:这次直接改为操作寄存器的方式实现,为保证测试一致性,优化等级还是调整回 0。
测出来的结果是 4Mhz,速率明显提升。
可是为什么低电平时间要比高电平时间多了那么多呢。经过分析可知是 while(1)循环占用了额外的时间。
实验 4:在实验 3 的基础上改进一下,while(1)多增加几条重复的语句。
测试翻转期间的速率为 12Mhz,这样就达到了理论上的最大速率。
第二个测试的是普冉的 PY32F002B MCU,该 MCU 基于 ARM Cortex-M0+内核,最高主频 24MHz。系统架构图如下:
可以看到这个 MCU 的 GPIO 是直接挂到内核上,它具备单周期快速翻转的能力。单周期 GPIO 是 ARM Cortex-M0+内核所特有支持的一个功能,M0 内核 MCU 没有此功能。所以该款 MCU GPIO 翻转最大速率理论值为:24Mhz/(1+1)=12Mhz。下面我们来看下实际测试结果。
PY32F002B_Firmware_V1.1.0\Projects\PY32F002B-STK\Example_LL\GPIO\GPIO_FastIO 直接提供了测试例程,什么都不用改,下载进去就可以测试,
可以看到 IO 翻转速率确实达到了 12Mhz。
C:Userswangwx1Desktop 普冉 12Mhz.jpg
虽然 PY32F002B 最高主频相比 MM32G0001 只有其一半,但是因为其直接挂在内核上,具备单周期翻转能力,所以两者的最高 IO 翻转速率都是 12Mhz。
最后再来看芯源的 CW32L010 MCU,这颗 MCU 也是 Cortex-M0+内核,但是其 GPIO 并没有像 PY32F002B 直接挂在内核上,而是挂在 AHB 总线上。该 MCU 最高主频也是 48Mhz。
有了上述测试基础,你是不是能够猜到该 MCU 的最大翻转速率了,你可能会认为和灵动微 G0001 一样也是 12Mhz。事实果真如此吗?
我们基于 CW32L010_StandardPeripheralLib_V1.0.2ExamplesGPIOgpio_blink 做了简单修改,该例子默认跑的是 4Mhz 主频,将其修改为 48Mhz
实际测试结果只有 8Mhz,这是什么原因呢?我们可以看到低电平时间是 2 个指令周期,但是高电平时间却是 4 个指令周期。
这是因为 Flash 读等待所导致的,当主频大于 24Mhz 之后,需要插入 1 个等待周期,所以无法保证每个翻转都能达到 2 个指令周期。
我们可以再做一个测试,将其主频降低为 24Mhz,可以看到此时 GPIO 翻转速率可以达到 6Mhz,这是因为没有 flash 读等待周期了。
最后再做一个测试,把上述翻转 GPIO 的代码做一点修改,上述用了 BSRR、BRR 寄存器来实现置位和清零,如果使用 ODR 寄存器会有什么效果呢?
可以看到,翻转速率直接只有 4Mhz。
通过汇编代码可以看到,多了一条 MOVS 指令,该指令需要 1 个指令周期,所有最高翻转速率为 24Mhz/(3+3)=4Mhz
除了置位/清零寄存器、输出数据寄存器实现 GPIO 翻转外,有的 MCU 还有翻转寄存器,比如 CW32L010 有,MM32G0001 和 PY32F002B 没有,直接用这一个寄存器就可以实现 IO 翻转,实测这个效果和 BSRR/BRR 一样。
由此可见,影响 MCU GPIO 翻转速度的因素有很多,包括系统主频、是否支持单周期翻转、Flash 读等待、翻转语句写法、编译器优化等级等多个因素。
最后再留一个问题供大家思考,为什么芯源 CW32L010 和灵动微 MM32G0001 同样都是跑 48Mhz 最高主频,芯源 CW32L010 无法达到理论值 12Mhz 但是灵动微 MM32G0001 却可以达到呢?
END
作者:TopSemic
来源:TopSemic嵌入式
推荐阅读
欢迎大家点赞留言,更多 Arm 技术文章动态请关注极术社区嵌入式客栈专栏欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。