Win10 IoT C#开发 6 - 4x4矩阵键盘扫描

原文:Win10 IoT C#开发 6 - 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

时间: 2024-08-30 12:38:35

Win10 IoT C#开发 6 - 4x4矩阵键盘扫描的相关文章

Win10 IoT C#开发 4 - UART 串口通信

原文:Win10 IoT C#开发 4 - UART 串口通信 Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,既可以开发设备UI与用户交互式操作,又可以控制GPIO等接口,使得原来嵌入式繁琐的开发变得简单.通过Remote Debug功能可以进行断点追踪调试.C#语言本身也有很好的用户基础,相信Win10 IoT 不远的将来会火起来.上个月帮朋友解决了关于Win10 IoT 的一些技术问题,当前也有很多公司在尝试采用Win10 IoT进行开发,可能也会遇到这些问题,

Win10 IoT C#开发 5 - 操作 IoT 设备内嵌 SQLite 数据库 CURD

原文:Win10 IoT C#开发 5 - 操作 IoT 设备内嵌 SQLite 数据库 CURD Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,与以往的Windows版本不同,是为物联网设备专门设计的,硬件也不仅仅限于x86架构,同时可以在ARM架构上运行. 前几章我们讲了 Raspberry 安装 Win10 IoT 系统及搭建开发环境.部署程序及操作 GPIO 和 UART 的方法,通过这些功能我们已经可以获得到传感器发送给我们的数据,但是如果数据不能及时推送

Win10 IoT C#开发 2 - 创建基于XAML的UI程序 及 应用的三种部署方法

原文:Win10 IoT C#开发 2 - 创建基于XAML的UI程序 及 应用的三种部署方法 Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,与以往的Windows版本不同,是为物联网设备专门设计的,硬件也不仅仅限于x86架构,同时可以在ARM架构上运行. 上一章我们讲了Raspberry安装Win10 IoT系统及搭建Visual Studio 2015开发环境的方法(http://www.cnblogs.com/cloudtech/p/5562120.html)

Win10 IoT C#开发 1 - Raspberry安装IoT系统及搭建开发环境

原文:Win10 IoT C#开发 1 - Raspberry安装IoT系统及搭建开发环境 Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,与以往的Windows版本不同,是为物联网设备专门设计的,硬件也不仅仅限于x86架构,同时可以在ARM架构上运行. The Raspberry Pi Foundation 是英国一个致力于科技推广的慈善组织,为广发爱好者和DIY科技迷开发了搭载ARM架构处理器的 mini 电脑 Raspberry Pi 并获得了成功.而微软最新发

51单片机矩阵键盘扫描问题

问题描述 51单片机矩阵键盘扫描问题 51单片机矩阵键盘动态扫描,我就看见例程编的程序都有个把io口值赋给一个temp,例如P3=temp然后再位与,然后再判断temp......我的问题就是为毛不直接判断P3口的值,多此一举干什么,直接用P3来判断按键按下不可以吗,大神门们求解 解决方案 51单片机矩阵键盘扫描 解决方案二: 键盘有抖动现象,需要判断是否是误按了,如果误按了一下,这个时间很短,所以显然不能用P口直接判断 解决方案三: 转换成汇编指令后就会有不同的. 解决方案四: 抖动呀,你按下

j矩阵键盘-verilog 实现不了矩阵键盘扫描啊,调了两天了,数码管还是乱码

问题描述 verilog 实现不了矩阵键盘扫描啊,调了两天了,数码管还是乱码 哪位大神有源代码,求帮忙发到我邮箱里379810405@qq.com verilog新手求解救!拜托拜托拜托拜托拜托拜托拜托拜托拜托拜托拜托拜托拜托拜托拜托拜托拜托拜托拜托拜托- 解决方案 http://wenku.baidu.com/link?url=Fy0dimklpMDms7dCqfYzKMO23xeCu5yxC90x78cKqv6f84cuxJrpSd_kxrGMgwS5JrgX7yW4wsdYrvqc3In9

Verilog HDL 4*4矩阵键盘扫描程序

硬件电路图如下: 1module key 2 3( 4 5 clk, //50MHZ 6 7 reset, 8 9 row, //行 10 11 col, //列 12 13 key_value //键值 14 15); 16 17input clk,reset; 18 19 input [3:0] row; 20 21 output [3:0] col; 22 23 output [3:0] key_value; 24 25 26 reg [3:0] col; 27 28 reg [3:0]

矩阵键盘控制ADC0832端口

问题描述 矩阵键盘控制ADC0832端口 各位前辈,我编了一个有由矩阵键盘控制ADC0832端口的电路,调不出来,怎么破?要求是在键盘输入一个数值(0~255),这个数值相应为ADC0832的端口输入得值,按Enter键结束.程序如下 #include "iom128v.h" #include "macros.h" #include "keym.h" #define uchar unsigned char ; #define uint unsig

小白关于51单片机矩阵键盘的疑惑

问题描述 小白关于51单片机矩阵键盘的疑惑 不理解为什么矩阵键盘一定要通过扫描的方式才能判断哪个键被按下,直接判断P3的值不可以吗 解决方案 因为单片机是单线程,除了中断以外,没有事件之类的东西.所以他要不断的重复检查键盘按键状态,也就是扫描动作