您的位置 首页 设计

浅谈单片机程序设计中的“分层思维”

“分层思想”并不是什么神秘的东西,事实上很多做项目的工程师本身自己也会在用。看了不少帖子都发现没有提及这个东西,然而分层结构确是很有用的东西,参透后会有一种恍然大悟的感觉。

  “分层思维”并不是什么奥秘的东西,事实上许多做项意图工程师自身自己也会在用。看了不少帖子都发现没有提及这个东西,可是分层结构确是很有用的东西,参透后会有一种茅塞顿开的感觉。假如说我不明白LCD怎样驱动,那好办,看一下datasheet,参阅一下他人的程序,很快就能够做出来。可是假如不明白程序规划的思维的话,会给你做项意图过程中带来许多许多的困惑。

  参阅了市面上各式各样的嵌入式书本,MCS-51,AVR ,ARM 等都有看过,可是没有发现有哪本是介绍规划思维的,就算有也是百里挑一。写程序不难,可是程序怎样样才能写的好,写的快,那是需关键阅历堆集的。结构化模块化的程序规划的思维,是最基本的要求。可是怎样将这个笼统的概念运用到工程实践傍边呢?那需求在做项意图过程中阅历苦难,将一些东西总结出来,笼统升华为理论,对阅历的堆集和技能的传达都大有裨益。所以鄙人出来献丑一下,总结一些东西。就我个人的阅历而谈,有两个规划思维是十分重要的。

  一个便是“时刻片轮的规划思维”,这个对实践中处理多任务问题十分有用,一般能够用这个东西来判别一个人是单片机学习者,仍是一个单片机工程师。这个有必要把握。由于网上介绍这个的帖子也不少,所以这儿就不多说了。

  第二个便是我今日想说的主题“分层屏蔽的规划思维”。下面用扫描键盘程序比方作为引子,引出今日说的东西。

  问题的提出 :单片机学习板一般为了简略起见,将按键分配的很好,例如整个 4*4 的键盘矩阵分配到P1口上面,8条控制线,刚好。这样的话程序也十分好写。只需求简略的

  KEY_DAT = P1;

  端口的数据就读进来了。固然,实践中没有这么好的作业。在实践的项目运用傍边,单片机引脚的复用恰当凶猛,这跟那些所谓的单片机学习板就有很大的不同了。

  别的一个原因,一般规划来说,是“软件合作硬件”的规划流程,简略点说便是,先确定好硬件原理图,硬件布线,最终才是软件的开发,由于硬件修正起来比较费事,相对来说软件修正的时分比较好改。这个便是中国传统的阴阳平衡哲学原理。硬件规划和软件规划原本便是鱼和熊掌的联系,两者不行兼得。便利了硬件规划,很或许给写软件带来很大的费事。反过来说,便利了软件规划,硬件规划也会恰当的费事。假如硬件规划和软件规划一起便利了,那只有两种或许,一是这个规划方案十分简略,二是规划师现已到达了一个十分高的境地。咱们不考虑那么多状况,单纯从常用的实践运用的视点来看问题。 硬件为了布线的便利,许多时分会或许将IO口分配到不同的端口上面,例如上面说的4*4键盘,8根线别离分配到 P0 P1 P2 P3 上面去了。那么,开发板的那些扫描键盘程序能够去见鬼了。怎样扫按键?我想起了我刚开端学习的时分,分红3段十分相似的程序,一个一个按键的扫描的阅历…… 或许有人不甘心,“那些东西我花了很长时刻学习的,也用的好好的,怎样能说一句不必就不必?”虽然有点残暴,可是我仍是想说“兄弟,承受实践吧,实践是严酷的……”

  不过,人差异于低等动物的不同,是人会发明,在碰到困难的时分会想办法处理,所以咱们开端了深思…… 后咱们引进初中数学学的“映射”的概念来处理问题。基本思维便是,将不同端口的按键映射到相同端口上面。

  这样按键扫描程序就分红3个层次了。

  1)最底层的是硬件层,完结端口扫描,20ms延时消抖,将端口的数据映射到一个KEY_DAT寄存器上面,KEY_DAT作为对上层驱动层的一个接口。

  2)中心的一层是驱动层,驱动层只对 KEY_DAT 寄存器的数值进行操作。简略点说,咱们不论底层的硬件是怎样接线的,在驱动层都不需求关怀,只需求关怀 KEY_DAT 这个寄存器的数值是什么就能够了。这样出来的直接作用便是“屏蔽了底层硬件的差异”,所以驱动层写的程序就能够通用了。驱动层的别的一个功用是为了上层供给音讯接口。咱们用了相似window程序的音讯的概念。这儿能够供给一些按键音讯,例如:按下音讯,松开音讯,长按键音讯,长按键的时分的步进音讯,等等。

  3)运用层。这儿便是依据项意图不同别离写按键功用程序,归于最上层的程序。它运用的是驱动层供给的音讯接口。在运用层写程序的思维便是,我不论基层是怎样作业的,我只关怀按键音讯。有按键音讯来的时分我就履行功用,没有音讯来的时分,我就什么也不做。

  下面用一个简略的常用的比方,阐明咱们这个规划思维的用法。秒表调整时刻的时分,要求按着某个按键不放,时刻能接连的向上添加。这个东西很有用,实践的家电中用处很广泛。在看下面的东西之前,我们能够想一下,这东西难吗?信任我们都会很嘹亮的答复,“不难!!”,可是我再问:“这东西费事吗?”我信任许多人必定会说“很费事!!” 这不由让我想起开端学单片机的时分写这种按键的那程序,杂乱无章的结构。假如不信任的话,能够自己用51写一下哦,那样就愈加能领会本文说的分层结构的优越性。

  项目要求:两个按键,别离分配在P10 和P20,别离是“加”“减”按键,要求长按键的时分完结接连加和接连减的功用。

  实战:假定:按键上拉,没有按键的时分高电平,有按键的时分低电平,别的,为了杰出问题,这儿没有将延时消抖的程序写上去,在实践项目中应该加上。C言语函数参数的传递多种多样,这儿作为比方,用了最简略的全局变量来传递参数,当然你也能够用 unsigned char ReadPort(void) 回来一个读键成果,乃至还能够 void ReadPort(unsigned char *pt) 用一个指针变量传递地址而到达直接修正变量的意图。办法是多种多样的,这个决定于每个人的程序风格。

  1)开端写硬件层程序,完结映射

  #define KYE_MIN 0X01

  #define KEY_PLUS 0X01

  unsigned char KeyDat;

  void ReadPort(void)

  {

  if (P1 & KEY_PLUS == 0 ){

  KeyDat |= 0x01 ;

  }

  if (P2 & KEY_MIN == 0 ){

  KeyDat |= 0x02 ;

  }

  }

  C言语应该很简略看懂吧?假如 KEY_PLUS 按下,P10口读到低电平,则 P1 & KEY_PLUS 的成果为 0 ,满意if 的条件,进入KeyDat |= 0x01 是将 KeyDat 的bit0 置一,也便是说,将 KEY_PLUS 映射到 KeyDat 的 bit0

  KEY_MIN 是相同的道理映射到 KeyDat 的 bit1

  假如 KeyDat 的 bit0 为 1 ,则阐明 KEY_PLUS 按下,反则亦然。

  不需求想的很奥秘,映射便是这么一回事。假如还有其他按键的话,用相同办法,将他们悉数映射到 KeyDat 上面。

  2)驱动层程序编写 【【硬件层给驱动层供给最基本的一些屏蔽掉底层的一些硬件的相关数据,这样能够把硬件层的数据结构(比方这儿是KeyDat)供给给驱动层,驱动层担任调用硬件层,运用层担任调用驱动层】】

  假如将 KeyDat幻想成 P1 口,那么这个跟学习板那规范的扫描程序不便是相同了吗?对的,这个便是底层映射的意图了。

  3)运用层程序编写

  依据音讯,硬件层是有必要别离出来,可是驱动层和运用层的要求就不那么严厉了,事实上一些简略的项目没有必要将这两层别离开来,依据实践运用灵敏应对就能够了。其实这样写程序是很便利移植的,依据板子的不同而恰当的修正一下硬件层那个 ReadPort 函数就完结了,驱动层和运用层许多代码能够不通过修正直接用,很能进步开发功率的。当然这个按键程序会存在必定的问题,特别是遇到常闭按键和点触按键的混合运用的场合。这个留给我们自己去想了,横竖问题总是能找到处理办法的,虽然办法有好有坏。

  结束语

  以按键为前言,介绍了程序规划傍边的“分层屏蔽”的思维的原理和运用,按键仅仅一个比方,其实分层的思维遍及存在着程序规划傍边。仔细留心一下的话发现其实window,linux,网络的tcp/ip 结构悉数都是分层的。这东西不是绣花枕头,而是实践用在工程上面的,仅仅平常不多见帖子介绍,或许没有人特意这样来总结,又或许是有阅历的工程师作为藏在心中的法宝吧,这个就不得而知。不过好东西应该同享,菜鸟应该共勉,一起来学飞吧。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/ziliao/sheji/115248.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部