矩阵键盘扫描程序实例

发布者:bianzitong521最新更新时间:2017-11-14 来源: eefocus关键字:矩阵键盘  扫描程序 手机看文章 扫描二维码
随时随地手机看文章

使用芯片STM8S003

所用端口:PD2~PD6, PA1~PA3

其中,PD3~PD6为输出,PA1~PA3 / PD2为输入(默认上拉)

/*
    PortCom BIT7 BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0
                  PD6  PD5  PD4  PD3  PD2  PA3  PA2  PA1
  */

程序如下:


  1. /*    添加包含芯片的头文件    */  

  2. #include  

  3.   

  4.   

  5.   

  6. volatile unsigned char CF[4];     //按键触发标志(表示4列,每一列同一行的  

  7.                                   //值是一样的但列标不一样来区分不同列的键)  

  8. volatile unsigned char Cont[4];  

  9. unsigned char KeyVal;     //键值  

  10. //unsigned char KeyOut[4] = {0xef,0xdf,0xbf,0x7f};    //4X4按输出端控制  

  11. //unsigned char KeyOut[4] = {0x7f,0xbf,0xdf,0xef};  

  12. unsigned char KeyOut[4] = {0x3f,0x5f,0x6f,0x77};      //两个端口组合4x4端口输出控制  

  13. unsigned char PortCom;    //两个端口组合的端口  

  14. unsigned char cIn0,cIn1,cIn2,cIn3;  

  15.   

  16.   

  17. /******************************************************************************* 

  18. **函数名称:void delay(unsigned int ms)     Name: void delay(unsigned int ms) 

  19. **功能描述:大概延时 

  20. **入口参数:unsigned int ms   输入大概延时数值 

  21. **输出:无 

  22. *******************************************************************************/  

  23. void delay(unsigned int ms)  

  24. {  

  25.   unsigned int x , y;  

  26.   for(x = ms; x > 0; x--)  

  27.     for(y = 1000 ; y > 0 ; y--);  

  28. }  

  29.   

  30. /* 

  31. **描述:新型4X4按键扫描程序 放在1ms-10ms中断内使用(十分稳定不需要再写消抖程序) 

  32. **备注:按键弹起时 keyVal = 0 单键按下 keyVal 有16个值,你自己程序可以针对不同值 

  33. **进行不同程序操作 keyVal单键值分别为  

  34. **0x01,0x02,0x04,0x08, 

  35. **0x11,0x12,0x14,0x18, 

  36. **0x21,0x22,0x24,0x28, 

  37. **0x31,0x32,0x34,0x38, 

  38. */   

  39. void Key_Head()   

  40. {  

  41.   unsigned char ReadData[4];  

  42.   static unsigned char i;  

  43.   /* 

  44.     PortCom BIT7 BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0 

  45.             PD6  PD5  PD4  PD3  PD2  PA3  PA2  PA1 

  46.   */  

  47.   cIn0 = 0;  

  48.   cIn1 = 0;  

  49.   cIn2 = 0;  

  50.   cIn3 = 0;  

  51.   if(++i>=4)i=0;  

  52.   

  53. //  PortCom = KeyOut[i]|0x0f;                     //忽略低4位  

  54.   //输出扫描  

  55.   PD_ODR = KeyOut[i];  

  56.   //输入侦测  

  57.   cIn0 = PA_IDR_bit.IDR1;  

  58.   cIn1 = PA_IDR_bit.IDR2;  

  59.   cIn2 = PA_IDR_bit.IDR3;  

  60.   cIn3 = PD_IDR_bit.IDR2;  

  61.   PortCom = (cIn3<<3) | (cIn2<<2) | (cIn1<<1) | cIn0;   

  62.     

  63.   ReadData[i] = (PortCom|0xf0)^0xff;            //忽略高4位 取反   

  64.   CF[i] = ReadData[i] & (ReadData[i] ^ Cont[i]);   

  65.   Cont[i] = ReadData[i];   

  66.   //输出键值  

  67.   switch(CF[i])//第i列  

  68.   {  

  69.     case 0x08: KeyVal = ((i<<4)+8);break;  

  70.     case 0x04: KeyVal = ((i<<4)+4);break;  

  71.     case 0x02: KeyVal = ((i<<4)+2);break;  

  72.     case 0x01: KeyVal = ((i<<4)+1);break;  

  73.     default:KeyVal = 0;break;  

  74.   }   

  75.       

  76.   delay(30);  

  77. }  

  78.   

  79.   

  80. /******************************************************************************* 

  81. **函数名称:void ALL_LED_Init()    Name: void ALL_LED_Init() 

  82. **功能描述:初始化LED灯的IO口设为输出 

  83. **入口参数:无 

  84. **输出:无 

  85. *******************************************************************************/  

  86. void ALL_LED_Init()  

  87. {  

  88.   //LED1 Init  

  89. //  PD_DDR_bit.DDR2 = 1;    //设置端口PD->2的输入输出方向寄存器为输出方向  

  90. //  PD_CR1_bit.C12 = 1;     //设置PD2为推挽输出  

  91. //  PD_CR2_bit.C22 = 1;     //设置PD2的输出最大速度为10MHZ  

  92.     

  93.   //LED2 Init  

  94.   PC_DDR_bit.DDR7 = 1;    //设置端口PC->7的输入输出方向寄存器为输出方向  

  95.   PC_CR1_bit.C17 = 1;     //设置PC7为推挽输出  

  96.   PC_CR2_bit.C27 = 1;     //设置PC7的输出最大速度为10MHZ  

  97.     

  98.   //LED3 Init  

  99.   PC_DDR_bit.DDR6 = 1;    //设置端口PC->6的输入输出方向寄存器为输出方向  

  100.   PC_CR1_bit.C16 = 1;     //设置PC6为推挽输出  

  101.   PC_CR2_bit.C26 = 1;     //设置PC6的输出最大速度为10MHZ  

  102.     

  103.   //LED4 Init  

  104.   PC_DDR_bit.DDR3 = 1;    //设置端口PC->3的输入输出方向寄存器为输出方向  

  105.   PC_CR1_bit.C13 = 1;     //设置PC3为推挽输出  

  106.   PC_CR2_bit.C23 = 1;     //设置PC3的输出最大速度为10MHZ  

  107. }  

  108.   

  109.   

  110. /******************************************************************************* 

  111. **函数名称:ALLKeyInit() 

  112. **功能描述:配置Key1 , Key2 , Key3输入按键 

  113. **入口参数:无 

  114. **输出:无 

  115. *******************************************************************************/  

  116. void ALLKeyInit()  

  117. {  

  118.   //PA1_Init  

  119.   PA_DDR_bit.DDR1 = 0;      //GPA->PIN3 设置为输入模式  

  120.   PA_CR1_bit.C11 = 1;       //GPA->PIN3 带上拉电阻输入  

  121.   PA_CR2_bit.C21 = 0;       //GPA->PIN3  禁止外部中断  

  122.     

  123.   //PA2_Init  

  124.   PA_DDR_bit.DDR2 = 0;      //GPA->PIN3 设置为输入模式  

  125.   PA_CR1_bit.C12 = 1;       //GPA->PIN3 带上拉电阻输入  

  126.   PA_CR2_bit.C22 = 0;       //GPA->PIN3  禁止外部中断  

  127.     

  128.   //PA3_Init  

  129.   PA_DDR_bit.DDR3 = 0;      //GPA->PIN3 设置为输入模式  

  130.   PA_CR1_bit.C13 = 1;       //GPA->PIN3 带上拉电阻输入  

  131.   PA_CR2_bit.C23 = 0;       //GPA->PIN3  禁止外部中断  

  132.     

  133.   //PD2_Init  

  134.   PD_DDR_bit.DDR2 = 0;      //GPD->PIN3 设置为输入模式  

  135.   PD_CR1_bit.C12 = 1;       //GPD->PIN3 带上拉电阻输入  

  136.   PD_CR2_bit.C22 = 0;       //GPD->PIN3  禁止外部中断  

  137.     

  138.   //PD3_Init  

  139.   PD_DDR_bit.DDR3 = 1;      //GPD->PIN3 设置为输入模式  

  140.   PD_CR1_bit.C13 = 1;       //GPD->PIN3 带上拉电阻输入  

  141.   PD_CR2_bit.C23 = 1;       //GPD->PIN3  禁止外部中断  

  142.     

  143.   //PD4_Init  

  144.   PD_DDR_bit.DDR4 = 1;      //GPD->PIN3 设置为输入模式  

  145.   PD_CR1_bit.C14 = 1;       //GPD->PIN3 带上拉电阻输入  

  146.   PD_CR2_bit.C24 = 1;       //GPD->PIN3  禁止外部中断  

  147.     

  148.   //PD5_Init  

  149.   PD_DDR_bit.DDR5 = 1;      //GPC->PIN5 设置为输入模式  

  150.   PD_CR1_bit.C15 = 1;       //GPC->PIN5 带上拉电阻输入  

  151.   PD_CR2_bit.C25 = 1;       //GPC->PIN5  禁止外部中断  

  152.     

  153.   //PD6_Init  

  154.   PD_DDR_bit.DDR6 = 1;      //GPC->PIN5 设置为输入模式  

  155.   PD_CR1_bit.C16 = 1;       //GPC->PIN5 带上拉电阻输入  

  156.   PD_CR2_bit.C26 = 1;       //GPC->PIN5  禁止外部中断  

  157. }  

  158.   

  159. int main(void)  

  160. {  

  161.   CLK_CKDIVR = 0x00;              //内部时钟为1分频  

  162.   ALL_LED_Init();                 //调用LED1初始化函数  

  163.   ALLKeyInit();                   //调用按钮初始化函数  

  164.   

  165.   while(1)  

  166.   {    

  167.     Key_Head();  

  168.       

  169.     switch(KeyVal)  

  170.     {  

  171.     case 0x01:  

  172.       {  

  173.         PC_ODR ^= 0x80;                //异或取反LED2使其亮灭  

  174.         break;  

  175.       }  

  176.     case 0x02:  

  177.       {  

  178.         PC_ODR ^= 0x40;                //异或取反LED3使其亮灭  

  179.         break;  

  180.       }  

  181.     case 0x04:  

  182.       {  

  183.         PC_ODR ^= 0x08;                //异或取反LED4使其亮灭  

  184.         break;  

  185.       }  

  186.     case 0x08:  

  187.       {  

  188.         PC_ODR ^= 0x80;                //异或取反LED2使其亮灭  

  189.         PC_ODR ^= 0x40;                //异或取反LED3使其亮灭  

  190.         break;  

  191.       }  

  192.     case 0x11:  

  193.       {  

  194.         PC_ODR ^= 0x80;                //异或取反LED2使其亮灭  

  195.         break;  

  196.       }  

  197.     case 0x12:  

  198.       {  

  199.         PC_ODR ^= 0x40;                //异或取反LED3使其亮灭  

  200.         break;  

  201.       }  

  202.     case 0x14:  

  203.       {  

  204.         PC_ODR ^= 0x08;                //异或取反LED4使其亮灭  

  205.         break;  

  206.       }  

  207.     case 0x18:  

  208.       {  

  209.         PC_ODR ^= 0x80;                //异或取反LED2使其亮灭  

  210.         PC_ODR ^= 0x40;                //异或取反LED3使其亮灭  

  211.         break;  

  212.       }  

  213.     case 0x21:  

  214.       {  

  215.         PC_ODR ^= 0x80;                //异或取反LED2使其亮灭  

  216.         break;  

  217.       }  

  218.     case 0x22:  

  219.       {  

  220.         PC_ODR ^= 0x40;                //异或取反LED3使其亮灭  

  221.         break;  

  222.       }  

  223.     case 0x24:  

  224.       {  

  225.         PC_ODR ^= 0x08;                //异或取反LED4使其亮灭  

  226.         break;  

  227.       }  

  228.     case 0x28:  

  229.       {  

  230.         PC_ODR ^= 0x80;                //异或取反LED2使其亮灭  

  231.         PC_ODR ^= 0x40;                //异或取反LED3使其亮灭  

  232.         break;  

  233.       }  

  234.     case 0x31:  

  235.       {  

  236.         PC_ODR ^= 0x80;                //异或取反LED2使其亮灭  

  237.         break;  

  238.       }  

  239.     case 0x32:  

  240.       {  

  241.         PC_ODR ^= 0x40;                //异或取反LED3使其亮灭  

  242.         break;  

  243.       }  

  244.     case 0x34:  

  245.       {  

  246.         PC_ODR ^= 0x08;                //异或取反LED4使其亮灭  

  247.         break;  

  248.       }  

  249.     case 0x38:  

  250.       {  

  251.         PC_ODR ^= 0x80;                //异或取反LED2使其亮灭  

  252.         PC_ODR ^= 0x40;                //异或取反LED3使其亮灭  

  253.         break;  

  254.       }  

  255.     default:  

  256.       {  

  257.         KeyVal = 0;  

  258.         break;  

  259.       }  

  260.     }  

  261.   }  

  262. }  


