单片机C语言实现键盘驱动详解

需积分: 9 1 下载量 193 浏览量 更新于2024-09-15 收藏 64KB DOC 举报
"这篇文档是关于单片机C语言实现4x4键盘驱动的教程,包含了一个头文件<KEY.H>的定义以及对应的函数实现文件<KEY.C>。主要介绍了如何设计一个简单的键盘驱动系统,包括检测按键、读取按键值、管理按键缓冲队列等功能。" 在单片机开发中,键盘驱动是必不可少的一部分,它负责处理用户通过键盘输入的数据。在这个例子中,我们关注的是一个4x4矩阵键盘,这种键盘由4行4列的按键组成,总共可以提供16个独立的按键。驱动程序的设计目的是使得上层的应用程序能够方便地获取和处理这些按键的输入。 首先,定义了头文件<KEY.H>,其中声明了以下几个关键函数: 1. `keyHit(void)`: 这个函数用于检查是否有按键被按下。如果按键被按下,它会返回非零值,否则返回零。这通常是一个非阻塞函数,快速检查键盘状态。 2. `keyGet(void)`: 这个函数用于读取当前被按下的按键值。如果没有任何按键被按下,它会等待直到有按键被按下。读取到按键值后,该函数会更新读取位置。 3. `keyPut(unsignedchar ucKeyVal)`: 这个函数将按键值`ucKeyVal`存入按键缓冲队列。这个队列用于暂时存储按键值,防止丢失。 4. `keyBack(unsignedchar ucKeyVal)`: 如果需要撤销最近的按键操作,这个函数会将键值`ucKeyVal`退回至缓冲队列的头部。 在<KEY.C>文件中,定义了一个16字节大小的按键缓冲队列`KeyBuf`,以及两个指针变量`KeyBufWp`(写入位置)和`KeyBufRp`(读取位置),用于跟踪队列中的数据存取状态。队列采用FIFO(先进先出)的方式工作,当`KeyBufWp`等于`KeyBufRp`时,表示缓冲队列为空。 `keyHit(void)`函数通过比较`KeyBufWp`和`KeyBufRp`来判断是否有按键事件发生。`keyGet(void)`函数则在有按键时从队列中读取并返回按键值,并更新读取位置。`keyPut(unsignedchar ucKeyVal)`将新的按键值存入缓冲队列,而`keyBack(unsignedchar ucKeyVal)`则将键值移回队列头部,实现了按键的撤销功能。 这样的键盘驱动设计允许单片机系统高效地处理键盘输入,同时也提供了错误恢复机制,确保了程序的稳定性和用户体验。在实际应用中,可能还需要考虑按键的防抖动处理、多按键同时按下(扫描码解码)等问题,以进一步完善键盘驱动。
2011-06-09 上传
c语言实现单片机的键盘程序 #include "SST89x5x4.H" #include #define uchar unsigned char #define uint unsigned int #define _Nop() _nop_() unsigned char code Key_Value_Table[16]={0xff,0x00,0x01,0xff,0x02,0xff,0xff,0xff, 0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; void Key_Init(void); unsigned char GetScanKey(void); unsigned char GetKey(void); void LCD_Init(void); void LCD_Init2(void); //void WriteW(uint a); void CheckBF(void); unsigned char Key_ASC2(unsigned char); void WritD(unsigned char); void Delay_ns(int i); void Delay_ms(int ms); unsigned char key; unsigned char key_asc2; unsigned char bKeyUp_Flag; uchar xdata *ptr; //函数功能描述:键盘初始化,将标志位置1; void Key_Init(void) { bKeyUp_Flag=1;//标志(全局变量)位置1 } //函数功能描述:键盘扫描函数,得到键的行列位置; unsigned char GetScanKey(void) { unsigned char key, i, temp; unsigned char xdata * ptr; key=0xff; for (i=1; i<0x10; i<<=1) //i的低4位为行数位,行依次检测 循环4次 { ptr=0x8fff; //数码管位选地址 * ptr =i; temp = * ptr; //取键盘IO口的值 temp &= 0x0f; //屏蔽高四位 if (temp!=0x00) //是否有有效键值 { key = i<<4; //取行数位的值并将其放入返回值高4位 key|=temp; //列数位的值放入返回值低4位 break; } } return key; //返回行位(高四)和列位(低四) } /*函数功能描述:取键值,长按无效; unsigned char code Key_Value_Table[16]={0xff,0x00,0x01,0xff,0x02,0xff,0xff,0xff, 0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; 说明:计算因子,定义在函数外部。此数组在计算键值的中间过程起作用。比如右下方键按下(行列值为0x88),通过查找数组得到行对应的中间值0x03,列对应的中间值0x03。 */ unsigned char GetKey(void) { unsigned char key, temp; if (!bKeyUp_Flag) //判断标志,是0执行 /*按键程序执行一次后会将bKeyUp_Flag标志位清零,执行此段程序,长按键无效返回无效值,直至按键无效返回无效按键值,置"1"标志位。按键输入恢复有效。屏蔽这部分则长按键有效*/ { key=GetScanKey(); if (key==0xff) //没有按键,置标志位 bKeyUp_Flag=1; else //保持按键 return 0xff; //因为0xff大于15,故为无效键值,实现长按键无效 } key=GetScanKey(); if (key==0xff) //没有按键 return key; else //有按键有效 temp=key; //取键值 Delay_ms(20); //延时20ms 消抖 key=GetScanKey(); //键盘扫描 if(key!=temp) //判断两次键值是否相同,排除干扰信号影响 确认有效信号 { key=0xff; return key; }