简介:
单片机IO口控制速度是指,在程序中对单片机的某个IO口操作,IO口需要多少时间才能真正的执行,这个数值很重要,因为在某些场合,比如刷屏,如果IO口速度够高,就能提高屏幕的刷新速度。有些场合,比如STC89C52单片机能不能驱动WS2812,这个也是要看WS2812的IO口操作速度的。下图为被测双方的合影留念。两个PCB,一个是2022年10月的作品,一个是2020年4月的作品。
1,测试对象
本文使用51单片机和32单片机进行比较。
51单片机选择STC8H8K64U-LQFP48,使用内部IRC时钟,主频设定为45MHz。
32单片机选择STM32F103VET6-LQFP100,使用外部8MHz时钟,内部倍频后主频为72MHz。
2,测试方法
使用KEIL编写代码,程序主循环while(1)内,写IO=1,IO=0;的翻转程序,连续写多个,降低while(1)执行对程序的干扰。使用示波器测量IO口的波形,测得结果后分析代码的汇编部分,,和测得结果对比分析,得出结论。
3,51单片机测试
使用STC8H8K64U单片机,单片机初始化阶段设置IO口为准双向,进行一些必要的初始化后,单片机一直执行while1的内容,代码如下。
测试引脚为P07引脚,代码中连续写了多个IO口翻转赋值指令。大概20条指令,能让IO口翻转20次,周期计数为10。因为主循环是一直执行的,所以一秒内可以执行很多次。
使用STC-ISP软件,设定本次下载需要修改硬件选项,调整IRC频率,手动输入数字45即可,将代码下载进单片机。
代码下载进单片机后,使用示波器连接单片机P07口,读取示波器的数据。测试结果如下图,频率22.5MHz(频率一直变化,选取最大值),我们看到此时的波形,不是方波,也不是正弦,接近正弦,此时应该是频率太高导致的。不过信号频率还是达到了主频,也就是45M的一半。因为频率计算,是高电平加低电平一起的倒数,所以就是主频的一半了。
当前测试说明STC8H单片机的IO口操作速度是主频。
4,51单片机测试分析
上述测试说明STC8单片机操作IO口的指令为但时钟周期操作,这个也是可以通过KEIL调试验证的,KEIL设置debug使用simulator,然后进入debug模式,就能看到汇编代码了。
因为单片机实际执行的内容就是机器语言,基本等于汇编,我们通过观察汇编,就能知道单片机执行了多少条指令,这个观察C语言是看不出来的。
上图截取的就是主循环的C代码和汇编的混合显示,C语言为我们实际编辑界面的内容,汇编代码则是编译器将C语言编译生成的。
While1的下面是没有汇编代码的,while1对应的代码是在最后一行,SJMP C:165B,这个汇编代码就是让CPU跳转到0X165B的地址执行程序,也就是循环的开始位置。
然后我们看到P07=0;P07=1;的C语言代码,对应的汇编代码则是CLR P07,SETB,P07,这两条执行,都是单时钟周期的指令。所以STC8H单片机IO口的操作速度和实际最高输出速度可以达到主频的速度。
5,32单片机测试
使用STM32F103VET6单片机进行测试,因为32单片机我使用的不多,所以测试起来比51单片机内容多不少,如果下文内容有误,感谢指出。
32单片机有库函数,寄存器开发,我选的一个寄存器开发的闪烁LED程序进行测试。首先就是IO口的初始化,我这里使用的PA0口进行测试,设置PA0口推挽输出,同时为高电平
然后是主函数部分,主循环部分,我测试了3种不同的赋值方式,
第一种是PAout(0)=0;PAout(0)=1;示波器测得频率为6M,那说明32单片机使用此种方式操作IO口的速度是12M,也就是6个时钟周期(72M/12M)
然后我又使用了初始化那里的赋值操作,GPIOA->ODR=1;GPIOA->ODR=0;这里应该是对整个P口赋值,这个具体我没有研究过,反正是PA0口肯定实现了0,1变换。此时示波器测得频率18Mhz,此时的波形和方波比较,失真了不少,快变成正弦波了。那么操作IO口的速度则是36Mhz,也就是2个时钟周期
第三种操作方法:GPIOA->BSRR=1;GPIOA->BRR=1;这个操作方法我不熟悉,示波器测试了一下速度,12M,那么操作IO口的速度是24M,也就是3个时钟周期。
6,32单片机测试分析
32单片机比51单片机复杂不少,操作方式也很多,上边测试,使用了3种代码,速度都不一样,那这里只分析速度最快的那个,也就是2个时钟就能操作IO口的代码。
首先看一下while1,这个while1有两个,一个是C语言代码中的位置,有两条指令。
一个是B 0x080005A0,这个地址是循环结束位置的地址,
另一个是B 0x08000526,这个地址是循环开始的地址,这两个应该是成对出现的。
我们看一下IO口赋值部分,前6次赋值,对应的是13条汇编指令,后边的6次赋值,都是12条指令,多了一个LDR r1,[PC,#120];@0x080005A4,这条指令应该是定位PA口的,之后对PA口操作,不需要再定位。这条指令执行需要多少时钟周期暂不清楚
每次IO口赋值,通用的两个指令是
0x0800059C 2000MOVS r0,#0x00
0x0800059E 6008STR r0,[r1,#0x00]
第一个指令是给寄存器r0赋值,第二个指令应该是把r0寄存器的内容传给r1对应的位置,去实现IO口操作。这里暂时就这么理解了,暂时不想去研究STM32的内容。
这两个指令,应该都是单时钟周期指令(由实验结果得出)。
所以STM32单片机操作的IO口速度能达到主频速度的一半,但是又达不到,因为每次给IO口写数据,还需要先定位到IO口,(这个我不清楚是否可以直接操作IO口,像51单片机那样)这个定位,也是需要时间的,一把情况下,我们可能会来回操作几个IO口,不知道编译器能否在操作其他IO口是,还保留r1,申请新的寄存器。因为不少程序,比如模拟SPI,是需要操作好几个IO口的,时钟引脚和数据引脚使用和切换的很频繁。
目前暂定STM32单片机操作IO口速度最高为2个时钟周期。
7,测试总结
STC8H8K64U单片机,45M主频,IO口翻转速度可达22.5MHz,单片机操作IO口速度为45MHz。
STM32F103VET6单片机,72M主频,IO口翻转速度可达18MHz,单片机操作IO口速度为36MHz。
这个频率已经很高了,目前输出的波形已经失真了。所以得出的结论是51操作IO口速度是和STM32相当的(在本测试条件的情况下)
本测试条件是指:STC8H8K单片机45M频率(基本是最高频率),STM32F103,72M频率,这个应该是常用的频率。
STC的51单片机呢,除了古老的STC89/STC90系列,基本都是单时钟周期操作。(STC32G也是单时钟周期)
STC89/90系列,在使用12M外置晶振的情况下,下载的时候设置双倍速,操作IO口的速度为2M,使用更高频率的外置晶振可以达到更高的IO口操作速度。
当然了,51单片机也有主频上百M的(某些厂家的某些型号),32单片机主频上百M的更多。当单片机主频足够高的时候,他们往往是为了提高运算速度,而非IO口的操作速度。当然IO口的操作速度也会提升。
8,结语
本文好像写了什么,又好像啥也没写,操作IO口最为一个基础的指令,难道不就是一个时钟就能完成吗?我也是这么觉得的。但是实际测试结果,51单片机可以,32单片机不行。但是32单片机运行的频率够高,所以最终的速度相当。
那么就有下一个问题了,既然速度相当,为啥不少人觉得51单片机太菜呢,这里的太菜应该是指STC89C52,我也觉得他很菜,所以我也很少去用。现在的51基本都可以单时钟周期了,不少指令的执行速度大大提升,性能比古老的51提高很多了。这也就是不少人还能接受和使用51单片机的一个原因。
那既然51单片机速度可以这么快了,那为啥还比不上32单片机呢?
51单片机的速度提升呢,他是在8位数据的范围内,但实际情况,我们要操作16位数据,32位数据,去运算,这一点51单片机是不能直接运算的,是通过将这些运算转换为8位的运算去计算的,这样一个计算,就需要好多条指令才能完成。
如果你需要大量的计算,建议选位数多的32位单片机。
如果你就是操作IO口完成一些内容,不需要大量的计算,51单片机可以完成。当然了,基于惯性原因,使用32单片机的可能还是选择32单片机(选择一些低价,高性价比的)
-
单片机
+关注
关注
6032文章
44514浏览量
632929 -
示波器
+关注
关注
113文章
6190浏览量
184507 -
51单片机
+关注
关注
273文章
5697浏览量
123167 -
时钟
+关注
关注
10文章
1720浏览量
131360 -
IO口
+关注
关注
3文章
169浏览量
23994
发布评论请先 登录
相关推荐
评论