关键字:矩阵键盘  扫描程序 引用地址:矩阵键盘扫描程序实例

上一篇:STM8学习经验
下一篇:STM8S003F3通过PWM波实现三基色呼吸灯

推荐阅读最新更新时间:2024-03-16 15:45

基于ARM的矩阵键盘设计及其linux驱动实现
1.引言 ARM微处理器已广泛应用于工业控制、消费类电子产品、通信系统等领域。矩阵键盘是一种常用的键盘形式,它将按键设计成M行N列,这样共需M+N根信号线,却可驱动M×N个按键,大大节约了I/O资源。本文介绍了一种利用TQ2440开发板的GPIO口扩展5×4矩阵键盘的方法,并将所有按键重新布局成手持终端的键盘形式,方便操作。 2.硬件设计 本设计扩展5行4列的矩阵键盘,如图1所示。其中行线ROW1-ROW5连接S3C2440的中断引脚EINT8,EINT9,EINT11,EINT13,EINT14 .这些中断引脚本身连有10kΩ的上拉电阻,把中断引脚电平拉高,确保按键空闲时不会触发中断。列线COL1-COL4连接S3C2440的普
[电源管理]
基于ARM的<font color='red'>矩阵键盘</font>设计及其linux驱动实现
ARM开发(4)基于STM32的矩阵键盘按键控制TM1629A LED显示
一 矩阵键盘按键控制TM1629ALED显示原理: 1.1 本实验实现矩阵键盘按键控制TM1629ALED显示 1.2 实验思路:共阴极数码管,掌握数码管段选位选原理 熟悉TM1629A芯片手册 1.3 开发环境 : MDK5 库函数版本开发 JLINK仿真 二 实验步骤: 2.1 keyled.h代码: #ifndef __KEYLED_H #define __KEYLED_H #include sys.h #define SEG_NUM 16 //段选,2个8段 #define GRID_NUM 8 //位选 #define WRITE_DATA_MODE_A
[单片机]
AVR M16 实验之五 矩阵键盘
/********************************************************************** * 文件名称: main.c * 程序作者: kidcao1987 * 程序版本: V1.0 * 功能描述: 按动16个按键,在数码管上显示 0~e 这16个16进制的数字。 * 编译器:WinAVR-20090313 * 芯片:ATmega16,外部11.0592MHZ晶振 * 技术支持:http://bbs.cepark.com **********************************************************************/ #include
[单片机]
MSP430 G2553 矩阵键盘 无源蜂鸣器 电子琴
伪代码: while (1) { key = get_key(); //获取按键 if (key) { //设置蜂鸣器鸣叫频率 可以定时器中断做 可以PWM做 while (get_key()) ; //等待按键松开 //关闭蜂鸣器 } }
[单片机]
PIC单片机矩阵键盘检测原理及实现
#include pic.h #define uchar unsigned char #define uint unsigned int __CONFIG(0x3B31); const uchar table ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; uchar key_num; void delay(uint x); void init(); void scan(); void didi(uchar num); void disp(); void main() { init();
[单片机]
51单片机矩阵键盘的软硬件设计
  下面以51单片机综合学习系统为硬件平台,介绍矩阵式键盘的编程方法。具体功能为:按下其键后,在一位数码管上显示出键值。0到16个键分别对应显示0到F。   1、硬件原理      本实验可以直接在配套开发板上完成,电路图如下图所示。   根据电路原理图,键盘扫描方法是:行线P1O~P13为输出线,列线P14~P17为输入线。一开始单片机将行线(P1O-P13)全部输出低电平,此时读入列线数据,若列线全为高电平说明没有键接下,若有列线为低电平则调用延时程序来去除按键抖动。延时后再读入列线看是否有低电平,如果列线数据还是有低电平,说明确实有键接下,接下来便是确定键值。下面以第二行的S5键为例,看接下S5后我们应该怎么得到这个键值。当
[单片机]
51单片机<font color='red'>矩阵键盘</font>的软硬件设计
我的矩阵键盘使用笔记——基于msp430g2553
Created on: 2012-9-6 Author: zhang bin 学习笔记 for msp430g2553 redesigned by zhang bin 2012-09-06 versions :12_09_01 All Rights Reserved 这里主要记录我的使用矩阵键盘输入数据的方法。在系统的设计中,输入数据是经常遇到的,而矩阵键盘是最常用的输入设备。如果矩阵键盘的扫描没有了问题,那么怎样用矩阵键盘输入数据呢,例如我要输入253.45这个数,该怎么实现呢。 下面是我用的两个实现方法: 一、是借用一个诡异的值,也就是键盘扫描时不可能扫到的值,这个数与键盘完全无关
[单片机]
AVR单片机入门系列(17)AVR IO输入之矩阵按键扫描程序
系统功能 使用AVR扫描4*4矩阵按键,一旦扫描到按键被按,做出被按的按键号指示。 硬件设计 关于AVR的I/O结构及相关介绍详见Datasheet,这里仅对作部分简单介绍,下面是AVR的I/O引脚配置表: AVR I/O 口引脚配置表 DDRXn PORTXn PUD I/O 方式 内部上拉电阻 引脚状态说明 0 0 X 输入 无效 三态(高阻) 0 1 0 输入 有效 外部
[单片机]
AVR单片机入门系列(17)AVR IO输入之矩阵按键<font color='red'>扫描</font><font color='red'>程序</font>
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
热门活动
换一批
更多
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

更多每日新闻
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved