当前位置:首页 > 消费电子 > 消费电子
[导读]最近刚把 DYS388 项目了结,期间写了不少程序,写着写着想到了一下东西,于是总结了一下。一、什么是占用式程序一个进程在一个时刻只能处理一个任务。每个任务是为了完成一

最近刚把 DYS388 项目了结,期间写了不少程序,写着写着想到了一下东西,于是总结了一下。

一、什么是占用式程序

一个进程在一个时刻只能处理一个任务。

每个任务是为了完成一个功能,如果这个功能的实现过程是一直占用进程处理资源的话,就称这个任务函数是占用式程序结构。

最常见的占用式程序结构就是延时函数了,比如我最常用的5ms延时函数

void delay5(unsigned char n)

{

unsigned int i;

for(;n>0;n--)

for(i=4700;i>0;i--); //12MHz,1T

}

在完成5ms功能过程中是一直占用调用它的进程处理资源的,在此期间不能进行其它任务。

还有一个很常见的占用式程序——数码管扫描,不过在这里我不举数码管扫描的例子,而举这次在DYS388中使用的8*8彩色点阵屏的扫描程序:

void refresh7()

{

unsigned char r;

for(r=0;r<8;r++)< p="">

{

//扫描红色

DPw = ~(0x01<

DPr = ~vm7r[r];//送入R灯IO接口显示

DELAY7 (light7);//显示时间长度

DPw=0xff;

DPr=0xff;

DPg=0xff;

DPb=0xff;

DELAY7 (32-light7);//灭灯时间长度

//为了简洁,这里把绿色和蓝色的扫描程序省略,它们的结构和红色扫描是一样的

}

}

这个函数是7色模式下的屏幕扫描程序,调用一次此函数会把整个屏幕扫描一遍。

r代表行数,r循环8次代表屏幕的8个行;在每次循环里,先导通对应的行和需点亮的灯,然后延时light7个单位,再关闭所有显示,再延时32-light7个单位。

二、占用式程序的缺点

占用式程序最大的缺点就是执行时间太长,耽误对其它任务的响应。另外就是资源浪费,很多时间浪费在执行中的延时上。

当然,可以在这些占用式程序中嵌入其它代码以及时处理其它任务,但是这样会造成程序结构混乱,嵌入的其它代码还会影响本程序的执行。如果嵌入的代码功能简单还好,如果功能复杂,尤其是当嵌入的代码也是占用式的,就会严重影响程序执行速度。

三、对占用式程序的改造

在此以DYS388的扫描程序为例,对其进行改造。

首先,每次调用就扫描8行,耗时太长,现将其改成每次扫描一行:

void refresh7()

{

static unsigned char r=0;

//扫描红色

DPw = ~(0x01<

DPr = ~vm7r[r];//送入R灯IO接口显示

DELAY7 (light7);//显示时间长度

DPw=0xff;

DPr=0xff;

DPg=0xff;

DPb=0xff;

DELAY7 (32-light7);//灭灯时间长度

//为了简洁,这里把绿色和蓝色的扫描程序省略,它们的结构和红色扫描是一样的

r++;

if(r==8)

r=0;

}

用一个静态变量r来记忆行数,这样每次调用此函数只需扫描一行,执行速度是原来的8倍,可以比较快地响应其它任务了。

但是这样还不够,每次扫描都会扫描三种颜色,时间还是有点长,下面再次改造,改为每次只扫描一种颜色:

void refresh7()

{

static unsigned char r=0;

static unsigned char flagrgb=0; //当前需要点亮的颜色,0-R,1-G,2-B

flagrgb++;

if(flagrgb==3) //说明三种颜色都扫描完了

{

flagrgb=0; //从红色开始扫描

r++; //开始扫描下一行

if(r==8) //如果发现行都扫描结束则从第行开始扫描

r=0;

}

switch(flagrgb)

{

case 0: //扫描红色

DPw = ~(0x01<

DPr = ~vm7r[r];//送入R灯IO接口显示

DELAY7 (light7);//显示时间长度

DPw=0xff;

DPr=0xff;

DPg=0xff;

DPb=0xff;

DELAY7 (32-light7);//灭灯时间长度

break;

case 1: //扫描绿色

//省略代码

break;

case 2: //扫描蓝色

//省略代码

break;

}

}

改造完成之后,执行时间再次缩短,变成了刚才的1/3。

这下还没完,我们发现每次扫描中都有延时,延时过程中什么也不做,这是极大的浪费,我们需要再此改造,把延时去掉:[!--empirenews.page--]

void refresh7()

{

static unsigned char r=0;

static unsigned char flagrgb=0; //当前需要点亮的颜色,0-R,1-G,2-B

static unsigned char num=0;

num++;

if(num==32)

{

num=0;

flagrgb++;

if(flagrgb==3) //说明三种颜色都扫描完了

{

flagrgb=0; //从红色开始扫描

r++; //开始扫描下一行

if(r==8) //如果发现行都扫描结束则从第行开始扫描

r=0;

}

}

if(num

{

switch(flagrgb)

{

case 0: //扫描红色

DPw = ~(0x01<

DPr = ~vm7r[r];//送入R灯IO接口显示

break;

case 1: //扫描绿色

DPw = ~(0x01<

DPg = ~vm7g[r];

break;

case 2: //扫描蓝色

DPw = ~(0x01<

DPb = ~vm7b[r];

break;

}

}

else //说明不需要点亮

{

DPw=0xff;

DPr=0xff;

DPg=0xff;

DPb=0xff;

}

}

现在,这个函数中没有任何延时和循环,执行所消耗的时间是非常少的,可以很快地响应响应其它任务。

四、改造的本质

上面我们对DYS388的扫描程序进行了“三大改造”,分别是:1、各个行扫描的分离;2、各个颜色扫描的分离;3、延时函数的消除。

这些改造的本质都是对原程序的分割,把一大坨程序分成多个步骤分别执行,以减小耗时,提高对外部的响应速度。

但就整个进程的执行来看,有效代码的比例是降低的,包括上面“三大改造”的第三点 延时函数的消除,看上去是消除了延时函数,提高了执行效率,但从“扫描一次整屏”这个任务来看,其执行的代码量反而是增加的。(但并不是所有的改造都一定会使效率降低,有些改造确实可以达到“消除延时函数”的目的)

那为什么还要对其进行改造呢,见下节分析。

五、非占用式程序结构的优势

1、非占用式程序相比于占用式程序,增加了一定的代码,虽然会使整体效率降低,但是提高了各个任务之间的切换速度,可以对各个任务都能很快地响应。这点类似于操作系统,虽然降低了效率,但是各个任务间的快速切换可以达到各个任务“并行处理”的效果,光是这点的好处就已经很大了。

2、非占用式程序结构可以放进定时器

之前写过一片《单片机用定时器分配任务程序结构总结》已经发现用定时器分配任务的好处,有些简短的代码可以直接放进定时器里。

在改造之前的扫描程序是不适合放在定时器中断处理程序里执行的,因为太长,可能还没执行完就来了下一个中断。就算勉强执行完了,留给主进程处理其它事情的时间也不多了。

而改为非占用式之后,可以在中断处理程序里直接调用扫描程序,它会很快地执行完,然后有充足的时间留给其他任务。

3、非占用式程序并不是一定会降低效率。

先拿“三大改造”的第三点说明,它虽然形式上消除了延时函数,但是每次调用此函数时对num变量的处理,以及有其产生的相关判断语句,总的代码量比原来的要多。

但是,这真的就仅仅是这样了吗?改造之前的函数,执行玩退出之后所有的led全是熄灭的,只有在此函数执行过程中(延时阶段)才会点亮(传统数码管扫描亦是如此)。

而改造之后的函数,它的功能就是指定一下每个灯的亮灭,然后立马退出,在执行其它任务的过程中该点亮的灯是在点亮的状态。这样就提高了整体的亮度,在执行其他任务的过程中,从某种意义上说也是在执行当前任务。

这可能还不能太清楚地说明问题,下面我要再举一例,传统的按键扫描一般是这样:

if(key==0) //key是某个引脚

{

delay5(1);

if(key==0) //确认按键已按下

{

//do something

}

}

这段代码也是很浪费时间的,中间有个5ms延时拜拜浪费。

通过对它改造之后,结合定时器,可以几乎完全地把这5ms时间省出来:

static unsigned char keylast; //保存上次的按键值

if(key==0 && keylast==1) //检测到一个下降沿

{

//do something

}

keylast=key;

结合定时器进行改造,是真的可以把占用式函数的延时时间节省出来的。

六、非占用式程序的一般结构

非占用式程序将占用式程序分割执行,需要用到静态变量对当前步骤进行记忆,其一般结构如下:

 

 

逻辑变量计算就是根据任务功能构建出一个合理的逻辑结构。

对逻辑变量的响应就是对构建好的逻辑结构的结果的响应和执行。

七、结论

最近开发 DYS388 写了不少程序,以前在写程序的过程中就隐约发现了所谓占用式和非占用式程序结构的区别,程序写多了肯定能发现问题,但是如果不停下来总结,而是一味的开发,那是不会有进步的。

组织庞大的程序需要正确的理论指导,学习很多的知识也需要进行总结。知识点太多不可能学完,只有将他们提升到理论层次,将这种思维方式刻在脑子里才能灵活地运用,并从容地接受新的知识。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

2023年10月18日,中国在第三届“一带一路”国际合作高峰论坛期间发布《全球人工智能治理倡议》,围绕人工智能发展、安全、治理三方面系统阐述了人工智能治理中国方案。

关键字: 人工智能 大模型 代码

我们看到这么多的安全问题,部分原因在于我们对待安全的方式:安全性通常被认为是事后考虑的问题,是在开发结束时才添加到设备上的东西。然而,复杂的系统,尤其是嵌入式系统,有一个很大的攻击面,这让攻击者有机可乘,能够在“盔甲”上...

关键字: 代码 嵌入式系统 软件漏洞

新富人群财务需求多元发展,投顾服务迎来新机遇 上海2023年9月20日 /美通社/ -- 2023年9月19日,上海交通大学上海高级金融学院(高金)与全球领先的金融服务机构嘉信理财(Charles Schwab)联合发...

关键字: BSP ADVANCED INA 代码

北京2023年9月14日 /美通社/ -- 生物医药高科技公司诺诚健华(港交所代码:09969;上交所代码:688428)今日宣布,新型蛋白酪氨酸磷酸酶SHP2变构抑制剂ICP-189联用针对表皮生长因子受体(EGFR)...

关键字: IC HP 代码 ARMA

(全球TMT2023年9月7日讯)9月6日,XREAL举行新品发布会,正式发布最新AR眼镜XREAL Air 2和Air 2 Pro。这两款产品已获国际独立第三方检测、检验和认证机构德国莱茵TÜV大中华区颁发AR产品色...

关键字: AR眼镜 AIR 蓝光 RGB

上海2023年9月1日 /美通社/ -- 2023上半年,安集科技(股票代码:688019)市场拓展规划成效显现,营业收入稳健增长。 全球半导体产业挑战持续存在的情形下,安集科技秉承发扬"克难攻坚,敢打硬...

关键字: 安集科技 BSP 代码 半导体材料

国际酒店运营商升级其在线支付功能 上海2023年8月28日 /美通社/ -- 加拿大金融科技公司Nuvei Corporation(以下简称“Nuvei”或“公司”)(纳斯达克代码:NVEI)(多伦多证券交易所代码:N...

关键字: 代码 IP SE 纳斯达克

2023年上半年收入7.459亿元 同比增长5.1% 毛利率水平上升 海外收入同比增长65.4% 香港2023年8月22日 /美通社/ -- 金邦达宝嘉控股有限公司及其附属公司(以下合称「金邦达」、「...

关键字: 数字化 代码 嵌入式软件 COM

我们经常对正在进行数字化转型的亚马逊云科技客户建议,将云迁移视为其数字化转型的一部分,数字化转型本身必须由业务成果驱动。其中治理计划的有效性决定了云迁移和数字化转型的成功与否。数字化转型中的云迁移总有结束的时候,但是如果...

关键字: 代码 数字化 云服务

广州及苏州生产基地产品均实现"出口"零突破 北京2023年8月21日 /美通社/ -- 百济神州(纳斯达克代码:BGNE;香港联交所代码:06160;上交所代码:688235)是一家全球性生物科技公...

关键字: 神州 代码 TI PD
关闭
关闭