资源描述
基于飞梭的人机接口设计
摘 要
本设计采用PIC24HJ作为主控芯片,通过飞梭和按键两个外部输入设备来控制1602液晶显示。能够在液晶上实现英文和数字显示,光标的移动,通过飞梭改变数值的大小等功能。单键飞梭(又称旋转编码器,或数字编码器),包含三个引脚:端口A,端口B,地GND。将端口A,B上拉到VCC,然后旋转单键飞梭,就能在示波器中观察到飞梭的电平转换过程,和电平抖动的现象。为了合理的消除抖动,在不添加外部硬件,同时不影响单键飞梭和单片机工作的性能条件下,根据飞梭的电平转换过程,在本设计中通过将端口A连接到PIC24HJ芯片的INIT1脚,合理设置飞梭判断程序和单片机的中断程序,在飞梭旋转的过程中就能够实现交替的执行外部中断程序,从而来确定飞梭转动的方向和转动的格数。
词
The Design Of User-Interface Based On Rotary Encoder
Rotary Encoder , 1602LCD,PIC24HJ
2.1 控制芯片PIC24芯片介绍
2.1.1 PIC24芯片部分性能及特点
2.2 16*2 字符型带背光液晶模组介绍
2.2.1 16*2 字符型液晶显示模块的内部结构2.4. 按键的抖动处理
3.1系统流程图
3.2 1602LCD初始化程序:3.4 按键消抖MPLAB IDE简介:
4.2 开发平台
4.3 烧写芯片
:
5 总随着计算机软、硬件技术的发展,嵌入式系统在工业控制中的应用越来越广。人机界面凭借其使用简单、交互方便、控制灵活、画面组态等优点也逐渐由工控机平台向嵌入式平台转移。工控设备日益繁多复杂,工控市场竞争日益激烈,因此,研究和开发界面友好、组态功能完善、通信能力强大的嵌入式控制系统人机界面,是技术发展的需要,是市场需求的呼唤。[1]
在工业技术发展和改造的过程中 ,为了方便工艺参数的记录和分析,以及及时的了解现场工作的情况,加强对整个工艺工程状况的把握,用户希望所使用的控制系统能够对生产信息进行直观,全面的监控,从而将人机界面的概念引入到工业设备中来而形成了工业人机界面设备,经过逐步发展工业人机界面设备已经广泛应用与各种工业现场,并逐步趋于智能化,嵌入化和网络化。[1]
工业人机界面能取代大部分传统控制面板的功能,使用人机界面不但可以节省PLC 的I/O 点数,还可节省大量的各式按钮开关,数字设定及指示灯等显示装置,且能随时显示重要信息,以利于操作人员正确掌握机器状况和避免错误,利于维修。人机界面能储存多幅画面,每一画面可由文字,图形以及指定的PLC 资料组成,设计者可依需要编辑出各种画面,用以显示设备状态、操作指示、参数设定、动作流程、统计资料、报警信息、简易报表等内容。
人机界面的主要功能有:数据的输入与显示;系统或设备的操作状态方面的实时信息显示;在人机界面上设置触摸控件可把人机界面作为操作面板进行控制操作;报警处理及打印;此外新一代工业人机界面还具有简单的编程,对输入的数据进行处理,数据记录及配方等智能化控制功能。
“单键飞梭”,作为一种用户输入方法,能在一定场合替代传统的按键。凭借其输入方式灵活可靠、成本低特别适合应用在嵌入式仪器设备和手持式设备上。使用飞梭不但能够简化软件设计,降低程序设计周期;而且提高了用户输入效率,满足生活电子“方便快捷”的要求。[5]
2.1 控制芯片PIC24芯片介绍
PIC24HJXXXGPX06A/X08A/X10A系列器件包括具有不同引脚数 (64 和 100 引脚)配置、不同程序存储容量(64 KB、128 KB和256 KB)和不同RAM容量(8 KB和16 KB)的器件。
这使本系列器件适合于多种高性能控制应用。器件的引脚与 dsPIC33F 系列器件的引脚兼容,并且还与dsPIC30F 系列器件高度兼容。这样便于根据应用对特定功能、计算资源和系统成本等方面的需求,在不同系列器件之间移植。
PIC24HJXXXGPX06A/X08A/X10A 系列器件采用强大的 16 位架构,对于需要高速、重复计算和控制的应用非常理想。
17 x 17 位乘法器、除法运算支持硬件、多位数据移位寄存器、大的 16 位工作寄存器阵列和多种数据寻址模式,共同为 PIC24HJXXXGPX06A/X08A/X10A 中央处理单元(Central Processing Unit,CPU)提供广泛的数学处理能力。灵活而确定的中断处理与功能强大的外设相结合,使得 PIC24HJXXXGPX06A/X08A/X10A 器件非常适合控制应用。此外,直接存储器访问(DMA)允许数据在多个外设和专用DMA RAM之间进行无CPU开销的传输。可靠的现场可编程闪存程序存储器确保能对使用 PIC24HJXXXGPX06A/X08A/X10A 器件的应用进行扩展。
2.1.1 PIC24芯片部分性能及特点
高性能 CPU:
• 改进型哈佛架构
• C 编译器优化的指令集
• 16 位宽数据总线
• 24 位宽指令
• 可寻址最大4M指令字的线性程序存储空间
• 可寻址最大64 KB 的线性数据存储空间
• 71 条基本指令:多为单字/ 单周期指令
• 16 个16 位通用寄存器
• 灵活和强大的间接寻址模式
• 软件堆栈
• 16 x 16 位乘法运算
• 32/16 位和 16/16 位除法运算
• 可将数据左移或右移最多16位
中断控制器:
• 中断响应延时为5 个周期
• 最多61个中断源
• 最多5 个外部中断
• 7 个可编程优先级
• 5 个处理器异常数字 I/O:
• 最多85个可编程数字 I/O引脚
• 最多24个引脚上具有唤醒 /电平变化中断功能
• 输出引脚可驱动3.0V至 3.6V的电压
• 所有数字输入引脚可承受5V的电压
• 所有I/O引脚的灌电流为4 mA
2.2 16*2 字符型带背光液晶模组介绍
1602LCD液晶
字符型液晶显示模块(LCM)是一类专门用于显示字母、数字、符号等的点阵型液晶显示模块。在显示器件的电极图形设计上,它是由若干个5*7 或5*11 等点阵字符位组成。
每一个点阵字符位都可以显示一个字符。点阵字符位之间空有一个点距的间隔起到了字符间距和行距的作用.
16*2 字符LCD 模块的控制器主要为日立公司的HD44780 及其替代集成电路,驱动器为HD44100 及其替代的兼容集成电路。
◆16*2 字符型液晶显示模块特性
1.+5V 电压,反视度(明暗对比度)可调整。
2. 内含振荡电路,系统内含重置电路。
3.提供各种控制命令,如清除显示器、字符闪烁、光标闪烁、显示移位等多种功能。
4.显示用数据DDRAM 共有80 个字节。
5.字符发生器CGROM 有160 个5*7 点阵字型。
6.字符发生器CGRAM 可由使用者自行定义8 个5*7 的点阵字型。
◆16*2 字符型液晶显示模块引脚及功能
1 脚(Vdd/Vss):电源5V±10%或接地。
2 脚(Vss/Vdd):接地或电源5V±10%。
3 脚(VO):反视度调整。使用可变电阻调整,通常接地。
4 脚(RS):寄存器选择。1:选择数据寄存器;0:选择指令寄存器。
5 脚(R/W):读/写选择。1:读;0:写。
6 脚(E):使能操作。1:LCM 可做读写操作;0:LCM 不能做读写操作。
7 脚(DB0):双向数据总线的第0 位。
8 脚(DB1):双向数据总线的第1 位。
9 脚(DB2):双向数据总线的第2 位。
11 脚(DB3):双向数据总线的第3 位。
11 脚(DB4):双向数据总线的第4 位。
12 脚(DB5):双向数据总线的第5 位。
13 脚(DB6):双向数据总线的第6 位。
14 脚(DB7):双向数据总线的第7 位。
15 脚(Vdd):背光显示器电源+5V。
16 脚(Vss):背光显示器接地。
2.2.1 16*2 字符型液晶显示模块的内部结构
LCM 的内部结构可分为三个部分:LCD 控制器,LCD 驱动器,LCD 显示装置,
◆液晶显示控制驱动集成电路HD44780 特点:
l. HD44780 不仅作为控制器而且还具有驱动40*16 点阵液晶像素的能力,并且HD44780的驱动能力可通过外接驱动器扩展360 列驱动。
2. HD44780 的显示缓冲区及用户自定义的字符发生器CGRAM 全部内藏在芯片内。
3. HD44780 具有适用于M6800 系列MCU 的接口,并且接口数据传输可为8 位数据传输和4 位数据传输两种方式。
4.HD44780 具有简单而功能较强的指令集,可实现字符移动、闪烁等显示功能。
◆HD44780 工作原理
1. DDRAM--数据显示用RAM(Data display RAM,简称DDRAM)
DDRAM 用来存放我们要LCD 显示的数据,只要将标准的ASCII 码送入DDRAM,内部控制电路会自动将数据传送到显示器上,例如要LCD 显示字符A,则我们只须将ASCII码41H 存入DDRAM 即可。DDRAM 有80bytes(字节)空间,共可显示80 个字(每个字为1 个bytes),其存储器地址与实际显示位置的排列顺序与LCM的型号有关
2 . CGROM--字符产生器ROM(Character Generator 的ROM,简称CGROM)
CGROM 储存了192 个5*7 的点矩阵字型,CGROM 的字型要经过内部电路的转换才会传到显示器上,仅能读出不可写入。字型或字符的排列方式与标准的ASCII 码相同,例如字符码 31H 为 l 字符,字符码41H 为A 字符。如我们要在LCD 中显示A,就是将A 的ASCII 代码41H 写入DDRAM 中,同时电路到CGROM 中将A 的字型点阵数据找出来显示。
3. CGRAM--字型、字符产生器RAM(Character Generator RAM,简称CGRAM)
CGRAM 是供使用者储存自行设计的特殊造型的造型码RAM,CGRAM 共有512bits(64 字节)。一个5*7 点矩阵字型占用8*8bit,所以CGRAM 最多可存8 个造型。
4. IR--指令寄存器(Instruction Register,简称IR)
IR 寄存器负责储存MCU 要写给LCM 的指令码。当MCU 要发送一个命令到IR 寄存器时,必须要控制LCM 的RS、R/W 及E 这三个引脚,当RS 及R/W 引脚信号为0,E 引脚信号由1 变为0 时,就会把在DB0~DB7 引脚上的数据送入IR 寄存器。
5. DR--数据寄存器(Data Register,简称DR)
DR 寄存器负责储存MCU 要写到CGRAM 或DDRAM 的数据,或储存MCU 要从CGRAM 或DDRAM 读出的数据,因此DR 寄存器可视为一个数据缓冲区,它也是由LCM的RS、R/W 及E 等三个引脚来控制。当RS 及R/W 引脚信号为l,E 接脚信号由1 变为0时,LCM 会将DR 寄存器内的数据由DB0~DB7 输出以供MCU 读取;当RS 接脚信号为l,R/W 接脚信号为0,E 接脚信号由1 变为0 时,就会把在DB0~DB7 引脚上的数据存入DR寄存器。
6. BF--忙碌标志信号(Busy Flag,简称 BF)
BF 的功能是告诉MCU,LCM 内部是否正忙着处理数据。当BF=1 时,表示LCM 内部正在处理数据,不能接受MCU 送来的指令或数据。LCM 设置BF 的原因为MCU 处理一个指令的时间很短,只需几微秒左右,而LCM 得花上40 微秒~1.64 亳秒的时间,所以MCU要写数据或指令到LCM 之前,必须先查看BF 是否为0。
7. AC--地址计数器(Address Counter,简称AC)
AC 的工作是负责计数写到CGRAM、DDRAM 数据的地址,或从DDRAM、CGRAM读出数据的地址。使用地址设定指令写到IR 寄存器后,则地址数据会经过指令解码器(Instruction Decoder),再存入AC。当MCU 从DDRAM 或 CGRAM 存取资料时,AC 依照MCU 对LCM 的操作而自动的修改它的地址计数值。
图2-1 单键飞梭
单键飞梭,或者称增量式旋转编码器是一种将角位移转化成电信号的装置,如图2-1所示。将位移转换成周期性的电信号再把这个电信号转变成计数脉冲,用脉冲的个数表示位移的大小。
单键飞梭一般包含三个引脚:端口A,端口B,地GND。飞梭旋转一周还包含有24个定位槽(不同型号定位槽的个数也不同)。当飞梭转动到定位槽处时,会发出响声如同按键按下,这样能够有效地避免飞梭的当前位置处于两个定位槽之前,提高飞梭的稳定性。将端口A,B接上拉电阻,当旋转飞梭时,在端口A,B都会有相应的矩形波输出,在示波器中能够观察到下图的波形。[4]
图2-2 飞梭旋转时的波形图
由于端口A,B输出的两个信号相位相差90°,因此编码器的旋转方向将很容易被确定。观察图2-2 ,当飞梭顺时针旋转时,当端口A有一个上升沿的时候,对应端口B是低电平,逆时针旋转时,当端口A有一个上升沿的时候,对应端口B是高电平。这使得我可以通过一段简单的程序就能判断飞梭旋转地方向了。
理想情况下,只需要端口A一个上升沿中断。一旦中断发生,端口B的电平将决定编码器转动的方向。但是,就如按键存在电平抖动的情况,单键飞梭同样也存在这个问题。如图2-3。当在端口A的下降沿之后,发生电平抖动。又出现一个上升沿,就会触发中断服务程序,而这时端口B的电平为高电平,从而发生错误。
图2-3 飞梭的电平抖动波形
飞梭的消抖的方法有很多种。旋转编码器的消抖类似于按键的消抖。在端口A 为上升沿跳变后,我们可以不断的观察它一段时间,直到端口A的信号平稳为止。这段时间就是电平抖动的时间,同时它也是非常短的的,因为如果我们等的时间太长,端口A和B的信号可能已经被改变了。一般而言,在端口A发生中断后480us,端口B的电平将改变。
图2-4 飞梭的电平抖动分析
在飞梭转动时由于转轴转动不稳,引起干扰脉冲。在A,B时刻,端口A处于抖动状态,此时端口的信号一直处于高电平。在A,C时刻比较,当飞梭装过一个定位槽后,端口B的电平发生变化。因此由图2-4可知,抖动干扰信号两个跳变沿时刻所对应的另一相脉冲信号的电平值总是一致的 ,因此 ,可以利用 D 触发器将两跳变时刻所对应的另一相脉冲的逻辑电平寄存起来 ,并在计数时刻进行比较。若一致则为干扰信号 ,计数器停止计数;若不一致则为正常工作信号 ,计数器进行正常计数 ,从而消除抖动引起的重复计数现象 ,实现高精度计量。[5]
因此,可以使用可编程逻辑器件(FPGA,CPLD)设计一个D触发器和计数器,将飞梭输出的信号输入到该消抖器件中,能够有效地过滤干扰信号,从而可以得到一个稳定的矩形脉冲输出信号。
优点:通过可编程逻辑器件过滤后输出的脉冲信号,能够实现高精度的测量。系统稳定性大大提高。
缺点:成本高,设计难度大。
由于在本设计中单键飞梭的使用,对精度要求不高。即使出现个别干扰信号未过滤,对光标的移动等操作影响也不大。因此没有选择这种方案。
1) 专用消抖芯片MC14490
MC14490是Motorola公司生产的用于消除信号抖动的电路,共有六组输入输出,每组都有一个4 位寄存器(积分器)和将输入与移位寄存器的内容相比较的逻辑单元。移位寄存器通过一串定时脉冲将输入信号移位到寄存器的各个位。定时脉冲可以由片内的振荡器产生,也可以由外部时钟电路产生经振荡器输入端输入。如图2-5所示。
图2-5 MC14490内部原理图
如果定时脉冲来时,输入信号的当前状态与寄存器以前的状态一致,就将移位寄存器每一位的状态后移一位,这样,如果输入状态在连续四个定时脉冲周期不发生变化,则移位寄存器的每一位的状态都一样,信号最终经反向器输出;如果在此期间输入状态发生变化,则移位寄存器的每一位都被恢复到原来的寄存器输出状态,以上过程重新开始。在输入与输出信号之间的时间畴(time distortion) 变量依赖于输入信号边沿上的抖动特性以及时钟信号的频率。因此,为了获得没有抖动的输出信号,时钟频率就需满足一个条件:在连续四个时钟脉冲周期内,输入信号不能有变化。因此,改变振荡器输入端输入的时钟信号的频率也就是改变了去抖电路低通滤波器的截止频率。
图2-6 MC14490 时序图
假设当移位寄存器所有位均输入低电平时,信号最终输出为高电平;反之,输出信号为低电平。如图2-6所示,在时钟脉冲1的下降沿,输入信号已达低电平,一个高电平就输入至该移位寄存器的第一位,当这一脉冲的下降沿过去时,输入信号又转为高电平,引起移位寄存器的所有位复位至低电平,于是一个时序重新开始。在时钟脉冲3至6的上升沿之间,输入信号保持低电平,因此高电平被传至移位寄存器的所有的四个位上,到下一个时钟脉冲的上升沿期间,输出转为低电平。N+1个时钟脉冲过去后,输入抖动为低电平,寄存器所有位都置于高电位;在N+2个脉冲到来时,状态不发生变化,这是因为输入输出都是低电平,且该移位寄存器的所有位均为高电平;在N+3个脉冲以后,输入信号为清晰的高电平信号;到N+6个脉冲的上升沿,因为四个低电平被移入移位寄存器,故输出转为高电平。[6]
优点:使用专用的消抖芯片,能够保证输出的信号将不会受到抖动信号的干扰。使得系统的设计简化,缩短开发周期。
缺点:增加成本,如果对系统的体积要求高的,也将不合适。
适合于对开发周期要求短,同对应抗抖动信号要求高,对成本要求不严格的系统。因此,在本系统中,没用选用这种方案。
软件消抖的一般步骤,如图2-7所示:
① 在端口A触发中断后,关闭A中断使能,开启B中断使能。
② 在端口B触发中断后,如果此时端口A是低电平,则置位一个标记(flag),同时,关闭B中断使能,开启A中断使能。
③ 在端口A触发中断后,判断标记(flag)是否被置位,如果已经被置位,则读取端口B的电平。如果是低电平,则为顺时针转动;反之,则为逆时针转动。同时,关闭A中断使能,开启B中断使能。
④ 在端口B触发中断后,关闭B中断使能,开启A中断使能
在只用GPIO口,没有消抖模块的前提下,只有考虑不依赖时间的解决办法。首先,允许两个端口都能够产生上升沿和下降沿中断(电平触发)。值得注意的是,同一时间只有一个中断被允许,而且每一次一个端口被允许中断时,我们就能够交替实现中断服务程序的调用。同时,也要保证在一个端口触发中断时,另一个端口已经结束抖动。尽管编码器在快速旋转,通过用示波器观察波形显示了波形是稳定的。所以,当一个端口发生中断时就告诉我们可以读另一个端口的电平了。
通过中断服务程序计算旋转编码器的旋转方向。在端口A产生一个上升沿中断之前,端口B总是会产生一个中断。当端口B 发生中断时,我们能测得端口A的电平(此时端口A 没有发生抖动)。如果端口A时低电平的,那么无论我们是顺时针旋转还是逆时针旋转,端口A都将产生一个上升沿。当A发生中断时,端口B的没有抖动的电平,就可以决定旋转编码器转动的方向。[4]
旋转编码器容易被用来做一个PSoC的接口来替代一部分按键。作为一个嵌入式系统用户接口的一部分,他们提供了一种快速方法在一个大范围数字之间调节。理想情况下,在每一个定位槽产生一个中断信号,来决定旋转的方向。然而程序算法中用到四次中断。虽然这增加了CPU的开销,但是除了消抖的问题将不需要使用任何数字或者模拟的模块.
优点:不需要额外的硬件消抖处理,节约成本。同时,能够有效地去除抖动。
缺点:必须要求作为主控制器的单片机拥有至少两个空闲的外部中断接口,而且这两个外部中断接口能够实现电平跳变触发。
本系统采用功能强大,资源丰富的PIC24芯片,拥有5个外部中断,使用该消抖动方法,可以有效地去除抖动,同时又不需要添加额外的硬件消除抖动。
2.4. 按键的抖动处理
由于按键的结构为机械弹性开关,因此按键从最初按下到接触稳定需数毫秒的弹跳时间,这样的抖动时间一般在 5~10ms,松开键时也有同样的问题,如图2-8所示。这种抖动对于人来说是感觉不到的,但对计算机来说,则是完全可以感应到的,因为计算机处理的速度是在微秒级,而机械抖动的时间至少是毫秒级。抖动会引起 CPU 对一次按下键或断开键进行多次处理,从而导致错误。因此,在单片机键盘系统中必须要消除抖动。常用的去抖动的方法有两种:硬件方法和软件方法。
图2-8 按键的电平抖动现象
硬件方法:图 2-9-a 所示,利用双稳态电路去抖;图 2-9-b 是利用单稳态去抖;图 2-9-c 利用RC 积分电路去抖。
a)双稳态消抖电路 b)单稳态消抖电路 c)滤波消抖电路
图2-9 普通按键硬件消抖方法
软件方法:在第一次检测到按下按键后,经过一定延时时间后(通常采用调用延时子程序方法消除抖动),再次检测按键是否按下。如果两次检测都有信号,那么就有按键按下了。延时子程序的时间同样要根据按键抖动的情况而定。如果延时时间太短了,则起不到消除抖动的效果;如果延时时间太长了,则键盘不灵活,错过较多的按键信号。
3.1系统流程图
本设计的软件程序是基于MPLAB IDE平台开发,通过MPLAB ICD 2 进行在线调试。本设计中,最主要的是软件部分,所有的操作都是由基于PIC24单片机程序实现的。上电开机后,单片机和外设进行初始化操作,之后进入开始界面。当按键按下一次后,旋动单键飞梭,在1602LCD上的光标将会随转动方向移动。在按键按下第二次后,随着飞梭的转动,能够改变1602LCD 光标当前位置的数值。
3.2 1602LCD初始化程序:
在本系统中,LCD液晶作为一个显示输出设备,起着非常重要的作用。飞梭和按键输入的信号,被PIC单片机接受,并对LCD液晶发出不同控制命令。在LCD液晶上的显示的不同内容,反馈给用户,使用户了解飞梭或键盘进行了哪些操作。
指令(数据)的读和写时序
读操作时序
写操作时序
时序参数
LCD初始化流程图
/****************LCD1602显示和初始化************************/
void delay(uint ms)//延时
{
uint i,j;
for(i=0;i<ms;i++)
{
for(j=0;j<200;j++);
}
}
void delayus(uint us)//延时
{
uint i,j;
for(i=0;i<us;i++)
{
for(j=0;j<10;j++);
}
}
void checkbusy()//忙检验
{
TRISA|=0XffFF; //为输入
LCD_RS=0;
LCD_RW=1;
LCD_E=1;
while(LCD_Data&0X80);
TRISA&=0X0000; //为输出
}
void write_com(uchar com)//写命令
{
//checkbusy();
//LCD_Data=com;
LCD_RS=0;
LCD_RS=0;
LCD_RW=0;
Nop();
LCD_Data=com;
Nop();
LCD_E=1;
delay(1);
LCD_E=0;
}
void write_dat(uchar dat)//写数据
{
LCD_RS=1;
LCD_RS=1;
Nop();
LCD_RW=0;
Nop();
LCD_Data=dat;
Nop();
LCD_E=1;
delay(1);
LCD_E=0;
}
void lcd_init()//初始化
{
write_com(0X38);///双行显示
delay(5);
write_com(0X38);
delay(5);
write_com(0X38);
delay(5);
write_com(0X08);///关闭显示屏
delay(5);
write_com(0X01);///清除DDRAM的所有单元,光标被移动到屏幕左上角
delay(5);
write_com(0X06);///地址指针加一,屏幕上的内容不滚动
delay(5);
write_com(0X0C);///打开显示屏,不显示光标,光标所在位置的字符不闪烁。
delay(5);
write_com(0X0F);///打开显示屏,显示光标,光标所在位置的字符闪烁
delay(5);
}
void displayone(uchar x,uchar y,uchar one)//写一个字符
{
uchar temp;
temp=x&0x0f; //确保列数在0~15的范围内取值;
y&=0x01; //确保行数在0和1之间取值;
if(y) temp|=0x40; //若是第二行,DDRAM的地址必须加0x40;
temp|=0x80;
Nop();
write_com(temp); //形成DDRAM写入指令;
delay(1);
write_dat(one);
delay(1);
}
void display(uchar x,uchar y,uchar m, uchar *dat)//写字符串
{
uchar temp,i;
temp=x&0x0f; //确保列数在0~15的范围内取值;
y&=0x01; //确保行数在0和1之间取值;
if(y) temp|=0x40; //若是第二行,DDRAM的地址必须加0x40;
temp|=0x80;
write_com(temp); //形成DDRAM写入指令;
delay(1);
for(i=0;i<m;i++)
{
write_dat(dat[i]);
delay(1);
}
}
void diplay_v(uchar x,uchar y,uchar j,uint dat)//写一数据
{
uchar i,table[10];
for(i=0;i<j;i++)
{
table[i]=dat%10+'0';
dat/=10;
displayone(x+j-1-i,y,table[i]);
}
}
/***********************LCD1602显示****************************/
在本系统中,飞梭的消抖方法采用软件消抖。Pic24的外部中断口能够实现电平变化中断。
控制飞梭左右旋转,实现光标在第二行移动。飞梭每转一格,光标跳两格。当光标到达最左或最右,除改变旋转方向,将在原地闪烁。
/////////////////飞梭光标////////////////////////////
if(key_flag1==0)
{
while(B==0)
{
while(!FS_B);
while(!FS_A);
delay(10);
B=2;
if(x_count>=7) x_count=7;
else
x_count+=2;
diplay_v(x_count,1,1,net2[x_count]);
displayone(x_count-1,1,0X20);
direct_flag=1;
}
while(B==1)
{
while(FS_B);
while(!FS_A);
while(!FS_B);
delay(10);
B=2;
if(x_count<=1) x_count=1;
else
x_count-=2;
diplay_v(x_count,1,1,net2[x_count]);
displayone(x_count-1,1,0X20);
direct_flag=1;
}
key_flag1=3;
}
IFS1bits.INT1IF = 0; //Clear the INT1 interrupt flag or else
//the CPU will keep vectoring back to the ISR
}
/*********************飞梭中断程序****************************/
void INTx_IO_Init(void)
{
INTCON2 = 0x0002; /*Setup INT1, INT2, INT3 & INT4 pins to interupt */
/*on falling edge and set up INT0 pin to interupt */
/*on rising edge */
IFS1bits.INT1IF = 0; /*Reset INT1 interrupt flag */
IEC1bits.INT1IE = 1; /*Enable INT1 Interrupt Service Routine */
}
void __attribute__((__interrupt__)) _INT1Interrupt(void)
{
B=FS_B;
key_flag1=key_flag;
飞梭左右旋转,通过软件消抖方法正确判断飞梭旋转方向,实现正确改变该光标所对应位置数字的大小。当数值为最大或最小时,除改变旋转方向,将保持最大或最小值不变。
////////////////////////////numbers////////////////////////////////////
if(key_flag1==1)
{
while(B==0) //右
{
while(!FS_B);
while(!FS_A);
delay(10);
B=2;
if(net2[x_count]>=9)net2[x_count]=9;
else
++net2[x_count];
diplay_v(x_count,1,1,net2[x_count]);
displayone(x_count-1,1,0X20);
direct_flag=1;
}
while(B==1) //左
{
while(FS_B);
while(!FS_A);
while(!FS_B);
B=2;
if(net2[x_count]<=0)net2[x_count]=0;
else
--net2[x_count];
diplay_v(x_count,1,1,net2[x_count]);
displayone(x_count-1,1,0X20);
direct_flag=1;
}
key_flag1=3;
}
//////////////////ZZZZZZ////////////////////////////
/***********************飞梭中断程序****************************/
3.4 按键消抖
通过if语句判断KEY是否处于低电平。如果是,则表示按键可能处于按下状态,经延迟后再判断,若仍然处于低电平状态,确定按键按下。
/////////////KEY///////////////////
if(KEY=
展开阅读全文