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
  • 相关阅读:
    使用Nginx搭建图片服务器(windows)
    Vue中使用百度地图——设置地图标注
    大型网站的 HTTPS 实践(三)——基于协议和配置的优化(转)
    大型网站的 HTTPS 实践(二)——HTTPS 对性能的影响(转)
    大型网站的 HTTPS 实践(一)—— HTTPS 协议和原理(转)
    TCP的状态兼谈Close_Wait和Time_Wait的状态
    SYN Flood攻击及防御方法 (转)
    LINUX下解决netstat查看TIME_WAIT状态过多问题(转)
    IP负载均衡技术
    ubuntu下安装Apache+PHP+Mysql
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/5724508.html
Copyright © 2011-2022 走看看