#申请原创# @21小跑堂
1 背景
近期有小伙伴讨论到APM32F103ZE的GPIO翻转速度极限值是多少?他用C语言的GPIO翻转速度远远达不到。本文章对APM32F103ZE的GPIO翻转速度的最大值的测试过程进行梳理分享。
2 APM32F103ZE基本规格
首先我们先去确认一下APM32F103ZE基本规格:
1. 主频:96MHz
2. GPIO处于APB2时钟上,最大频率支持96MHz。
注:我的测试平台是APM32F103ZET6 MINI板,测试引脚是PE5/PE6。
3 GPIO翻转频率测试
常见的GPIO翻转的测试非常简单,使用C语言编写,深究底层就是控制其输出寄存器,不断重复输出0/1此时便是翻转。但我们这里是测试极限速度,我们需要注意主频(包括GPIO所在的APB2时钟)要求是最高,GPIO模式什么的也要求设置为最高值。
梳理我们的需求,输出我们的测试步骤:
1. 设置主频为96MHz。
2. AHB与APB2不分频。
3. GPIO初始化为推挽输出模式、速度设置为50MHz。
4. 设置GPIO的BSC与BC寄存器(或者是ODATA寄存器),使其交替输出0/1。
3.1 C语言函数版本
这个版本的测试代码与我们LED闪烁的频率并无不同,仅是把延时取消掉即可。
代码直接调用:APM_MINI_LEDToggle函数即可。
测试情况如下:
发现速度仅1MHz这样而已。
难道速度仅此而已了么?由于C语言的函数调用是有一定的消耗(函数的调用涉及出栈入栈等消耗)。那我们进阶一下呢?直接操作寄存器呢?
3.2 C语言寄存器版本
我们把C语言库函数最深层的内容的寄存器表达直接写在main函数里面的while循环里 面,以减少由于函数的调用的损耗。
参考代码如下:
APM_MINI_LEDInit(LED2);
APM_MINI_LEDInit(LED3);
while (1)
{
{// 这两者是一致的
// GPIOE->ODATA = 0x00000060;
// GPIOE->ODATA = 0x00000000;
GPIOE->BSC = 0x00000060;
GPIOE->BC = 0x00000060;
}
}
我们查看示波器:
我们发现,频率确实有所提升但是这个波形十分奇怪:理论上的高低电平的占比比是不一致的。为什么呢?
我们查看一下反汇编代码:
如图所示,我们发现使得GPIO翻转的汇编指令分别为第3/5条的STR指令,这两个指令直接的间隔指令数量并不一致,所以导致了最终输出的波形占空比有问题:
1. 指令3至指令5:中间间隔指令4。
2. 指令5至指令3:中间间隔指令6、1、2。
3.3 汇编版本1
为了测试极限值,我们把翻转GPIO的功能写成汇编代码,汇编代码的加入大家可以查阅网上的资料。我这里直接新建一个.s文件,在该文件中编写测试的代码。
在测试函数1中,我们把寄存器的赋值等内容放在循环外面,循环中仅进行GPIO的翻转,不做其他事情。
参考代码如下:
gpio_toggle_speed_1 PROC
LDR R0, =0x40011800 ; Load the address of GPIOE ODR into R0
LDR R1, =0x60 ; Load the toggle value into R1
toggle_1
STR R1, [R0, #0x10] ; Store R1 into GPIOE BSRR register (Set bits)
STR R1, [R0, #0x14] ; Store R1 into GPIOE BRR register (Reset bits)
B toggle_1 ; Branch unconditionally to 'toggle' label
ENDP
测试波形如下:
频率进一步提高,但是占空比依旧有所问题,那消耗在哪里呢?是的,正如前文所说,跳转指令“B”导致的。
3.4 汇编版本2
由此,我们把翻转的代码增多,这样子相比之下跳转指令的影响就减少了。
频率来到了24MHz左右!那这个会不会是最高频率了呢?我们把主频提升至120MHz(超频),发现频率已经无法上升,或者设置其程序运行至RAM也无法提升。
4 测试总结
按照本文的测试方法,APM32F103ZE的GPIO翻转理论最大速度基本为24MHz这样。你有什么好的测试方案么?欢迎在评论区留言。
这里是代码
APM32GPIO极限翻转速度测试_code.zip
(2.17 MB)
。
|
@21小跑堂 :小跑堂是技术人员吗?很懂呀
@21小跑堂 :感谢支持。
@21小跑堂 :IO的翻转需要可控制:我需要是1就应该是1,需要0就是0。MCO和定时器输出PWM都是不可控制的(它们的输出是周期性的)。 这个IO翻转其实有许多的应用场景,如模拟SWD时序,如果使用PWM或者MCO去操作。模拟逻辑就非常复杂,如果是用IO翻转的,逻辑就很好控制了。
一个很常见的问题,也是一个很有意思的实验,通过汇编尽可能减少指令跳转的影响,测量IO翻转速率。24MHz真的是极限吗?二姨可是记得作者本人发过一篇MCO的原创哦,这个是否也是IO的翻转效果呢。