为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

第9章 键盘输入接口与状态机编程

2017-11-01 31页 doc 131KB 27阅读

用户头像

is_180829

暂无简介

举报
第9章 键盘输入接口与状态机编程第9章 键盘输入接口与状态机编程 基于AVR的单片嵌入式系统原理与实践应用 在前面的章节中,已经详细介绍了AVR单片机通用数字I/O口的特性以及应用于输出方式的基本使用方法,并给出了一些与中断、定时计数器相结合的输出控制应用和应用实例。 本章将进一步讨论AVR通用I/O口用于按键和键盘输入接口,以及基于状态机的软件设计思 想和实现。 假如把一个单片机嵌入式系统比做一个人的话,那么单片机就相当于人的心脏和大脑, 而输入接口就好似人的感官系统,用于获取外部世界的变化、状态等各种信息,并把这些信 息输送进人的大脑。嵌入式系统的...
第9章 键盘输入接口与状态机编程
第9章 键盘输入接口与状态机编程 基于AVR的单片嵌入式系统原理与实践应用 在前面的章节中,已经详细介绍了AVR单片机通用数字I/O口的特性以及应用于输出方式的基本使用方法,并给出了一些与中断、定时计数器相结合的输出控制应用和应用实例。 本章将进一步讨论AVR通用I/O口用于按键和键盘输入接口,以及基于状态机的软件设计思 想和实现。 假如把一个单片机嵌入式系统比做一个人的话,那么单片机就相当于人的心脏和大脑, 而输入接口就好似人的感官系统,用于获取外部世界的变化、状态等各种信息,并把这些信 息输送进人的大脑。嵌入式系统的人机交互通道、前向通道、数据交换和通信通道的各种功 能都是由单片机的输入接口及相应的外围接口电路实现的。 对于一个电子系统来讲,外部现实世界各种类型和形态的变化和状态都需要一个变换器 将其转换成电信号,而且这个电信号有时还需要经过处理,使其成为能被MCU容易识别和处理的数字逻辑信号,这是因为单片机常用的输入接口通常都是数字接口(A/D接口,模拟比较器除外,他们属于模拟输入口,而是在芯片内部将模拟信号转换成数字信号的)。上述的 所为“变换器”和“转换处理”从专业的角度讲就是“传感器技术”和“信号调理电路”。 因此,一个单片机嵌入式系统的设计和开发人员要具备这些专业知识和技能,不仅要熟悉一 些常用传感器的特性和应用,以及相关的信号调理、转换、接口电路,还要跟踪国际上新技 术的发展,将新型传感器器件和新型电路元器件应用于系统设计中。采用新型传感器器件和 新型电路元器件,可以大大提高嵌入式系统设计的效率,简化系统的硬件结构和软件设计难 度,缩短开发周期,提高系统的性能和可靠型。 根据系统外围电路输入的电信号形式,可以把输入信号分为以下几种形式: (1) 模拟信号和数字信号。 传感器将某个外部参数(如温度、转速)的变化转换成电信号(电压或电流)。如果传 感器输出电信号的幅度变化特征代表了外部参数的变化,如电压的升高下降(电流增大减小) 表示温度高低的变化,那么这个传感器就是模拟传感器,它产生是模拟信号。由于MCU是数字化的,因此模拟信号要转换成数字信号才能由MCU处理。这个转换电路称为摸数转换 “A/D”。A/D变换是嵌入式系统重要的外围接口电路之一,用途广泛。在系统硬件设计中可 以选取专用的A/D变换芯片作为模拟传感器和单片机之间的接口,也可以选取片内带A/D 转换功能的单片机以简化硬件电路的设计。大多数型号的AVR单片机在片内都集成有A/D 接口,关于A/D接口将在以后的章节中进行专门介绍。 有些外部参数的变化可以采用数字式传感器器件直接将其变化转换成数字信号。如采用 光栅和光电开关器件将位移和转动圈数转换成脉冲信号,用以测量位移或转速。还有一些新 型的传感器器件,把模拟传感器、A/D变换和数字接口集成在一片芯片内,构成了智能数字 传感器,如AD公司和MAXIM公司的数字温度传感器器件等,这些器件的推出,方便了嵌入 式系统的硬件设计。 华东师范大学 电子系 马 潮 9-1 第9章 键盘输入接口与状态机编程 (2) 电压信号和电流信号。 单片机I/O接口的逻辑是数字电平逻辑,既以电压的高和低电平作为逻辑“1”和“0”,因此进入单片机的信号要求是电压信号。一些传感器的输出是电流信号,甚至是微小的电流, 那么在进入单片机前还需要将电流信号放大、并把电流转换成电压的信号调理电路。 在一些长远距离的应用中,考虑到电压信号的抗干扰能力差,长线衰减等因素,往往在 一端把电压信号变成电流信号,在长线中传送电流,而在另一端再把电流信号再转换成电压 信号,这样大大提高了信号传输的可靠性,如RS-485通信等。另外,为了防止外部强电信 号对嵌入式系统的冲击而使用的光电隔离技术,也是电流/电压变换的应用(图9-1)。 (3) 单次信号和连续信号。 间隔时间较长单次产生的脉冲信号,以及较长时间保持电平不变化的信号称为单次信 号。常见的单次信号一般是由按键、限位开关等人为动作或机械器件产生的信号。而连续信 号一般指连续的脉冲信号,如计数脉冲信号,数据通信传输等。 单次信号要注意信号的纯净和抗干扰,如消除按键的抖动,外部的干扰等。在图9-1中,外部状态开关与系统之间采用电流传输方式,在系统入口串接磁阻线圈。当外部开关闭 合后,回路中有大电流通过,光电器件导通输出“0”;而在开关断开后,回路中无电流流通, 光电器件不会导通输出“1”。空间的电磁信号会在传输线上产生高频的干扰信号,磁阻线圈 则对高频信号起到阻碍作用,使电流不能突变。另外空间电磁干扰往往能产生较高的干扰电 压,但不会产生大的干扰电流(协议
等。AVR单片机提供了丰富的接口,如外部中断、定时计数器、USART、I2C、SPI,可以方便的对连续脉冲信号进行检测、计数,以及支持多种协议的数据交换和通信等。 根据不同的硬件接口电路和嵌入式系统功能需求的不同,输入接口软件的设计也是千百 万化、丰富多彩的。设计开发一个好的嵌入式系统产品,不仅要求软件设计人员要具备很强 的硬件能力,还要有相当高的软件设计编程能力和经验。这是开发嵌入式系统的特点:硬件 软件不可分割,同等重要。在以后的学习中,我们会逐渐体会和深入学习各种接口的软件设 计技巧。 在本章以下的几节中,将主要讲解通用数字I/O口的一个基本和重要应用:按键和键盘 接口的软硬件设计与实现。按键和键盘是单片机嵌入式系统中一个重要的组成部分,虽然在 华东师范大学 电子系 马 潮 9-2 基于AVR的单片嵌入式系统原理与实践应用 硬件电路上的连接实现非常简单,但由于按键其本身的特殊性(如需要考虑消除抖动,确认 释放等)和功能的多样性(如连续按键,多功能等),它的软件接口程序的设计和实现要相 对复杂些。所以读者在学习本章的内容时,更重要的是掌握系统软件设计编写的方法和技术, 采用模块化的思想实现功能模块的单一性、独立性,以及学习基于状态机思想的程序设计方 法。 AVR通用I/O口的结构以及相关的寄存器已经在本书的第六章中做了介绍,同时给出了 通用I/O口的输出应用实例。但要将AVR单片机的I/O接口用做数字输入口使用时,请千万 注意AVR单片机同其它类型单片机的I/O口的不同,即AVR的通用I/O口是有方向的。在程序设计中,如果要将I/O口作为输入接口时,不要忘记应先对I/O进行正确的初始化和设置。 最后一点是由于在PINx.n和AVR内部数据总线之间有一个同步锁存器(图6-4中的SYNCHRONIZER)电路,使用该电路避免了当系统时钟变化的短时间内外部引脚电平也同时变 化而造成的信号不稳定的现象,但它将产生大约一个时钟周期(0.5~1.5)的时延。 在单片机嵌入式系统中,按键和键盘是一个基本和常用的接口,它是构成人机对话通道 的一种常用的方式。按键和键盘能实现向嵌入式系统输入数据、传输命令等功能,是人工干 预、设置和控制系统运行的主要手段。 键盘是由一组按键组合构成的,所以我们先讨论简单的单个按键的输入。 图9-2是简单按键输入接口硬件连接电路图,图中单片机的三个I/O口PC7、PC6、PC5作为输入口(输入方式),分别与K3、K2、K1三个按键连接。其中K2是的连接方式,当没有按下K2时,PC6的输入为高电平,按下K2输入为低电平。PC6引脚上的电平值反映了按键的状态。 华东师范大学 电子系 马 潮 9-3 第9章 键盘输入接口与状态机编程 按键K1是一种经济的接法,它充分利用了AVR单片机I/O口的内部上拉特点。在K1 的连接中,除了把PC5定义为输入方式时(DDRC.5=0),同时设置PC5口的上拉电阻有效(PORTC.5=1),这样当K1处在断开状态时,PC5引脚在内部上拉电阻的作用下为稳定的高电 平(如果上拉电阻无效,则PC5处在高阻输入态,PC5的输入易受到干扰,不稳定),按下K1输入为低电平。与K2连接方式比较,K1连接电路中省掉了一个外部上拉电阻,而在K2 的连接方法中,由于外部使用了上拉电阻,所以只要设置PC6口为输入方式即可,该口内部的上拉电阻有效与否则不必考虑了。电阻R1不仅起到上拉的作用,还有限流的作用,通常 在5K-50K之间。 而对于K3的连接方式,我们不提倡使用,因当K3按下闭合时,PC7口直接与Vcc接通 了,有可能会造成大的短路电流流过PC7引脚,从而把端口烧毁。 根据按键连接电路可知,按键状态的确认就是判别按键是否闭合,反映在输入口的电平 就是和按键相连的I/O引脚呈现出高电平或低电平。如果输入高电平表示断开的话,那么低 电平则表示按键闭合,所以简单的讲,在程序中通过检测引脚电平的高低,便可确认按键是 否按下。 但对于实际的按键确认并不是象上面描述的那么简单。首先要考虑的是按键消抖的问 题。通常,按键的开关为机械弹性触点开关,它是利用机械触点接触和分离实现电路的通、 断。由于机械触点的弹性作用,加上人们按键时的力度、方向的不同,按键开关从按下到接 触稳定要经过数毫秒的弹跳抖动,既在按下的几十毫秒时间里会连续产生多个脉冲。释放按 键时,电路也不会一下断开,同样会产 生抖动(图9-3)。这两次抖动的时间分 别为10-20ms左右,而按键的稳定闭合键按下 期通常大于0.3-0.5秒。因此,为了确 保MCU对一次按键动作只确认一次,在 确认按键是否闭合时,必须要进行消抖 处理。否则,由于MCU软件执行的速度 很快,非常可能将抖动产生的多个脉冲 误认为多次的按键。在第七章的例7.1 中,采用了简单的中断输入按键接口,没有消抖动的功能,所以出现了按键输入控制不稳定 华东师范大学 电子系 马 潮 9-4 基于AVR的单片嵌入式系统原理与实践应用 的现象。 消除按键的抖动既可采用硬件方法,也可采用软件的方法。使用硬件消抖的方式,需要 在按键连接的硬件设计上增加硬件消抖电路,如采用R-S触发器或RC积分电路等。采用硬件消抖方式增加了系统的成本,而利用软件方式消抖则是比较经济的做法,但增加了软件设 计的复杂性。 软件方式消抖的基本原理是在软件中对按键进行两次测试确认,既在第一次检测到按键 按下后,间隔10ms左右再次检测该按键是否按下,只有在两次都测到按键按下时才最终确 认有键按下,从而消除了抖动的影响。 在按键接口软件中,除了要考虑按键消抖外,一般还要判别按键的释放,只有检测到按 键释放以后,才能确定为一次完整的按键动作完成。 一般的教课书中给出的按键输入软件接口程序通常非常简单,在程序中一旦检测到按键 输入口为低电平时(图9-2),便采用(调用)软件延时程序延时10ms。然后再次检测按键输入口,如果还是低电平则表示按键按下,转入执行按键处理程序。如果第二次检测按键输 入口为高电平,则放弃本次按键的检测,从新开始一次按键检测过程。这种方式实现的按键 输入接口,作为基础学习和一些简单的系统中可以采用,但在多数的实际产品设计中,这种 按键输入软件的实现方法有很大的缺陷和不足。 上面所提到简单的按键检测处理方法,不仅是由于采用了软件延时而使的MCU的效率降低,而且也不容易同系统中其它功能模块协调工作,系统的实时性也差。另外,由于在不同 的产品系统中对按键功能的定义和使用方式也会不同,而且是多变的,加上在测试和处理按 键的同时,MCU还要同时处理其它的任务(如显示、计算、计时等),因此编写键盘和按键 接口的处理程序需要掌握有效的分析方法,具备较高的软件设计能力和程序编写的技巧。 读者可以先仔细观察一下实际产品中各种按键的功能和使用。如一般的电子手表上只有 2-3个的按键,却要实现时间、日期、闹钟时间的设置和查看显示等多种功能,因此这些按 键是多功能(或复用)的,在不同的状态下,按键的功能也不同。更典型的是手机的键盘, 就拿手机键盘上的数字键“2”来将,当手机用于打电话需要拨出电话号码时,按“2”键代表数值“2”。而使用手机发短信用于输入短信文字信息时(英文输入),第一次按下“2”键 为字母“A”,紧接着再次按下为字母“B”,连续短时间按下该键,它的输入代表的符号不同, 但在同一个位置,而稍微等待一段时间后,光标的位置就会右移,表示对最后输入字符的确 认。 因此,按键输入接口设计和实现的核心,更多的体现在软件接口处理程序的设计中。下 面将以此为例,介绍有限状态机的分析设计原理,以及基于状态机思想进行程序设计的基本 方法与技巧。 一、有限状态机分析设计的基本原理 对于电子技术和电子工程类的读者,最先接触和使用到状态机应该是在数字逻辑电路课 程里,状态机的思想和分析方法被应用于时序逻辑电路设计。其实,有限状态机(FSM)是 实时系统设计中的一种数学模型,是一种重要的、易于建立的、应用比较广泛的、以描述控 制特性为主的建模方法,它可以应用于从系统分析到设计(包括硬件、软件)的所有阶段。 很多实时系统,特别是实时控制系统,其整个系统的分析机制和功能与系统的状态有相 当大的关系。有限状态机由有限的状态和相互之间的转移构成,在任何时候只能处于给定数 目的状态中的一个。当接收到一个输入事件时,状态机产生一个输出,同时也可能伴随着状 态的转移。 一个简单的有限状态机在数学上可以描述为: 华东师范大学 电子系 马 潮 9-5 第9章 键盘输入接口与状态机编程 (1) 一个有限的系统状态的集合 ,,,,,,,,St,{St,St,?,St}ik1k2kqk 其中(i = 1,2,„,q)。该式表示系统可能存(处)在的状态有q个,而在时刻Tk,系统的状态为其中之一Si(唯一性)。 (2) 一个有限的系统输入信号的集合 ,,,,,,,,It,{It,It,?,It}jk1k2kmk 其中(j = 1,2,„,m),表示系统共有m个输入信号。该式表示在时刻Tk,系统的输入信号为输入集合的全集或子集(集合性)。 (3) 一个状态转移函数F: ,,,,,,St,St,It',k1ikjki 状态转移函数也是一个状态函数,它表示对于时刻Tk,系统在某一状态Si下,相对给定输入Ij后,FSM转入该函数产生的新状态,这个新状态就是系统在下一时刻(K+1)的状态。这个新的状态也是唯一确定的(唯一性)。 (4) 一个有限的输出信号集合 ,,,,,,,,,,,,,,,,OSt,{OSt,OSt,?,OSt}lik1ik2iknik 其中(l = 1,2,„,n),表示系统共有n个输出信号。该式表示对于在时刻Tk,系统的状态为Si时,其输出信号为输出集合的全集或子集(集合性)。这里需要注意的是,系统 的输出只与系统所处的状态有关。 (5) 时间序列 T,{t,t,?,t,t,?}01kk,1 在状态机中,时间序列也是非常重要的一个因素,从硬件的角度看,时间序列如同一个 触发脉冲序列或同步信号,而从软件的角度看,时间序列就是一个定时器。状态机由时间序 列同步触发,定时检测输入,以及根据当前的状态输出相应的信号,并确定下一次系统状态 的转移。在时间序列进入下一次触发时,系统的状态将根据前一次的状态和输入情况发生状 态的转移。其次,作为时间序列本身也可能是一个系统的输入信号,影响到状态的改变,进 而也影响到系统的输出。所以对于时间序列,正确分析和考虑选择合适的时间段的间隔也是 非常重要的。间隔太短的话,对系统的速度、频率响应要求高,并且可能减低系统的效率; 间隔太长时,系统的实时性差,响应慢,还有可能造成外部输入信号的丢失。一般情况下, 时间序列的时间间隔的选取,应稍微小于外部输入信号中变化最快的周期值。 通常主要有两种方法来建立有限状态机,一种是“状态转移图”,另一种是“状态转移 表”,分别用图形方式和表格方式建立有限状态机。实时系统经常会应用在比较大型的系统 中,这时采用图形或表格方式对理解复杂的系统具有很大的帮助。 总的来说,有限状态机的优点在于简单易用,状态间的关系能够直观看到。应用在实时 系统中时,便于对复杂系统进行分析。 下面将给出两个按键与显示相结合的应用设计实例,结合设计的例子,讨论如何使用有 限状态机进行系统的分析和设计,以及如何在软件中进行描述和实现。 二、基于状态机分析的简单按键设计(一) 我们把单个按键作为一个简单的系统,根据状态机的原理对其动作和确认的过程进行分 析,并用状态图表示出来,然后根据状态图编写出按键接口程序。 把单个按键看成是一个状态机话,首先需要对一次按键操作和确认的实际过程进行分 析,根据实际的情况和系统的需要确定按键在整个过程的状态,每个状态的输入信号和输出 信号,以及状态之间的转换关系。最后还要考虑时间序列的间隔。 采用状态机对一个系统进行分析是一项非常细致的工作,它实际上是建立在对真实系统 有了全面深入的了解和认识的基础之上,进行综合和抽象化的模型建立的过程。这个模型必 华东师范大学 电子系 马 潮 9-6 基于AVR的单片嵌入式系统原理与实践应用 须与真实的系统相吻合,既能正确和全面的对系统进行描述,也能够适合使用软件或硬件方 式来实现。 在一个嵌入式系统中,按键的操作是随机的,因此系统软件对按键需要一直循环查询。 由于按键的检测过程需要进行消抖处理,因此取状态机的时间序列的周期为10ms左右,这样不仅可以跳过按键抖动的影响,同时也远小于按键0.3-0.5秒的稳定闭合期(图9-3),不会将按键操作过程丢失。很明显,系统的输入信号是与按键连接的I/O口电平,“1”表示按键处于开放状态,“0”表示按键处于闭合状态(图9-2)。而系统的输出信号则表示检测 和确认到一次按键的闭合操作,用“1”表示。 1 2 图9-4给出了一个简单按键状态机的状态转换图。在图中,将一次按键完整的操作过程 分解为3个状态,采用时间序列周期为10ms。下面对该图做进一步的分析和说明,并根据 状态图给出软件的实现方法。 首先,读者要充分体会时间序列的作用。在这个系统中,采用的时间序列周期为10ms,它意味着,每隔10ms检测一次按键的输入信号,并输出一次按键的确认信号,同时按键的 状态也发生一次转换。 图中“状态0”为按键的初始状态,当按键输入为“1”时,表示按键处于开放,输出 “0”(1/0),下一状态仍旧为“状态0”。当按键输入为“0”,表示按键闭合,但输出还是 “0”(0/0)(没有经过消抖,不能确认按键真正按下),下一状态进入“状态1”。 “状态1”为按键闭合确认状态,它表示了在10ms前按键为闭合的,因此当再次检测 到按键输入为“0”时,可以确认按键被按下了(经过10ms的消抖),输出“1”表示确认按键闭合(0/1),下一状态进入“状态2”。而当再次检测到按键的输入为“1”时,表示按键可能处在抖动干扰,输出为“0”(1/0),下一状态返回到“状态0”。这样,利用状态1,实现了按键的消抖处理。 “状态2”为等待按键释放状态,因为只有等按键释放后,一次完整的按键操作过程才 算完成。 从对图9-4的分析中可以知道,在一次按键操作的整个过程,按键的状态是从“状态0”->“状态1”->“状态2”,最后返回到“状态0”的。并且在整个过程中,按键的输出信号 仅在“状态1”时给出了唯一的一次确认按键闭合的信号“1”(其它状态均输出“0”)。所以上面状态机所表示的按键系统,不仅克服了按键抖动的问题,同时也确保在一次按键整个 的过程中,系统只输出一次按键闭合信号(“1”)。换句话讲,不管按键被按下的时间保持多 华东师范大学 电子系 马 潮 9-7 第9章 键盘输入接口与状态机编程 长,在这个按键的整个过程中都只给出了一次确认的输出,因此在这个设计中,按键没有“连 发”功能,它是一个最简单和基本的按键。 一旦有了正确的状态转换图,就可以根据状态转换图编写软件了。在软件中实现状态机 的方法和程序结构通常使用多分支结构(IF-ELSEIF-ELSE、CASE等)实现。下面是根据图9-4、基于状态机方式编写的简单按键接口函数read_key()。 该简单按键接口函数read_key()在整个系统程序中应每隔10ms调用执行一次,每次执行时将先读取与按键连接的I/O的电平到变量key_press中,然后进入用switch结构构成的状态机。switch结构中的case语句分别实现了3个不同状态的处理判别过程,在每个状 态中将根据状态的不同,以及key_press的值(状态机的输入)确定输出值(key_return),和确定下一次按键的状态值(key_state)。 函数read_key()的返回参数提供上层程序使用。返回值为0时,表示按键无动作;而返回1表示有一次按键闭合动作,需要进入按键处理程序做相应的键处理。 在函数read_key()中定义了3个局部变量,其中key_press和key_return为一般普通 华东师范大学 电子系 马 潮 9-8 基于AVR的单片嵌入式系统原理与实践应用 的局部变量,每次函数执行时,key_press中保存着刚检测的按键值。key_return为函数的返回值,总是先初始化为0,只有在状态1中重新置1,作为表示按键确认的标志返回。变 量key_state非常重要,它保存着按键的状态值,该变量的值在函数调用结束后不能消失, 必须保留原值,因此在程序中定义为“局部静态变量”,用static声明。如果使用的语言环境不支持static类型的局部变量,则应将key_state定义为全局变量(关于局部静态变量 的特点请参考相关介绍C语言程序设计的书籍)。 1) 硬件电路 在前面的章节中曾几次给出了简易实时时钟的设计例子,但都没有加入按键,不能实现 时钟校时的设置。下面结合上面的按键接口的设计,实现对时钟的校时设置。在该例子中, 只是实现了秒的校时设置,其重点是让读者体会和实践按键输入接口和处理的实现。 时钟系统的硬件电路与图6-15基本相同,仅在I/O口PD7上连接一个按键K1,该按键的功能为秒加1,既每按下一次,秒加1,到60秒时分加1,秒回到为0。图9-5为电原理图。 2) 软件设计 以下是采用一个简单按键实现秒单元的校时设置系统的程序。程序中,给出了采用一个 简单按键实现时钟校时(仅秒位)设置功能的基本设计,时钟本身的计时显示方法用秒闪烁 表示(每秒种LED数码管的小数点段闪烁一次)。 华东师范大学 电子系 马 潮 9-9 第9章 键盘输入接口与状态机编程 华东师范大学 电子系 马 潮 9-10 基于AVR的单片嵌入式系统原理与实践应用 华东师范大学 电子系 马 潮 9-11 第9章 键盘输入接口与状态机编程 该程序中LED数码管动态扫描等部分与前面介绍的例子相同,T/C0的工作于CTC方式,每2ms产生中断。在T/CO中断服务中增加了10ms到的标志变量key_stime_ok,作为按键状态机的时间触发序列信号。在主程序中,每隔10ms调用read_key()按键接口程序,当函数返回值为1时,说明产生了一次按键操作过程,秒位加1,然后进行时间调整。 3) 思考与实践 , 仔细分析read_key()函数的调用和执行情况,说明为什么该按键接口程序可以正 确的处理一次按键的操作过程? , 如果将read_key()中标有(1)的语句key_return = 1去掉,而将状态2的处理 程序改为: 华东师范大学 电子系 马 潮 9-12 基于AVR的单片嵌入式系统原理与实践应用 或: 时,按键处理会产生什么变化?为什么? 三、基于状态机分析的简单按键设计(二) 在上面的例子中,对秒的校时设置操作还是不方便,例如,如果将秒从00设置为59,需要按键59次。如果将按键设计成一个具有“连发”功能的系统,就能很好的解决这个问 题。 现在考虑这样的一个按键系统:当按键按下后在1秒内释放了,此时秒计时加1,而当按键按下后在1秒内没有释放,那么以后每隔0.5秒,秒计时就会自动加上10,直到按键释放为止。这样的按键系统就具备了一种“连发”功能,其中时间也成为系统的一个输入参数 了。 参考图9-4,根据状态机的分析方法,可以得到具有上述“连发”功能的按键系统状态 转换图(图9-6)。 1 2 1 3 2 在图9-6所示的图中,按键系统输出“1”表示按键在1秒内释放了,输出“2”表示按键产生一次“连发”的效果。根据图9-4,下面是基于状态机方式编写的带“连发”功能按 键接口函数read_key_n()。 华东师范大学 电子系 马 潮 9-13 第9章 键盘输入接口与状态机编程 华东师范大学 电子系 马 潮 9-14 基于AVR的单片嵌入式系统原理与实践应用 函数read_key_n()与前面的read_key()结构非常类似,设计为每隔10ms被调用执行一次,在构成状态机的switch结构中使用了局部静态变量key_time作为按键时间计数器,按键按下的时间值。 函数read_key_n()的返回参数提供上层程序使用。返回值为0时,表示按键无动作;返回1表示一次按键的“单发”(<1s)动作;返回2表示一次按键的“连发”动作,提供按 键处理程序做相应的键处理。 1) 硬件电路 硬件电路还是图9-6,在I/O口PD7上连接一个按键K1,该按键为具备“连发”功能,按键按下后并在1秒内释放,此时秒计时加1;而当按键按下后在1秒内没有释放,那么每隔0.5秒,秒计时就会自动加上10,直到按键释放为止。 2) 软件设计 以下是采用具备“连发”功能按键实现秒单元的校时设置系统的程序,程序中的显示等 部分与demo_9_1.c相同,仅仅在主程序中做了相应的改变。 华东师范大学 电子系 马 潮 9-15 第9章 键盘输入接口与状态机编程 华东师范大学 电子系 马 潮 9-16 基于AVR的单片嵌入式系统原理与实践应用 主程序中,每隔10ms调用read_key_n()按键接口程序,并根据其返回值对秒位的时间 进行加1或加10的处理。 在上节中按键的连接方法采用的是独立式按键接口方式。独立式按键就是各按键相互独 立,每个按键各占用一位I/O的口线,它们之间状态是独立的,相互之间没有影响,只要单 独测试口线电平的高低就能判断键的状态。独立式按键电路简单、配置灵活,软件结构也相 对简单。此种接口方式适用于系统需要按键数目较少的场合。在按键数量较多的情况下,如 系统需要12或16个按键的键盘时,采用独立式接口方式就会占用太多的I/O口,因此一般适用于按键数量多的硬件连接方式往往使用矩阵式键盘接口。 当键盘中按键数量较多时,为了减少对I/O口的占用,通常将按键排列成矩阵形式,也 称为行列键盘,这是一种常见的连接方式。矩阵式键盘接口见图9-7所示,它由行线和列线组成,按键位于行、列的交叉点上。当键被按下时,其交点的行线和列线接通,相应的行线 华东师范大学 电子系 马 潮 9-17 第9章 键盘输入接口与状态机编程 或列线上的电平发生变化,MCU通过检测行或列线上的电平变化可以确定哪个按键被按下。 图9-7为一个4 x 3的行列结构,可以构成12个键的键盘。如果使用4 x 4 的行列结构,就能组成一个16键的键盘。很明显,在按键数量多的场合,矩阵键盘与独立式按键键 盘相比可以节省很多的I/O口线。 矩阵键盘不仅在连接上比单独式按键复杂,它的按键识别方法也比单独式按键复杂。在 矩阵键盘的软件接口程序中,常使用的按键识别方法有行扫描法和线反转法。这两种方法的 基本思路是采用循环查循的方法,反复查询按键的状态,因此会大量占用MCU的时间,所以较好的方式也是采用状态机的方法来设计,尽量减少键盘查询过程对MCU的占用时间。 下面以图9-7为例,介绍采用行扫描法对矩阵键盘进行判别的思路。图9-7中,PD0、PD1、PD2为3根列线,作为键盘的输入口(工作于输入方式)。PD3、PD4、PD5、PD6为4根行线,工作于输出方式,由MCU(扫描)控制其输出的电平值。行扫描法也称为逐行扫描 查询法,其按键识别的过程如下。 , 将全部行线PD3-PD6置低电平输出,然后读PD0-PD2三根输入列线中有无低电平 出现。只要有低电平出现,则说明有键按下(实际编程时,还要考虑按键的消抖)。 如读到的都是高电平,则表示无键按下。 , 在确认有键按下后,需要进入确定具体哪一个键闭合的过程。其思路是:依次将行 线置为低电平,并检测列线的输入(扫描),进而确认是具体的按键位置。如当PD5 输出低电平时(PD3=1、PD4=1、PD5=0、PD6=1),测到PD1的输入为低电平(PD0=1、 PD1=0、PD2=1),则可确认按键K3-2处于闭合状态。通过以上分析可以看出,MCU 对矩阵键盘的按键识别,是采用扫描方式控制行线的输出和检测列线输入的信号相 配合实现的。 , 矩阵按键的识别仅仅是确认和定位了行和列的交叉点上的按键,接下来还要考虑键 盘的编码,即对各个按键进行编号。在软件中常通过计算的方法或查表的方法对按 键进行具体的定义和编号。 在单片机嵌入式系统中,键盘扫描只是MCU的工作内容之一。MCU除了要检测键盘和处理键盘操作之外,还要进行其他事物的处理,因此,MCU如何响应键盘的输入需要在实际系 统程序设计时认真考虑。 华东师范大学 电子系 马 潮 9-18 基于AVR的单片嵌入式系统原理与实践应用 通常,完成键盘扫描和处理的程序是系统程序中的一个专用子程序,MCU调用该键盘扫描子程序对键盘进行扫描和处理的方式有三种:程序控制扫描、定时扫描和中断扫描。 , 程序控制扫描方式。在主控程序中的适当位置调用键盘扫描程序,对键盘进行读取 和处理。 , 定时扫描方式。在该方式中,要使用MCU的一个定时器,使其产生一个10ms 的定 时中断,MCU响应定时中断,执行键盘扫描,当在连续两次中断中都读到相同的按 键按下(间隔10ms作为消抖处理),MCU才执行相应的键处理程序。 , 中断方式。使用中断方式时,键盘的硬件电路要做一定的改动,增加一个按键产生 中断信号的输入线,当键盘有按键按下时,键盘硬件电路产生一个外部的中断信号, MCU响应外部中断,进行键盘处理。 下面我们介绍基于状态机并采用定时键盘扫描的键盘处理系统的设计方法。 根据图9-7,下面的键盘接口函数read_keyboaed()完成了对4*3键盘的扫描识别和键盘的编码。编码键盘的定义使用define语句定义,键盘的形式类似电话和手机键盘,如图9-8所示。 1 2 3 4 5 6 7 8 9 0 华东师范大学 电子系 马 潮 9-19 第9章 键盘输入接口与状态机编程 华东师范大学 电子系 马 潮 9-20 基于AVR的单片嵌入式系统原理与实践应用 系统主程序应每隔10ms调用该键盘接口函数read_keyboaed(),函数返回值为255时 表示无按键按下。检测和确认按键按下时,函数返回值为0到11之间的一个,该返回值已经是经过了键盘编码的值。 键盘接口函数read_keyboaed()是基于状态机实现的,将键盘扫描处理过程化分成三个 状态,每个状态的功能为: , 状态0,键盘扫描检测。控制PD3-PD6,4根行线逐行输出低电平,对键盘进行扫 描检测。一旦检测到有键按下(key_value),立即停止键盘的扫描,状态转换到状 华东师范大学 电子系 马 潮 9-21 第9章 键盘输入接口与状态机编程 态1。注意此时变量key_value中保存着读到的列线输入值,而且该行线低电平的 输出是保持不变的。 , 状态1,消抖处理和键盘编码。再次检测键盘列线的输入,并与状态0时的key_value 比较,不相等则返回状态0,实现了消抖处理。相等则确认该键的输入,进行键盘 编码和设置函数的返回值,状态转化到状态2。 , 状态2,等待按键释放。控制PD3-PD6,4根行线全部输出低电平,检测3根列线 输入全部为高电平(无按键按下)时状态返回到状态0。 读者在阅读该段程序时,请注意key_mask、key_value、key_line的作用和使用,它们不仅与键盘的硬件连接有关系,同时还要注意他们在程序中是如何使用的,其值的保存等等。 通过这个例子也可以看出,在硬件设计的过程中,也需要认真考虑软件的编写。比如, 你也可以将4根键盘行线与PD0、PD2、PD3、PD6连接,列线使用PD1、PD4、PD5,从硬件的角度看是完全可以的,但会给软件编写造成很多麻烦。所以,一个好的嵌入式系统工程师 必须同时具备良好的软件设计编写能力和硬件设计能力。 实际上read_keyboaed()还是一个比较简单的键盘接口函数,还不能处理类似多键按下 的识别、按键“连发”等功能。但当你真正掌握了基本键盘接口的设计思想和方法后,就可 以在这个简单的键盘接口函数基础上,设计出功能更加完善的键盘系统了。 当AVR的I/O口处于输入方式工作时,其对应的PINx就是外部引脚上的实际电平。为了防止读入PINx时数据的不稳定和不确定,(例如在读的期间,正好引脚电平发生 改变),AVR的I/O输入端到总线之间加入一个同步锁存器,用以保证读入数据的稳定和确 定。同步锁存器在系统I/O时钟的作用下,经过1/2-3/2个系统时钟周期,将引脚电平锁定, 提供MCU读取。也就是说外部引脚的电平变化要经过1/2-3/2个时钟周期才能真正的被读到,见图9-9。 因此,当编写程序读取AVR的I/O口PINx电平值时应注意: , 当I/O口从输出方式改成输入方式后,应延时一个CLK再读。 , 当I/O外部引脚电平改变后,也要延时一个CLK后再读取。 华东师范大学 电子系 马 潮 9-22 基于AVR的单片嵌入式系统原理与实践应用 在本例的键盘扫描程序中,根据扫描条件,首先改变行线输出的电平,如果按键按下的 话,那么对应点的列线(输入口)电平也马上改变了,此时需要延时一个CLK后读列线的输入电平值才是正确的。程序中采用输出2次相同的行电平的方式,第2次输出的实际作用是起到延时的作用(其实相当于2个NOP)。当然,也可以输出1次行电平,在读I/O口时采用读2次的方式,只要满足规定的延时时间就可以的。 1) 硬件电路 在这个例子中,结合图9-7的硬件电路和图9-8定义的键盘,实现一个简单的电话拨号 键盘。系统由PA、PC口控制的8个LED数码管和PD口的4*3键盘组成,系统上电时,8个LED数码管显示“--------”8条横线,每按下一个号码后,原8位LED数码管的显示内容向左移动一位,最右边一位则显示键盘上刚按下的数字(“*”键用“A”表示,“#”键用“b”表示)。要求:对键盘按键操作的反应迅速而且无误,同时按键操作过程中应保证LED的扫描显示均匀、连续不间断。 2)软件设计 华东师范大学 电子系 马 潮 9-23 第9章 键盘输入接口与状态机编程 华东师范大学 电子系 马 潮 9-24 基于AVR的单片嵌入式系统原理与实践应用 3)思考与实践 程序中LED扫描和定时器的使用与以前的方式相同,每隔2ms进行LED的扫描,同时每隔10ms调用read_keyboard()键盘接口程序读键盘,并根据返回结果调整LED显示的内容。程序本身不复杂,主要体会键盘接口程序的功能和使用,请读者自己分析并实现。 , 本例中,在T/C0的中断服务中进行了LED的扫描,而读键盘和键盘处理是在主程序中 完成的。如果将读键盘和键盘处理也放在T/C0中断中完成是否可以?请深入分析这两 种处理方式的优点和缺点,说明原因。 , 在read_keyboard()中,行线输出语句为什么重复2次? , 说明在read_keyboard()中,key_mask的作用,另外是否可以将变量key_line和 key_value定义成普通的局部动态变量?为什么? , 修改程序,键盘上数字键功能不变,而“#”键的功能为总清除(即清除LED上的全部 的数字显示,显示复原为8个“-”),“*”键的功能为修改键(表示最后输入的数字有 误,LED显示全部左移一位,清除最后输入的数字,最左边一位补入“-”)。 1.在按键处理过程中,除了要进行消抖处理,还要判别按键的释放,如果不进行按键释放 的判别,会发生什么现象? 2.为什么要使用状态机的程序设计方法?该方法有什么优点?说明其基本原理。 3.如何使用状态机的程序设计方法来设计嵌入式系统的软件,在程序设计中应注意和掌握 华东师范大学 电子系 马 潮 9-25 第9章 键盘输入接口与状态机编程 那些原则? 4.说明矩阵式键盘的硬件结构和软件处理思想。 5.认真分析和理解本章中所给出的所有示例,并进行实践,思考和回答所有的问题。 6.简易秒表的设计与实现 使用6个数码管组成秒表的显示,两个一组,分别显示分、秒和百分之一秒。使用一个 按键,作为秒表的记时控制。秒表初始显示“00.00.00”;第一次按键,秒表启动百分之一秒的记时并显示;第二次按键,秒表停止百分之一秒的记时,显示器显示两次按键之间的相 隔时间;第三次按键,秒表复位,显示“00.00.00”。 ------------------------------------------------------------------------------- 本章参考文献: 1.《ATmega16数据》(英文,CDROM),ATMEL,www.atmel.com 华东师范大学 电子系 马 潮 9-26
/
本文档为【第9章 键盘输入接口与状态机编程】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索