|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
分层的思想,并不是什么神秘的东西,事实上很多做项目的工程师本身自己也会在用。看了不少帖子都发现没有提及这个东西,然而分层结构确是很有用的东西,参透后会有一种恍然大悟的感觉。如果说我不懂LCD怎么驱动,那好办,看一下datasheet,参考一下阿别人的程序,很快就可以做出来。但是如果不懂程序设计的思想的话,会给你做项目的过程中带来很多很多的困惑。参考了市面上各种各样的嵌入式书籍,MCS-51,AVR ,ARM 等都有看过,但是没有发现有哪本是介绍设计思想的,就算有也是凤毛麟角。写程序不难,但是程序怎么样才能写的好,写的快,那是需要点经验积累的。结构化模块化的程序设计的思想,使最基本的要求。然而这么将这个抽象的概念运用到工程实践当中恩?那需要在做项目的过程中经历磨难,将一些东西总结出来,抽象升华为理论,对经验的积累和技术的传播都大有裨益。所以在下出来献丑一下,总结一些东西。就我个人的经验而谈,有两个设计思想是非常重要的。一个就是“时间片轮的设计思想”,这个对实际中解决多任务问题非常有用,通常可以用这个东西来判断一个人是单片机学习者,还是一个单片机工程师。这个必须掌握。(下文将介绍)。
* U2 u$ j b8 @4 }4 M' u9 x. X1 Q. h6 v4 d |, }
第二个就是“分层屏蔽的设计思想”即分层思想。下面用扫描键盘程序例子作为引子,引出今天说的东西。问题的提出单片机学习板一般为了简单起见,将按键分配的很好,例如整个 4*4 的键盘矩阵分配到 P1 口上面,8条控制线,刚好。这样的话程序也非常好写。只需要简单的:KEY_DAT= P1;端口的数据就读进来了。诚然,现实中没有这么好的事情。在实际的项目应用当中,单片机引脚的复用相当厉害,这跟那些所谓的单片机学习板就有很大的差别了。* p" j* Z* d8 r) U$ b5 ]- X2 ^2 i6 C% l5 M, d& h% Y. I; |' s' e
1 W, A W6 r) w0 Q6 U
3 a8 O: c6 q& _另外一个原因,一般设计来说,是“软件配合硬件”的设计流程,简单点说就是,先确定好硬件原理图,硬件布线,最后才是软件的开发,因为硬件修改起来比较麻烦,相对来说软件修改的时候比较好改。这个就是中国传统的阴阳平衡哲学原理。硬件设计和软件设计本来就是鱼和熊掌的关系,两者不可兼得。方便了硬件设计,很可能给写软件带来很大的麻烦。反过来说,方便了软件设计,硬件设计也会相当的麻烦。如果硬件设计和软件设计同时方便了,那只有两种可能,一是这个设计方案非常简单,二是设计师已经达到了一个非常高的境界。我们不考虑那么多情况,单纯从常用的实际应用的角度来看问题。+ [/ F5 m I* a. D
4 n& |; x' g8 I7 l0 R, } E$ t+ m# H% }6 X
硬件为了布线的方便,很多时候会可能将IO口分配到不同的端口上面,例如上面说的4*4键盘,8根线分别分配到 P0 P1 P2 P3 上面去了。那么,开发板的那些扫描键盘程序可以去见鬼了。怎么扫按键?我想起了我刚开始学习的时候,分成3段非常相似的程序,一个一个按键的扫描的经历......
8 j% E6 `3 k! a# o6 d' H0 U6 n0 E2 u4 e. A5 N5 C0 G3 E: E( ^
$ \3 \! W) k- h. J$ C6 k' {' B或许有人不甘心,“那些东西我花了很长时间学习的,也用的好好的,怎么能说一句不用就不用?”虽然有点残忍,但是我还是想说“兄弟,接受现实吧,现实是残酷的......”/ n3 U( W" J2 r3 R, L6 k- X
8 N. @8 i1 d+ w& Z: B5 m4 M3 Q8 U' T% `; B( u, C: [% W7 R7 }: z8 t* a. Q% o
不过,人区别于低等动物的差别,是人会创造,在碰到困难的时候会想办法解决,于是我们开始了沉思......
6 Q9 P2 d7 j; {2 }5 v* ?( u9 G9 h/ F5 e% B& w* t/ E* {( v
2 E0 O, ?; `/ ^8 T9 W2 P! T' }2 w最后我们引入初中数学学的“映射”的概念来解决问题。基本思想就是,将不同端口的按键映射到相同端口上面。) k! F) ?0 j4 H6 T" \! F4 S. i4 `3 k7 T2 v1 ^
# g5 [' c: a- z( @% H; ~
! Z8 j ^% d# t# x$ r4 v这样按键扫描程序就分成3个层次了:3 ]- S, U. [1 z5 u: \0 n# Y: R+ ~4 p, o
1)最底层的是硬件层,完成端口扫描,20ms延时消抖,将端口的数据映射到一个KEY_DAT寄存器上面,KEY_DAT作为对上层驱动层的一个接口。8 ]. s5 k# l! |
3 e2 l& ?/ Y e1 ~6 a n; f, n. y u) G
( f' p$ t+ H3 C; c. q2 ?5 t6 j2)中间的一层是驱动层,驱动层只对 KEY_DAT 寄存器的数值进行操作。简单点说,我们无论底层的硬件是怎么接线的,在驱动层都不需要关心,只需要关心 KEY_DAT 这个寄存器的数值是什么就可以了。这样出来的间接效果就是“屏蔽了底层硬件的差异”,所以驱动层写的程序就可以通用了。0 _- b! y' x/ M4 ? q$ S2 \! W: i9 `: w) ]
0 L) |$ X3 P z1 w: {
驱动层的另外一个功能是为了上层提供消息接口。我们用了类似window程序的消息的概念。这里可以提供一些按键消息,例如:按下消息,松开消息,长按键消息,长按键的时候的步进消息,等等。 \; n2 m, d' Q% U$ r: H+ D
& M4 @* C8 h) p E3)应用层。这里就是根据项目的不同分别写按键功能程序,属于最上层的程序。它使用的是驱动层提供的消息接口。在应用层写程序的思想就是,我不管下层是怎么工作的,我只关心按键消息。有按键消息来的时候我就执行功能,没有消息来的时候,我就什么也不做。
; E( n! ]- B( E' ^6 v) d |
|