看看硬件工程师是如何写代码的(二),榨干CPU的性能

目前本人已经不再写代码了,只是想把自己走过的弯路,踩过的坑分享出来,希望更多的小伙伴能看到,少走弯路,仅供参考哈!

这章重点给新手们提供一个能最大利用CPU性能的程序架构思路,具体程序就不再展示了。

前言

在学习51单片机或者用51单片机做项目时,由于51单片机的资源配置都是有限的,所以当外围需要实现的功能较多时,就必须要从程序的架构上下功夫,如果使用“单一任务”的思维去写程序,会直接影响效果甚至运行不起来。

架构思路

而在上一篇文章中,我们使用定时器的方式,避免了CPU空等待的情况,没看过的小伙伴可以戳这里:

看看硬件工程师是如何写代码的(一),巧妙的程序!

其实思路也是比较简单的,如下图1所示:

上图中的任务体其实就是CPU在一定的时间内需要“光顾”的事件,比如想让LED在1S的时间做亮灭的动作,那CPU就不用一直“盯着”LED,可以先去做其他“事件”,等1S时间到了之后再去控制LED就行。

举个日常生活的例子:

假如水烧开需要8分钟,那在这8分钟里,我们可以不用一直在等着,我们可以利用这8分钟去做其他事情,比如画板子和写代码都是没问题的,等8分钟到了之后我们再回来把热水壶关掉(现实中热水壶开了会自动断电,这里只是举例说明)。

那在实际的项目中,比如LCD显示屏的刷新和ADC的采集,都是不用CPU一直盯着的,特别是ADC采集转化时是需要时间的,如果ADC转换时间CPU一直在等,那将是致命的,LCD面对的对象是人眼,所以刷新的频率并不需要太快。

还有按键的扫描,数码管的显示等等!

但需要注意的一点就是:CPU不会像人一样,工作起来可以随时停下来,CPU是需要借助“中断”来把CPU“拉回来”,从而实现任务的切换。

如下图1和图2所示

图1

图2

图1和图2是两种不同的方式,图1中CPU在没有任务需要执行的时候,都是在空闲任务里面循环运行,定时器中断隔一段时间把CPU拉回来。不同的任务当满足要求时,就可以获得CPU的“关照”,关照完后就回到空闲任务重进行循环。

图2中,中断可以发生在任何时候,包括任务执行的时候,但是需要提前定义不同任务需要CPU啥时候回来“关照”。一般以200HZ或者100HZ作为“基准”时间,再加上“节拍计数器”让不同的任务获得CPU短暂的“关照”,任务而不至于被CPU“冷落”。

一般来说LCD刷新的频率10HZ左右即可满足,按键做到20HZ基本上不会出现丢键的情况,数码管刷新率做到50HZ左右即可满足人眼的需求。

我们以100HZ作为定时器中断时间,也就是任务切换的基准时间,则:

LCD的节拍数:100HZ/10HZ=10

按键的节拍数:100HZ/20HZ=5

数码管的节拍数:100HZ/50HZ=2

那任务切换代码是如何实现的,其实很简单,只需要在大循环里面用if做判断即可,给每一个任务做条件判断,满足条件即可让CPU执行相应的任务,如下:

while(1)

{

if(task_num[0]==0) task0(); //task0 节拍数到,CPU执行task0

if(task_num[1]==0) task1(); //task1 节拍数到,CPU执行task1

if(task_num[2]==0) task2(); //task2节拍数到,CPU执行task2

if(task_num[3]==0) task3(); //task3节拍数到,CPU执行task3

} 

最后,我们看一下定时中断服务函数里面该怎么写?(省略TH0和TL0部分代码)

void timer0(void) interrupt 1

{

if(task_num[0]) task_num[0]--;

if(task_num[1]) task_num[1]--;

if(task_num[2]) task_num[2]--;

if(task_num[3]) task_num[3]--;

} 

这一类程序的架构思路,中心思想就是把“单一的CPU”划分成“多个CPU”的效果,充分利用CPU的资源,使外围电路较多的项目运行起来更为流畅。

好了,今天就先聊到这吧,以上纯属个人看法,仅供参考!

声明:本内容为作者独立观点,不代表电子星球立场。未经允许不得转载。授权事宜与稿件投诉,请联系:editor@netbroad.com
觉得内容不错的朋友,别忘了一键三连哦!
赞 3
收藏 4
关注 46
成为作者 赚取收益
全部留言
0/200
成为第一个和作者交流的人吧