Chinaunix首页 | 论坛 | 博客
  • 博客访问: 226457
  • 博文数量: 52
  • 博客积分: 15
  • 博客等级: 民兵
  • 技术积分: 390
  • 用 户 组: 普通用户
  • 注册时间: 2012-09-06 09:31
文章分类

全部博文(52)

文章存档

2015年(1)

2014年(44)

2013年(7)

我的朋友

分类: 嵌入式

2014-05-30 11:09:44

晚上帮同学写了段代码  用单片机P1口扩展成4*4的键盘  按下按键点亮P0口的LED 
 
矩阵键盘的扩展不算复杂 主要是检测代码部分比较复杂 
 
IO扩展原理
 
矩阵键盘.png
    矩阵键盘又称行列键盘,它是用四条I/O线作为行线,四条I/O线作为列线组成的键盘。
在行线和列线的每个交叉点上设置一个按键。这样键盘上按键的个数就为4*4个。
这种行列式键盘结构能有效地提高单片机系统中I/O口的利用率。
 
检测原理
 
    当无按键闭合时,行线与列线之间开路。当有键闭合时,与闭合键相连的两条I/O口线之间短路。
 
    判断有无按键按下的方法:
  1. 粗扫描。行线输出低电平,列线输出高电平。读取Px口,若数据不等于 0x0F则有按键按下。
  2. 细扫描。行线逐行输出低电平,其他IO口输出高电平。读取Px口,若数据不等于输出的数值则有按键按下。并可以确定行数。同理列线逐行输出低电平,可以检测出列数。
  3. 根据行数和列数转换按键码 
 


代码如下:
01 #include
02 #define  uchar  unsigned char 
03  
04 #define  LED_ON(X)  P0 = ~(1<<(X))      //LED低电平点亮
05  
06 uchar KeyScan(void);
07  
08 void main(void)
09 {
10     uchar key;
11  
12     while(1){
13         key = KeyScan();
14  
15         if(key > 0)
16         {
17             key = key -1;
18             LED_ON(key);
19         }
20     }
21 }
22  
23 uchar KeyScan(void)                    
24 {
25  
26     uchar i,val,row,col,key;
27  
28     P1 = 0xF0;          //行线置0,列线置1
29  
30     if( P1 != 0x0F0 )   //按键按下
31     {
32         for(i=0;i<4;i++)   //行扫描
33         {
34             val = 0xFF&(~(1<
35             P1 = val;                  
36             if(P1 != val)
37             {
38                 row = i;    //确定行数
39                 break;      //终止循环
40             }
41         }
42  
43         for(i=0;i<4;i++)   //列扫描
44         {
45             val = 0xFF&(~(0x10<
46             P1 = val;                  
47             if(P1 != val)
48             {
49                 col = i+1;  //确定列数
50                 break;      //终止循环
51             }
52         }
53         key = row*4+col;
54         return key;
55     }else{
56         return 0;
57     } 
58 }
阅读(1896) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~