最近一个工程师问我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。
虽然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却可以达到呢?欢迎评论区留言。
关注我们:
扫码加入嵌入式交流群: