zoukankan      html  css  js  c++  java
  • 4x4矩阵键盘扫描

    4x4矩阵键盘扫描

    Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,与以往的Windows版本不同,是为物联网设备专门设计的,硬件也不仅仅限于x86架构,同时可以在ARM架构上运行。

    上一章我们讲了 Win10 IoT 如何对本地 IoT 设备内嵌 SQLite 数据库进行 CURD 操作 ,这章我们来学习如何使用 GPIO Pin 扫描4x4矩阵键盘按键状态。如果对安装部署过程还不熟悉可以参考前几篇文章,Raspberry安装 IoT系统及搭建开发环境(http://www.cnblogs.com/cloudtech/p/5562120.html),创建 IoT应用及三种部署方法(http://www.cnblogs.com/cloudtech/p/5637983.html)。

    准备工作:

    刷好Win 10 IoT Core系统的 Raspberry Pi 2

    部署Visual Studio 2015开发环境的PC

    4x4矩阵键盘

    GPIO扩展板

    IDC排线

    杜邦线

    面包板

    实验目标: 在4x4矩阵键盘上按下按键后,在程序界面上显示对应的按键字符。

    1.安装元器件

    首先将 GPIO扩展板 安装到面包板上,再通过 IDC排线 与 Raspberry Pi 2 的 GPIO 接口连接。

    4x4矩阵键盘电路图

    行线R0-3分别与Pin5、Pin6、Pin13、Pin19 引脚连接。

    列线C0-3分别与Pin12、Pin16、Pin20、Pin21 引脚连接。

    2.编写代码

    打开 VS 2015 点击 New Project 在Visual C# -> Windows -> Universal 中找到 Blank App (Universal Windows) 项目模板,选中模板输入项目名称后点击OK按钮创建项目。

     项目创建完成后,在Reference Manager Extensions中 勾选Windows IoT Extensions for the UWP 添加 IoT扩展。

    程序启动后获取默认GPIO控制器,对引脚进行初始化。

    行线R0-3设置为输入端,20ms延时消抖,检测到高电平认为有按键按下,对列线逐一扫描确认。

    列线C0-3设置为输出端高电平。

    键码映射表如下

    行线R0-3对应键码低4位。

    列线C0-3对应键码高4位。

    这里为了简便把MainPage.cs作为ViewModel,来实现INotifyPropertyChanged接口完成一个简易的MVVM框架。

    代码如下:

    复制代码
    namespace CloudTechIot6
    {
        //http://www.cnblogs.com/cloudtech
        //cloudtechesx@gmail.com
        public sealed partial class MainPage : Page, INotifyPropertyChanged
        {
            #region Fileds
            //GPIO控制器
            //Gpio Controller
            private GpioController _gpioController;
            //引脚集合
            //Pin Collection
            private GpioPin[] _pins;
            //键码表
            //KeyCode Table
            private Dictionary<byte, char> _keyMaps;
            private bool _initCompleted;
    
            #endregion
    
            #region Events
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            #endregion
    
            #region Properties
    
            private string _msg;
            //键码
            //Key Code
            public string Msg
            {
                get
                {
                    return _msg;
                }
    
                set
                {
                    _msg = value;
                    OnPropertyChanged(this, new PropertyChangedEventArgs("Msg"));
                }
            }
    
            public string FreshTime
            {
                get
                {
                    return _freshTime;
                }
    
                set
                {
                    _freshTime = value;
                    OnPropertyChanged(this, new PropertyChangedEventArgs("FreshTime"));
                }
            }
    
            private string _freshTime;
    
            #endregion
    
            #region Constructor
    
            public MainPage()
            {
                this.InitializeComponent();
                this.DataContext = this;
                _initCompleted = false;
                _keyMaps = new Dictionary<byte, char>();
                InitKeyMaps();
                //获取默认GPIO控制器
                //Get Default Gpio Controller
                _gpioController = GpioController.GetDefault();
                if (null == _gpioController)
                {
                    throw new Exception("GpioController init failed");
                }
                //初始化 GPIO Pin
                //Init GPIO 引脚
                _pins = new GpioPin[] { _gpioController.OpenPin(5), _gpioController.OpenPin(6), _gpioController.OpenPin(13), _gpioController.OpenPin(19), _gpioController.OpenPin(12), _gpioController.OpenPin(16), _gpioController.OpenPin(20), _gpioController.OpenPin(21) };
    
                for (int i = 0; i < 8; i++)
                {
                    //设置为输入并监听引脚电平变化
                    //set input mode and listen pin level change
                    if (i < 4)
                    {
                        _pins[i].SetDriveMode(GpioPinDriveMode.Input);
                        _pins[i].DebounceTimeout = TimeSpan.FromMilliseconds(20);
                        _pins[i].ValueChanged += (GpioPin sender, GpioPinValueChangedEventArgs args) =>
                        {
                            lock (this)
                                //高电平
                                //high level 
                                if (_initCompleted && GpioPinEdge.RisingEdge == args.Edge)
                                    //扫描列线
                                    //scan column pin
                                    for (int j = 4; j < 8; j++)
                                    {
                                        _pins[j].Write(GpioPinValue.Low);
                                        if (GpioPinValue.Low == sender.Read())
                                        {
                                            //获取生成键码并输出到界面
                                            //generate keycode and print on UI
                                            Msg = _keyMaps[(byte)((1 << ToIndex(sender)) | (1 << j))].ToString();
                                            FreshTime = DateTime.Now.ToString("HH:mm:ss");
                                            _pins[j].Write(GpioPinValue.High);
                                            break;
                                        }
                                        _pins[j].Write(GpioPinValue.High);
                                    }
                        };
                    }
                    //设置为输出高电平
                    //set output high level
                    else
                    {
                        _pins[i].SetDriveMode(GpioPinDriveMode.Output);
                        _pins[i].Write(GpioPinValue.High);
                    }
                }
                Msg = "Push Button";
                //初始化完成
                //initialize completed
                _initCompleted = true;
            }
    
            #endregion
    
            #region Methods
    
            //MVVM依赖属性通知事件
            private async void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
            {
                await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { PropertyChanged?.Invoke(sender, e); });
            }
    
            //初始化键码表
            //initialize keycode
            private void InitKeyMaps()
            {
                _keyMaps.Add(0x88, '1');
                _keyMaps.Add(0x84, '2');
                _keyMaps.Add(0x82, '3');
                _keyMaps.Add(0x81, 'A');
                _keyMaps.Add(0x48, '4');
                _keyMaps.Add(0x44, '5');
                _keyMaps.Add(0x42, '6');
                _keyMaps.Add(0x41, 'B');
                _keyMaps.Add(0x28, '7');
                _keyMaps.Add(0x24, '8');
                _keyMaps.Add(0x22, '9');
                _keyMaps.Add(0x21, 'C');
                _keyMaps.Add(0x18, '*');
                _keyMaps.Add(0x14, '0');
                _keyMaps.Add(0x12, '#');
                _keyMaps.Add(0x11, 'D');
            }
    
            //获取行线索引
            //get row pin index
            private int ToIndex(GpioPin pin)
            {
                int result = -1;
                for (int i = 0; i < _pins.Length; i++)
                {
                    if (pin.Equals(_pins[i]))
                    {
                        result = i;
                        break;
                    }
                }
                if (0 > result)
                {
                    throw new Exception("Unknow Pin Index");
                }
                else
                {
                    return result;
                }
            }
    
            #endregion
        }
    }
    复制代码

    3.调试代码

    为Raspberry连接电源及网线,连接HDMI显示器。接通电源待系统启动完成后显示器上会显示当前IoT设备的IP地址。

    在 Visual Studio 2015 的工具栏中选择 Remote Machine 进行调试,IP地址输入设备对应地址。点击运行后会自动部署到设备上。

    这里要注意平台要选择ARM。

    程序启动后按下4x4矩阵键盘上的按键后,程序界面上显示对应的按键字符,与预期结果一致。

    到这里C#操作 Win10 IoT设备的4x4矩阵键盘过程就完成了,如果对代码有优化的建议,欢迎留言或发邮件给我(cloudtechesx@gmail.com)。也可以扫描下面的二维码加我的微信号查看以前的文章。

    完整项目源码 GitHub https://github.com/CloudTechx/CloudTechIot 的 CloudTechIot6 目录下。

    Win10 IoT C#开发 1 - Raspberry安装IoT系统及搭建开发环境 http://www.cnblogs.com/cloudtech/p/5562120.html
    Win10 IoT C#开发 2 - 创建基于XAML的UI程序 及 应用的三种部署方法 http://www.cnblogs.com/cloudtech/p/5637983.html
    Win10 IoT C#开发 3 - GPIO Pin 控制发光二极管 http://www.cnblogs.com/cloudtech/p/5617902.html
    Win10 IoT C#开发 4 - UART 串口通信 http://www.cnblogs.com/cloudtech/p/5518306.html
    Win10 IoT C#开发 5 - 操作 IoT 设备内嵌 SQLite 数据库 CURD http://www.cnblogs.com/cloudtech/p/5657123.html

     
    分类: Win10 IoT
  • 相关阅读:
    链表--判断一个链表是否为回文结构
    矩阵--“之”字形打印矩阵
    二叉树——平衡二叉树,二叉搜索树,完全二叉树
    链表--反转单向和双向链表
    codeforces 490C. Hacking Cypher 解题报告
    codeforces 490B.Queue 解题报告
    BestCoder19 1001.Alexandra and Prime Numbers(hdu 5108) 解题报告
    codeforces 488A. Giga Tower 解题报告
    codeforces 489C.Given Length and Sum of Digits... 解题报告
    codeforces 489B. BerSU Ball 解题报告
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/5724508.html
Copyright © 2011-2022 走看看