我们从2011年坚守至今,只想做存粹的技术论坛。  由于网站在外面,点击附件后要很长世间才弹出下载,请耐心等待,勿重复点击不要用Edge和IE浏览器下载,否则提示不安全下载不了

 找回密码
 立即注册
搜索
查看: 951|回复: 0

[技术文章] 矩阵程序

[复制链接]

该用户从未签到

139

主题

157

回帖

102

积分

二级逆天

积分
102

社区居民忠实会员社区劳模原创达人终身成就奖

QQ
发表于 2016-2-22 06:23:33 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区

您需要 登录 才可以下载或查看,没有账号?立即注册

×
在我们初学单片机的时候,每当遇到使用按键我们都会遇到按键的消抖与松手检测的问题。传统的方法一般都是使用ms延时的方法来处理,这样处理是最省事,不需要考虑太多的问题。但是这样做带来的结果是白白浪费了单片机的资源。延时函数会让单片机傻傻的等待,不能去处理其他更重要的事情,这对于实时性要求较高,或者还有更多任务要处理的系统来说,是万万不可接受的,基于这个问题,今天跟大家分享一个基于状态机的按键程序,它不会让单片机处于傻等的尴尬状态。这是转载于马朝老师的一本书籍。
一、传统按键消抖处理方法:
if(按键按下)
delay_ms(10);
if(按键确实按下)
{进行任务处理}

二、基于状态机的按键处理方法:
1、首先是 keyboard.c 文件
//***************************************************************
// File Name : keyboard.c
// Author    :
// Created   :
// Modified  :
// Revision  :
//***************************************************************
#ifndef _keyboard_c_
#define _keyboard_c_

#include
#include
#include "keyboard.h"

//***************************************************************
//端口定义
//PIN DESCRIPTION   
//P17 P16 P15 P14
// |   |   |   |
// \---\---\---\---P10        1  2  3  F1
// \---\---\---\---P11        4  5  6  F2
// \---\---\---\---P12        7  8  9  F3
// \---\---\---\---P13        *  0  #  F4
//***************************************************************
#define KeyPort P1

#define key_state_0 0      //定义按键状态(基于状态机)
#define key_state_1 1
#define key_state_2 2
#define key_state_3 3

#define NO_key        0
//***************************************************************
// Function    : KeyBoardScan
// Input       : none
// Output      : Key Number
//                 0~9、*、#:ASCII code
//                 F1、F2、F3、F4: (A、B、C、D) ASCII code
// Description : 4*4 matrix keyboard scanning Function
//               
//***************************************************************
uchar KeyBoardScan(void)
{   
    uchar key_temp;
    uchar key_num = NO_key;
    static uchar key_status = key_state_0;         //按键状态

    //线反转法扫描键盘
    KeyPort = 0x0f;
    key_temp = KeyPort;
    KeyPort = 0xf0;
    key_temp |= KeyPort;
    KeyPort = 0xff;

    switch(key_status)
    {
        case key_state_0:                                    //状态零为初始状态
            if(key_temp != 0xff)
                key_status = key_state_1;
            break;
        case key_state_1:                                   //状态一为按键按下状态
            if(key_temp == 0xff)
                key_status = key_state_0;             //若只是抖动,调回状态零
            else
            {
                key_status = key_state_2;            //若确实按下,调到状态二
                switch(key_temp)
                {
                    case 0x7e:        //0111 1110
                        key_num = "1";
                        break;
                    case 0xbe:        //1011 1110
                        key_num = "2";
                        break;
                    case 0xde:        //1101 1110
                        key_num = "3";
                        break;
                    case 0x7d:        //0111 1101
                        key_num = "4";
                        break;
                    case 0xbd:        //1011 1101
                        key_num = "5";
                        break;
                    case 0xdd:        //1101 1101
                        key_num = "6";
                        break;
                    case 0x7b:        //0111 1011
                        key_num = "7";
                        break;
                    case 0xbb:        //1011 1011
                        key_num = "8";
                        break;
                    case 0xdb:        //1101 1011
                        key_num = "9";
                        break;
                    case 0xb7:        //1011 0111
                        key_num = "0";
                        break;
                    case 0x77:        //0111 0111
                        key_num = "*";                  //*
                        break;
                    case 0xd7:        //1101 0111
                        key_num = "#";                  //#
                        break;
                    case 0xee:        //1110 1110
                        key_num = "A";                  //F1
                        break;
                    case 0xed:        //1110 1101
                        key_num = "B";                  //F2
                        break;
                    case 0xeb:        //1110 1011
                        key_num = "C";                  //F3
                        break;
                    case 0xe7:        //1110 0111
                        key_num = "D";                  //F4
                        break;
                }
            }
            break;
        case key_state_2:                                      //状态二表示确实有按键按下
            if(key_temp == 0xff)
                key_status = key_state_3;                //若检测到松手,调到状态三
            break;
        case key_state_3:
            if(key_temp == 0xff)
                key_status = key_state_0;               //若判断确实松手后,调回初始状态零
            else
                key_status = key_state_2;              //若只是抖动并不是真的松手,调回状态二
            break;
    }
    return key_num;
}

#endif
//===============================END OF FILE==================================//


2、其次是 keyboard.h 文件
// File Name : keyboard.h
// Author    :
// Created   :
// Modified  :
// Revision  :
//***************************************************************
#ifndef _keyboard_h_
#define _keyboard_h_

#include
#include "DataType.h"
//***************************************************************
//端口定义
//PIN DESCRIPTION   
//P17 P16 P15 P14
// |   |   |   |
// \---\---\---\---P10        1  2  3  F1
// \---\---\---\---P11        4  5  6  F2
// \---\---\---\---P12        7  8  9  F3
// \---\---\---\---P13        *  0  #  F4
//***************************************************************


//global functions declaration
extern uchar KeyBoardScan(void);

#endif
//===============================END OF FILE==================================//


使用方法:以上程序代码只要添加到工程的源代码便可以。要利用单片机的定时器资源,每10-15ms中断一次,在中断里面调用 KeyBoardScan() 函数。


好了,以上就是今天要分享的知识,希望可以帮到大家,也留给不爱记录的自己,常温故而知新。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

公告:服务器刚移机,
大家请不要下载东西。
会下载失败


Copyright ©2011-2024 NTpcb.com All Right Reserved.  Powered by Discuz! (NTpcb)

本站信息均由会员发表,不代表NTpcb立场,如侵犯了您的权利请发帖投诉

( 闽ICP备2024076463号-1 ) 论坛技术支持QQ群171867948 ,论坛问题,充值问题请联系QQ1308068381

平平安安
TOP
快速回复 返回顶部 返回列表