单片机软件设计_单片机软件框架设计 - CSDN
  • C语言嵌入式系统编程修炼之一:背景篇不同于一般形式的软件编程,嵌入式系统编程建立在特定的硬件平台上,势必要求其编程语言具备较强的硬件直接操作能力。无疑,汇编语言具备这样的特质。但是,归因于汇编语言开发...
    展开全文
  • “分层思想”并不是什么神秘的东西,事实上很多做项目的工程师本身自己也会在用。...但是如果不懂程序设计的思想的话,会给你做项目的过程中带来很多很多的困惑。 参考了市面上各种各样的嵌入式书籍,MCS-51,

    “分层思想”并不是什么神秘的东西,事实上很多做项目的工程师本身自己也会在用。看了不少帖子都发现没有提及这个东西,然而分层结构确是很有用的东西,参透后会有一种恍然大悟的感觉。如果说我不懂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 结构全部都是分层的。这东西不是绣花枕头,而是实际用在工程上面的,只是平时不多见帖子介绍,或者没有人特意这样来总结,又或者是有经验的工程师作为藏在心中的法宝吧,这个就不得而知。不过好东西应该共享,菜鸟应该共勉,一起来学飞吧。

    展开全文
  • 原文地址:...RTX51是德国 Keil公司开发的一种应用于MCS51系列单片机的实时多任务操作系统,它可以工作在所有8051 单片机以及派生家族中,简化了复杂的软件设计,缩短了项目周期。我们在实践中

    原文地址:http://www.bol-system.com/APPLICATION/RTX51.htm

    1 概述

    很多单片机的应用中都需要同时执行很多任务。对于这样的应用,我们可以利用实时操作系统来灵活地安排系统资源。RTX51是德国 Keil公司开发的一种应用于MCS51系列单片机的实时多任务操作系统,它可以工作在所有8051 单片机以及派生家族中,简化了复杂的软件设计,缩短了项目周期。我们在实践中用RTX51来开发单片机软件,设计单片机控制的GPS接收板软件,取得了很好地效果。

    2 RTX51介绍

    RTX51有2个模式:RTX51完全模式和最小模式。RTX51最小模式版是RTX51完全版的一个子集,可以很容易地运行在8051系统上,而不需要外部RAM(XDATA)。RTX51完全模式有4个任务优先级,可以和中断函数并行处理,各个任务之间通过使用“邮箱”系统来进行信号和消息的传递,可以从内存池中申请和释放内存;同时,可以强制一个任务停止执行,等待一个中断,或者是其它中断传来的信号量或者消息。

    RTX51对系统硬件的要求如表所列:

    描述 RTX51完全模式 RTX51最小模式
    任务数 最大256,19个激活任务,其中16个标准任务,3个快速任务 16
    RAM 40~46字节RAM
    20~200字节IDATA
    最少450字节XDATA
    7字节RAM
    3*任务数IDATA
    不需要XDATA
    ROM 6KB~8KB 900字节
    定时器 定时器0或1 定时器0

    2.1 RTX51任务

    RTX51区分2类任务:快速任务和标准任务。快速任务有很快的响应速度,每个快速任务使用8051一个单独的寄存器组,并且有自己的堆栈区域。RTX51支持最大同时有3个快速任务。标准任务需要多一点的时间来进行任务切换,因此使用的内部RAM相对快速任务要少,所有的标准任务共用1个寄存器组和堆栈。当任务切换的时候,当前任务的寄存器状态和堆栈内容转移到外部存储器中。RTX51支持最大16个标准任务。
    RTX51任务状态:

    (1)运行(RUNNING)-当前正在运行的任务处于RUNNING状态,同一时间只有1个任务可以运行。

    (2)就绪(READY)-等待运行的任务处于READY状态,在当前运行的任务退出运行状态后,就绪队列中优先级最高的任务进入到运行状态。

    (3)阻塞(BLOCKED)-等待一个事件的任务处于BLOCKED状态,如果事件发生且优先级比正在运行的任务高,此任务进入运行状态;如果优先级比正在运行的任务低,此任务进入READY状态。

    (4)删除(DELETED)-没有开始的任务处于删除状态。

    (5)任务切换-RTX51包含一个事件驱动的任务切换机制,它能够按照任务的优先级进行切换,也就是抢占式多任务系统;另外还有一个可选的时间片轮转切换任务模式,在时间片轮转模式下,同级别的任务是按照时间片分别占用CPU 的。RTX51任务有4个优先级:0、1、2 可以分配给标准任务,优先级3是为快速任务保留的。每个任务都可以等待事件的发生,而并不增加系统的负担;任务可以等待消息、信号、 中断、超时事件或者它们的组合。任务切换是按照一定规则进行的,包括:进入到“就绪”状态的优先级高的任务先执行;如果“就绪” 状态的几个任务是同一个优先级,那么最先进入“就绪”状态的先执行。

    2.2 RTX51事件

    *超时(timeout):挂起运行的任务指定数量的时钟周期。

    *间隔(interval):类似于超时,但是软件定时器没有复位,典型应用是产生时钟。

    *信号(signal):用于任务内部同步协调。

    *消息(message):适用于RTX51 Full,用于信息的交换。我们可以把一个消息发送到一个特定的邮箱。消息由2字节组成,可以是用户按照自己的需求定义的数据,也可以是指向数据的指针。如果邮箱的消息列表已满,而且是中断发送消息,这个消息将会丢失;如果是任务发送消息,那么任务将会进入到等待状态,直到邮箱重新有了位置可以接收这一条信息。邮箱是按照FIFO的原则来管理消息的,如果几个任务都在等待接收消息,那么最先进入等待接收队列的将接收消息。一个邮箱最多可以存储8条消息。当邮箱满的时候,最多只能有16个等待任务。

    *中断(interrupt):适用于RTX51 Full,一个任务可以等待8051硬件中断。

    *信号量(semaphore):适用于RTX51 Full,信号量用于管理共享的系统资源。通过使用“令牌”,允许在同一时刻只有一个任务使用某些资源。如果几个任务申请访问同一个资源,那么首先提出申请的将允许访问,其它的任务进入等待队列,直到第1个任务操作完毕,下一个任务才能继续。

    Os_wait()函数:挂起一个任务来等待一个事件的发生。这样可以同步2个或几个任务。它的工作过程如下:当任务等待的事件没有发生的时候,系统挂起这个任务;当事件发生时,系统根据任务切换规则切换任务。

    2.3 RTX51中断处理

    RTX51完全模式提供2种方法来处理中断:一种是C51的中断函数,另一种是RTX51的任务中断。它又可以分为快速任务中断和标准任务中断。

    对于中断函数这种方法,它同时也可以在不使用RTX51的情况下使用,当中断发生的时候,程序就跳到了相应的中断函数,它和正在运行的任务是相互独立的,中断的处理是在RTX51系统之外,和任务切换规则没有关联。

    对于任务中断的方法,不管使用快速还是标准任务来处理中断,如果中断发生,等待中断的任务就从“等待”状态进入到就绪状态,并按照任务切换规则进行切换。这种中断处理是完全 集成在RTX51的内部,硬件中断事件的处理和信号、消息的处理是完全相同的。

    在系统响应时间上中断函数是最快的。RTX51必须完全控制中断使能寄存器,这样才能遵守任务的切换规则并保证中断程序的无误进行。必须注意中断使能寄存器是由RTX51完全控制的,禁止用户手动修改。

    3 应用实例

    以下给出RTX51在单片机控制的GPS接收板上的应用。

    (1)系统硬件组成

    单片机W77E58、快速8051内核、32KB ROM、1KB的XDATA RAM,符合使用RTX51的硬件要求;键盘、GPS定位模块、液晶显示模块。

    (2)系统软件构成

    软件运行环境KEIL uVision2 6.20集成开发环境加上RTX51完全版。任务KEY-BOARD,监测键盘的情况,如果有按键按下,把按键的编码发送到邮箱1,外部中断1等待接收GPS数据,并把数据存储起来,向DISPLAY任务发出信号,进行处理。任务SEND_OUT,把接收到的数据 进行处理,并发送出去。任务VOICE进行语音输出。

    下面给出简写的源程序:

        #include<RTX51.h>                                //包含RTX51文件 
        #define DISPLAY 0 
        #define SEND_OUT 1 
        #define KEY_BOARD 2 
        #define VOICE 3 
        void main(void) 
       {   init_system();                               //系统初始化 
           os_start_system(DISPLAY);                    //启动RTX51 
           } 
        viod task0(void)_task_DISPLAY 
       {   os_set_slice(1000);                          //设置时间片大小 
           os_enable_isr(0);                            //允许外部中断0 
           os_creat_task(SEND_OUT);                     //启动SEND_OUT任务 
           os_creat_task(KEY_BOARD);                    //启动KEY_BOARD任务 
           os_creat_task(VOICE);                        //启动VOICE任务 
           for(;;){ 
           switch(os_wait(K_SIG+K_MBX+1255,& keyboard)) //等待接收信号和键盘消息,分类处理 
          {case EVENT_SIGNAL;                           //当接收到信号的时候 
              display1(); break; 
           case EVENT_MBOX:                             //当从邮箱接收到数据的时候 
           switch(keyboard) 
          {   case '1': 
              ... 
              os_send_signal(SEND_OUT);                 //向任务SEND_OUT发送信号 
              ... 
              os_send_signal(VOICE);}                   //向任务VOICE发送信号 
              ...;} 
              ...;} 
              } 
              void task1(void)_task_SEND_OUT            //处理发送数据任务 
             { while(1) 
              {    os_wait(K_SIG,255,0)                 //等待信号 
                   operation_send(); 
           } 
           void task3(void)_task_VOICE 
          { while(1){ 
              os_wait_signal(K_SIG,255,0);              //等待语音处理信号 
              voice();} 
           } 
           void interrupt1(void)interrupt 2 using 1 
          {   read_gps_data (p_gps_data);               //接收数据 
              isr_send_signal(DISPLAY);                 //向DISPLAY任务发信号 
           } 
              #pragma REGISTERBANK (2)                  //使用寄存器组2 
           void task2(void)_task_KEYBOARD_priority_3    //设置为快速任务 
          {   os_attach_interrupt(0);                   //绑定任务和外部中断0 
              while(1){ 
              os_wait(K_INT,255,0);                     //等待中断的发生 
              KEY=iic_read_keyboard(); 
              os_send_message(1,KEY,0);}                //将键盘编码发送到邮箱1 
           }

    4 结论

    通过实践我们可以发现,使用RTX51开发单片机程序更加方便了,尤其是较大的程序,避免了自己写消息循环等烦琐工作,效率明显增加了。在硬件资源足够的情况下,效果更加明显。

    摘编自《单片机与嵌入式系统应用》2002.12

    展开全文
  • 单片机软件设计思路

    2014-07-02 22:57:40
  • 链接:https://pan.baidu.com/s/1vU5UHX73zNwQe-_ZtR0bEQ 密码:tg8g 本书为完整版,以下为内容截图:
  • 超实用的电子设计软件/工具推荐DC-DC电源设计工具:DCDCDesigner 3.12DC-DC电源设计工具:DCDCDesigner 3.12 DC-DC电源设计工具:DCDCDesigner 3.12 DCDCDesigner 是 MPS系列DC-DC电源设计工具,可以在MPS官网上下载...
  • 单片机开发,首要的两个软件一个是编程软件,一个是下载软件。编程软件我们用 Keil uVision4 的 51 版本,也叫做 Keil C51,不做过多介绍,先直接讲如何安装。 1) 首先准备 Keil uVision4 安装源文件,双击安装...
  • 单片机产品开发流程

    2019-03-05 08:49:39
    我们学习单片机的目的就是为了进行嵌入式系统的开发,学好单片机首先要有一个整体认识,下面将简要介绍一下单片机应用系统的开发流程,如图1所示。 图1 单片机系统开发流程 1、明确任务 分析和了解项目的总体要求,...
  • 51单片机作为基础入门的单片机应用十分广泛,一直以来基于51单片机的作品就层出不穷,推陈出新,有一段时间没有给大家整理关于51单片机的作品了,今天给大家分享电路城上最新的基于51单片机的作品,尤其是智能家居...
  • 单片机的架构介绍

    2017-06-04 11:04:53
    评-单片机的架构介绍 ---- 爱评才会赢  [导读]:什么是单片机的架构?单片机的架构有哪几种?本文对这个问题做了个简单的介绍。单片机的架构根据指令结构可以分为CISC(Complex Instruction Set...
  • 经过几天的回忆与思考,分析了我的成长路径,选择一些我自认为是成长关键点的位置,总结一个关键字,一步一步来讨论关于嵌入式单片机软件的架构。 我先把总结出的关键字写出来吧:**流水式、中断前后台、任务式、...
  • 能做计算器的单片机 单片机的出现是计算机制造技术高速发展的产物,...本计算器是将键盘输入信息经处理通过缓存,送入数码管显示,数码管采用动态扫描方式,计算功能通过软件实现,用C语言对单片机可编芯片进行编程...
  • 单片机软件工程(一)--FIFO设计  中午调一个程序,一个比较简单的程序,就是几个按键,一个数码管,使得用按键控制数码管上的数字,前提是不阻塞CPU!!(本来整个程序设计是不准备利用延时的,...
  • 基于单片机的智能报警系统设计 基于51单片机的报警系统实现 网上转载:本系统具备发送短信、接收短信,拨打电话、接听电话等功能。主控检测到有人入侵之后会立即产生高分贝的警报,吓退闯入者,与此同时通过GSM模块...
  • 单片机系统里,按键是常见的输入设备,在本文将介绍几种按键硬件、软件设计方面的技巧。一般的在按键的设计上,一般有四种方案:一是GPIO口直接检测单个按键,如图1.1所示;二是按键较多则使用矩阵键盘,如图1.2所...
  • 单片机硬件设计总结

    2018-09-14 14:56:15
    下面是总结的一些设计中应注意的问题,和单片机硬件设计原则,老生常谈了,不过还是写一下:   (1)在元器件的布局方面,应该把相互有关的元件尽量放得靠近一些  例如,时钟发生器、晶振、CPU的时钟输入端都易...
  • 首先来说,每一款单片机的编程软件都有软件仿真功能。我们可以通过这个软件仿真功能学习一些单片机的功能。  例如,可以通过软件仿真功能实现单片机端口输出高低电平,然后通过观察相应的端口寄存器的值来看程序...
  • 一个单片机应用系统的硬件电路设计包含两部分内容:一是系统扩展,即单片机内部的功能单元,如ROM、RAM、I/O、定时器/计数器、中断系统等不能满足应用系统的要求时,必须在片外进行扩展,选择适当的芯片,设计相应的...
  • 在提高硬件系统抗干扰能力的同时,软件抗干扰以其设计灵活、节省硬件资源、可靠性好越来越受到重视。下面以MCS-51单片机系统为例,对微机系统软件抗干扰方法进行研究。    1 软件抗干扰方法的研究    在工程...
  • 本文主要介绍了怎么使用51单片机最小系统板和温湿度传感器制作一个温湿度检测系统。  本次设计主要涉及了温湿度的测量、显示以及实现简单控制。硬件方面有五个模块,即STC89C52单片机主控模块、传感器模块、LCD...
1 2 3 4 5 ... 20
收藏数 31,017
精华内容 12,406
关键字:

单片机软件设计