单片机程序设计中的“分层思想”

最新更新时间:2015-03-14来源: 互联网关键字:单片机程序设计 手机看文章 扫描二维码
随时随地手机看文章
分层的思想,并不是什么神秘的东西,事实上很多做项目的工程师本身自己也会在用。看了不少帖子都发现没有提及这个东西,然而分层结构确是很有用的东西,参透后会有一种恍然大悟的感觉。如果说我不懂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想象成P1口,那么这个跟学习板那标准的扫描程序不就是一样了吗?对的,这个就是底层映射的目的了。

3)应用层程序编写

根据消息

硬件层是必须分离出来,然而驱动层和应用层的要求就不那么严格了,事实上一些简单的项目没有必要将这两层分离开来,根据实际应用灵活应对就可以了。其实这样写程序是很方便移植的,根据板子的不同而适当的修改一下硬件层那个ReadPort函数就完成了,驱动层和应用层很多代码可以不经过修改直接用,很能提高开发效率的。当然这个按键程序会存在一定的问题,特别是遇到常闭按键和点触按键的混合使用的场合。这个留给大家自己去想了,反正问题总是能找到解决办法的,尽管方法有好有坏。

结束语

以按键为媒介,介绍了程序设计当中的“分层屏蔽”的思想的原理和应用,按键只是一个例子,其实分层的思想普遍存在着程序设计当中。细心留意一下的话发现其实window,linux,网络的tcp/ip结构全部都是分层的。这东西不是绣花枕头,而是实际用在工程上面的,只是平时不多见帖子介绍,或者没有人特意这样来总结,又或者是有经验的工程师作为藏在心中的法宝吧,这个就不得而知。

关键字:单片机程序设计 编辑:探路者 引用地址:单片机程序设计中的“分层思想”

上一篇:51单片机程序执行流程详细分析
下一篇:扩展示波器用途的另外十个技巧

推荐阅读最新更新时间:2023-10-12 22:53

单片机C语言程序设计:按键控制定时器选播多段音乐
/* 名称:按键控制定时器选播多段音乐 说明:本例内置 3 段音乐,K1 可启动 停止音乐播放,K2 用于选择音乐段。 */ #include reg51.h #include intrins.h #define uchar unsigned char #define uint unsigned int sbit K1=P1^0; //播放和停止键 sbit SPK=P3^7; //蜂鸣器 uchar Song_Index=0,Tone_Index=0; //当前音乐段索引,音符索引 //数码管段码表 uchar code DSY_CODE ={0xc
[单片机]
<font color='red'>单片机</font>C语言<font color='red'>程序设计</font>:按键控制定时器选播多段音乐
单片机C语言程序设计:演奏音阶
/* 名称:演奏音阶 说明:本例使用定时器演奏一段音 阶,播放由 K1 控制。 */ #include reg51.h #define uchar unsigned char #define uint unsigned int sbit K1=P1^0; sbit SPK=P3^4; uint i=0; //音符索引 //14 个音符放在方式 2 下的定时寄存器 (TH0,TL0) uchar code HI_LIST ={0,226,229,232,233,236,238,240,241,242,244,245,246,247,248}; u
[单片机]
<font color='red'>单片机</font>C语言<font color='red'>程序设计</font>:演奏音阶
单片机程序设计方法的介绍(延时程序、子程序、循环程序)
  一、延时程序   延时程序是一种应用较为广泛的小程序,一般采用多条语句循环执行来实现延时。   例 1 :当前 fosc=12MHz ,试计算下面延时程序的延时时间。   因为 fosc=12MHz ,故 T 机 =12/fosc=1us   DEL1 : MOV R3 , #10 ;1 个 机器周期   DEL2 : NOP ;1 个 机器周期   NOP ;1 个 机器周期   DJNZ R3 , DEL2 ;2 个 机器周期   t1= (1T 机 +1T 机 +2T 机 ) 10+ 1T 机 =41us   例 2 :来看看下面这个程序能够实现的延时时间:   T 机 =12/f
