找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1766|回复: 10
打印 上一主题 下一主题
收起左侧

忽略系统的前提下,单片机新手如何提高程序的执行效率

[复制链接]
跳转到指定楼层
楼主
ID:136119 发表于 2022-8-5 09:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在忽略系统的前提下,如何使自己写到代码更美观,运行效率更高。是一个初级开发人员的追求。
追求代码美观和代码可读性,我们要学会善于用结构体和指针,结构体能有效的帮助我们表达复杂的变量关系和复杂的变量定义,当你习惯用time1、time2、time3……定义变量名的时候,推荐你可以思考一下用结构体,是否满足你的需求。
本次话题主要讲的是提高代码的执行效率,那么如何才能使代码执行效率更高了,最简单粗暴的方式就是减少延时函数的调用。减少函数调用后,相对程序执行效率就会高一些。
那么还有其它更好的方式吗?当然有了,比如有段代码需0.1s执行一次,我们就让0.1秒执行一次,如果代码需要0.5秒执行一次就让他0.5秒执行一次,这样单片机就能更好的执行其它代码了,如果代码按照你设想时间运行,并且你们没有使用延时函数。你的代码执行效率会提升很多。

话不多说直接上思路和代码。首先跟着我来了解一个结构体。
         typedef struct
         {
         unsigned short int  time; // 定义一个时间变量,它用来判断何时进入函数,目的是减少代延时函数调用(8位单片机只能,定义8位数据,16或32数据会因中断打扰导致数据赋值出错。)
         unsigned char  label;  // label用来记代码执行到那个阶段了,
unsigned char  value ;  // 用来记录,你想要的值,或者其它什么概念的东西。当然你可以删除
         } AP_APP;         

定义一个指示灯结构体变量,
AP_APP  AP_LED ; 我想他看上去很简单对吧。
在while(1)循环体中定义指示灯函数
         VoidFun_Led(void)
{        
if(AP_LED.time==0 )
{
AP_LED.time  =  250 ; // AP_LED.time标记什么时间进入当函数,类似延时函数,中断中需要对--AP_LED.time处理。         
IO_LED  =  ~ LO_LED;//这个只是端口取反后再次输出。
}
}
这就是一个指示灯函数,看上去是不是比较简单。
我们再来假设一个中断,是每2ms进入一次,中断里面我们这样写
Void 中断服务函数(void) //每2ms进入一次
{
if(AP_LED.time != 0xFFFF )  // AP_LED.time 不等0xFFFF。我们进入函数
{                                           //等于0xFFFF 你可以设想先一下出现什么情况。
                   if(AP_LED.time)  --AP_LED.time; // 我们每过2ms,减去一个值,一直到变量
//等于0。等于0后再进入Fun_Led内部函数执相关代码
}
}
当前的程序没有使用延时函数,能很好的控制LED的亮灭时间,提高我们代码执行效率。看上去也比较简单。
我们很明确的知道程序不使用延时函数,我们的其他代码执行效率就会提高,

我起初定义了一个结构体,其中有个AP_LED. label,AP_LED. label我在这里表示程序运行到哪里了,或者简单说状态机。
还是led控制,例如我想控制LED亮时间和灭的时间不同,我们可以调整程序如下
         VoidFun_Led(void)
{        
if(AP_LED.time==0 )
{
switch (AP_LED. Label)
{
                  Case 1 :
                            AP_LED.Label =2;
IO_LED = 1;
AP_LED.time  =  50 ; // 进入下一次LED状态的间隔时间
                            break;
                  case 2 :
                            AP_LED.Label =3;
IO_LED = 0;
AP_LED.time  =  100 ; //进入下一次LED状态的间隔时间
                            break;
                  Case 3:
                            AP_LED.Label =4;
IO_LED = 1;
AP_LED.time  =  150 ; // 进入下一次LED状态的间隔时间
                            break;
                  case 4:
                            AP_LED.Label =1;
IO_LED = 0;
AP_LED.time  =  200 ; //进入下一次LED状态的间隔时间
                            break;
                  default:    //刚开机或者其它情况进入当前信息
                            AP_LED.Label =1;
AP_LED.time  =  250 ; // AP_LED.time标记什么时间进入当函数。
                           break;
}
}
}
当我们遇到一个复杂的代码,并且每个动作执行时间不定长度的时候,当前的结构形式更为简单一些,更方便我们理解。
关于AP_LED. Value我也很少用,但是不表示我不用,当上一个代码中在嵌套一个switch (AP_LED. Value),或者在其它函数中获取,读取或者标记一些状态,传递一些消息都会用上。这个我就不多说了,你喜欢就看看移植一下,理解了就是最适合你的。

如果有人喜欢 我下次讲解我的按键代码

http://www.51hei.com/bbs/dpj-215832-1.html  5楼,这也是一个不错的代码,最起码我是这样理解的。

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:883242 发表于 2022-8-5 22:27 | 只看该作者
switch/case那部分写的太啰嗦了,简单的查表就行。楼主的水平还达不到传道受业解惑的程度。
回复

使用道具 举报

板凳
ID:824490 发表于 2022-8-6 17:41 | 只看该作者
switch (AP_LED. Label)这段这么有规律,可以优化掉!
回复

使用道具 举报

地板
ID:824490 发表于 2022-8-6 17:43 | 只看该作者
续上贴:
IO_LED = AP_LED.Label % 2;
AP_LED.time =  AP_LED.Label *50;
AP_LED.Label ++;
AP_LED.Label = AP_LED.Label % 5;
回复

使用道具 举报

5#
ID:401564 发表于 2022-8-7 14:55 | 只看该作者
我一直不明白,为什么很多人都要提高单片机的运行效率?有什么意义呢?
这总得看场合的吧,如果一个程序要做的东西并不多,提高效率的意义何在?
这一堆代码,让我感觉原本应该可以很简单的东西,看起来好恐怖
回复

使用道具 举报

6#
ID:123289 发表于 2022-8-7 22:35 | 只看该作者
学会汇编语言,就知道如何做效率高了。
回复

使用道具 举报

7#
ID:420836 发表于 2022-8-7 23:59 | 只看该作者
对于一个单片机程序员的初学者来说,最重要的是让每一行代码都正确,因为对于一个没有经验的程序员来说,调试代码是一个挑战。
回复

使用道具 举报

8#
ID:136119 发表于 2022-8-8 08:28 | 只看该作者
怎么说了,你们都是对的,只是当前你们没有遇到,对应代码需求, 理解就行
回复

使用道具 举报

9#
ID:1034262 发表于 2022-8-8 17:43 | 只看该作者
程序架构要合理,程序中不要用软件延时。
回复

使用道具 举报

10#
ID:811253 发表于 2022-8-13 11:32 | 只看该作者
用定时器代替延时就能提升效率了
回复

使用道具 举报

11#
ID:139866 发表于 2022-8-17 10:34 | 只看该作者
需要提高执行效率,只有在比较精细的项目中才会考虑,有可能让新手接手这种项目的公司,我觉得项目经理心可能很大
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表