打印

一段经典的按键程序 的 疑问(匠人百宝箱也有这个代码,但

[复制链接]
2964|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
我是土匪|  楼主 | 2009-3-11 11:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
程序是<嵌入式系统结构>中通用可移植的矩阵键盘程序,代码如下:
/*
*********************************************************************************************************
*                                   Embedded Systems Building Blocks
*                                Complete and Ready-to-Use Modules in C
*
*                                         Matrix Keyboard Driver
*
*                            (c) Copyright 1999, Jean J. Labrosse, Weston, FL
*                                           All Rights Reserved
*
* Filename   : KEY.H
* Programmer : Jean J. Labrosse
*********************************************************************************************************
*                                          USER DEFINED CONSTANTS
*
* Note: These #defines would normally reside in your application specific code.
*********************************************************************************************************
*/

#ifndef  CFG_H
#define  KEY_BUF_SIZE               10      /* Size of the KEYBOARD buffer                             */

#define  KEY_PORT_ROW           0x0312      /* The port address of the keyboard matrix ROWs            */
#define  KEY_PORT_COL           0x0311      /* The port address of the keyboard matrix COLUMNs         */
#define  KEY_PORT_CW            0x0313      /* The port address of the I/O ports control word          */

#define  KEY_MAX_ROWS                4      /* The maximum number of rows    on the keyboard           */
#define  KEY_MAX_COLS                6      /* The maximum number of columns on the keyboard           */

#define  KEY_RPT_DLY                 2      /* Number of scan times before auto repeat executes again  */
#define  KEY_RPT_START_DLY          10      /* Number of scan times before auto repeat function engages*/

#define  KEY_SCAN_TASK_DLY          50      /* Number of milliseconds between keyboard scans           */
#define  KEY_SCAN_TASK_PRIO         50      /* Set priority of keyboard scan task                      */
#define  KEY_SCAN_TASK_STK_SIZE   1024      /* Size of keyboard scan task stack                        */

#define  KEY_SHIFT1_MSK           0x80      /* The SHIFT1 key is on bit B7 of the column input port    */
                                            /*     (A 0x00 indicates that a SHIFT1 key is not present) */
#define  KEY_SHIFT1_OFFSET          24      /* The scan code offset to add when SHIFT1 is pressed      */

#define  KEY_SHIFT2_MSK           0x40      /* The SHIFT2 key is on bit B6 of the column input port    */
                                            /*     (A 0x00 indicates that an SHIFT2 key is not present)*/
#define  KEY_SHIFT2_OFFSET          48      /* The scan code offset to add when SHIFT2 is pressed      */

#define  KEY_SHIFT3_MSK           0x00      /* The SHIFT3 key is on bit B5 of the column input port    */
                                            /*     (A 0x00 indicates that a SHIFT3 key is not present) */
#define  KEY_SHIFT3_OFFSET           0      /* The scan code offset to add when SHIFT3 is pressed      */
#endif


#define  KEY_ALL_ROWS             0xFF      /* Select all rows (i.e. all rows LOW)                     */

/*
*********************************************************************************************************
*                                           FUNCTION PROTOTYPES
*********************************************************************************************************
*/

void    KeyFlush(void);                /* Flush the keyboard buffer                                    */
INT8U   KeyGetKey(INT16U to);          /* Get a key scan code from driver if one is present, -1 else   */
INT32U  KeyGetKeyDownTime(void);       /* Get how long key has been pressed (in milliseconds)          */
BOOLEAN KeyHit(void);                  /* See if a key has been pressed (TRUE if so, FALSE if not)     */
void    KeyInit(void);                 /* Initialize the keyboard handler                              */


void    KeyInitPort(void);             /* Initialize I/O ports                                         */
INT8U   KeyGetCol(void);               /* Read COLUMNs                                                 */
void    KeySelRow(INT8U row);          /* Select a ROW                                                 */

相关帖子

沙发
我是土匪|  楼主 | 2009-3-11 11:54 | 只看该作者

问题

INT8U  KeyGetCol (void)
{
    return (~inp(KEY_PORT_COL));                 /* Complement columns (ones indicate key is pressed)  */
}


这个函数的目的是:读取和返回列的输入端口的补码(1表示一个健被按下)

那么根据我的硬件结构这个函数应该返回的是一个端口数值,表示某端口是否读到按键,请问这个函数返回数值应该怎么即体现端口号也体现状态,简言之这个函数应该怎么改写。

我的COL一共4个, 8 * 4的

使用特权

评论回复
板凳
一级菜鸟| | 2009-3-11 11:59 | 只看该作者

端口号

在这里体现
#define  KEY_PORT_COL           0x0311    
 /* The port address of the keyboard matrix COLUMNs         */

按键状态由其返回的值体现

使用特权

评论回复
地板
我是土匪|  楼主 | 2009-3-11 12:10 | 只看该作者

楼上

2点疑问:
1、#define  KEY_PORT_COL           0x0311  后面这个常量代表什么,我  可  以随便定义成其他量吗?

2、我返回值具体可以是多少,怎么和端口对应?如返回0/1/0X08,那些是合法的,怎么让返回值对应我的端口及其状态?

使用特权

评论回复
5
一级菜鸟| | 2009-3-11 12:11 | 只看该作者

使用特权

评论回复
6
我是土匪|  楼主 | 2009-3-11 12:29 | 只看该作者

inp

inp不是标准库,想改写

、#define  KEY_PORT_COL           0x0311  是端口地址

但是我的键盘列不是一个端口,
INT8U  KeyGetCol (void)
{
    return (~inp(KEY_PORT_COL));                 /* Complement columns (ones indicate key is pressed)  */
}

这个函数感觉始终返回同一个数值。

使用特权

评论回复
7
一级菜鸟| | 2009-3-11 12:31 | 只看该作者

不是一个端口就得扫两次

使用特权

评论回复
8
huangqi412| | 2009-3-11 13:06 | 只看该作者

菜鸟哥最近又开始冒泡了...

使用特权

评论回复
9
我是土匪|  楼主 | 2009-3-11 13:16 | 只看该作者

高手

INT8U  KeyGetCol (void)
{
    //return (~inp(KEY_PORT_COL));                 /* Complement columns (ones indicate key is pressed)  */
}
是不是这样理解:
比如我P0.3 P 0.9 P0.10 P0.16为输入端口,如果哪个端口被按下,改函数返回值对应位就是1,否则为0 

使用特权

评论回复
10
一级菜鸟| | 2009-3-11 13:23 | 只看该作者

依据硬件连接方式,可能是0,可能是1,贴图出来再说

另外,别叫菜鸟高手,你才是高手呢,你们全家都高手

使用特权

评论回复
11
一级菜鸟| | 2009-3-11 13:25 | 只看该作者

huangqi412起来得挺早的嘛,嘿嘿

使用特权

评论回复
12
我是土匪|  楼主 | 2009-3-11 13:37 | 只看该作者

我不是单片机世家

图如下:
8行分别输出0,4列循环读端口

使用特权

评论回复
13
我是土匪|  楼主 | 2009-3-11 13:45 | 只看该作者

被按下对应端口对应位就0

所以我只要返回端口状态:
INT8U  KeyGetCol (void)
{
    return IO0PIN;//return (~inp(KEY_PORT_COL));
}
YES OR NO?

关键是我函数返回的数值是否和使用它的函数是否在一致

使用特权

评论回复
14
我是土匪|  楼主 | 2009-3-11 16:17 | 只看该作者

如果不考虑同时按下

应该这样:如果第一列就是返回0X01,第二列0x02,第3列0x04,,第4列0x08

使用特权

评论回复
15
渤海三叠浪| | 2009-3-11 18:50 | 只看该作者

这程序写得 !!!牛啊!!

使用特权

评论回复
16
我是土匪|  楼主 | 2009-3-11 19:57 | 只看该作者

郁闷了我一天

终于OK了,改天抽空讲下菜鸟心得。

使用特权

评论回复
17
zjw5000| | 2009-7-14 22:36 | 只看该作者

mark

mark,抽空看

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

226

主题

1761

帖子

30

粉丝