[单片机]
<font color='red'>单片机</font><font color='red'>程序设计</font>方法的介绍(延时程序、子程序、循环程序)
PIC单片机人机接口模块独立式按键的程序设计
  下面是查询方式下的键盘程序,程序中没有使用散转指令,也没有软件防抖动措施,只包括按键查询、键功能程序转移。FP0~FP7为功能程序入口地址标号,PROM0~PROM7分别为每个按键的功能程序。   程序清单(设I/O口为P1口)如下:   由此程序可以看出,各按键由软件设置了优先级,优先级顺序依次为0~7。   本节所讲的模块中,在按键按下或弹起时经常会出现一些毛刺,所以在首次检测到输入的值后应添加一个延时程序DELAY。   这个延时程序延时100ms左右,延时后再检测输入的值,如果改变了,则证明此时按键按下或弹起时读出的值是不准确的,再调用延时程序DELAY,延时100ms
[单片机]
PIC<font color='red'>单片机</font>人机接口模块独立式按键的<font color='red'>程序设计</font>
单片机C语言程序设计:并行数据转换为串行数据
/* 名称:并行数据转换为串行数据 说 明 : 切 换 连 接 到 并 串 转 换 芯 片 74LS165 的拨码开关,该芯片将并行数据以 串行方式发送到 8051 的 RXD 引脚,移位脉 冲由 TXD 提供,显示在 P0 口。 */ #include reg51.h #include intrins.h #include stdio.h #define uchar unsigned char #define uint unsigned int sbit SPL=P2^5; //shift/load //延时 void DelayMS(u
[单片机]
<font color='red'>单片机</font>C语言<font color='red'>程序设计</font>:并行数据转换为串行数据
PIC单片机C语言程序设计(2)
  五、C语言的标识符和关键字   一个完整的PIC单片机C语言程序,通常由包含文件(即头文件1,变量定义、变量说明、函数定义、函数体和注释等六部分等组成。   1.C语言的标识符   所谓标识符,实际上是一些由程序编写者自定义的名称,类似于PIC单片机汇编语言中给寄存器(RAM)的命名。C语言中所用到的变量名、函数名、数组名、文件名等都是由标识符组成的。   标识符是由一串字母(常指英语字母)、数字和下线符(或称下划线)组成的字符串。标识符的第一个字符必须是字母或下线符。按照惯例,以下线符开头的标识符是系统程序专用的,程序员最好不用。程序员可将下线符作为分段符使用,如SUM_1。   同一字母的大小
[单片机]
PIC<font color='red'>单片机</font>C语言<font color='red'>程序设计</font>(2)
单片机动态扫描接口及程序设计
    什么叫动态扫描显示   在单片机系统中动态扫描显示接口是单片机中应用最为广泛的一种显示方式之一。其接口电路是把所有显示器的8个笔划段a-h同名端连在一起,而每一个显示器的公共极COM是各自独立地受I/O线控制。CPU向字段输出口送出字形码时,所有显示器接收到相同的字形码,但究竟是那个显示器亮,则取决于COM端,而这一端是由I/O控制的,所以我们就能自行决定何时显示哪一位了。而所谓动态扫描就是指我们采用分时的办法,轮流控制各个显示器的COM端,使各个显示器轮流点亮。   在轮流点亮扫描过程中,每位显示器的点亮时间是极为短暂的(约1ms),但由于人的视觉暂留现象及发光二极管的余辉效应,尽管实际上各位显示器并非同时点亮,
[嵌入式]
PIC单片机C语言程序设计(14)
  十五、Pic单片机的A/D转换   在电子技术中,传感器是一种很重要的器件,传感器的种类也有多种,如温度传感器、光敏传感器、压力传感器……,其特点是能把非电量,如温度、光度、压力等转换成相关的电量(电流或电压)。这些电量都是模拟量,可用Pic 单片机的A/D 转换,将上述的模拟量转换成数字量,再将数字量进行各种处理,如LED、LCD 显示。   Pic16F87X 系列单片机, 具有A/D 转换的功能。Pic16F876/873 芯片为28 引脚, 有5 个模拟输入端的10 位A/D 转换(5 通道);Pic16F877 为40 引脚,有8 个模拟输入端的10位A/D 转换(8 通道)。Pic16F876/873 芯
[单片机]
PIC<font color='red'>单片机</font>C语言<font color='red'>程序设计</font>(14)
小广播
最新电源管理文章
换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved