单片机练习 - 模拟电话键盘

因为课程有单片机, 所以今天将上年买的 TX-B开发板拿了出来玩玩. 写了一个关于行列扫描的单片机程序.
参考: 矩阵键盘检测

键盘与单片机的连接电路图

6位数码管与单片机的连接电路图


共阴极数码管数字编码

 2006813234022.jpg

 矩阵键盘的四行分别与P3.0-P3.3连接,四列分别与P3.4-P3.7连接。

代码使用"KeilC51v612" 编写, 代码如下:

ContractedBlock.gif ExpandedBlockStart.gif 电话键盘
  1None.gif#include <reg51.H>
  2None.gif//模拟电话键盘, 按动一个键, 显示相应的数值, 行列按普通电话的3 x 4方式排布
  3None.gifunsigned char t, key, a, count;
  4None.gif
  5None.gifsbit light8 = P1^7;
  6None.gif//控制数码管段选的锁存器锁存端   下降沿过后锁存,即先令dula = 1,再令dula=0,完成锁存
  7None.gifsbit dula=P2^6;  
  8None.gif//控制数码管位选的锁存器锁存端   过程如dula
  9None.gifsbit wela=P2^7
 10None.gif
 11ExpandedBlockStart.gifContractedBlock.gifunsigned char code table[]=dot.gif{0x3f,0x06,0x5b,0x4f,0x66,
 12ExpandedBlockEnd.gif    0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}
;//0-F数码管的编码
 13None.gifvoid display(unsigned char num) //数码管显示函数
 14ExpandedBlockStart.gifContractedBlock.gifdot.gif{
 15InBlock.gif    P0=table[num];   //将第num个显示编码送到P0口,从而送到总线上
 16InBlock.gif    dula=1;  //产生一个下降沿将数据锁存
 17InBlock.gif    dula=0;
 18InBlock.gif    P0= 0xc0;
 19InBlock.gif    wela=1;  //同理dula
 20InBlock.gif    wela=0;
 21ExpandedBlockEnd.gif}

 22None.gif
 23None.gif//获取键值, 通过对列检测, base是每一行第一列的数值, 这里的行列按普通电话的3 x 4方式排布
 24None.gifunsigned char getKey(unsigned char da, unsigned char base)
 25ExpandedBlockStart.gifContractedBlock.gifdot.gif{
 26InBlock.gif    switch(da)
 27ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 28InBlock.gif        case 0xe0:  //检测第一列
 29InBlock.gif            return base;
 30InBlock.gif        case 0xd0:  //检测第二列
 31InBlock.gif            return base + 1;
 32InBlock.gif        case 0xb0//检测第三列
 33InBlock.gif            return base + 2;
 34InBlock.gif        default : //其它返回上一次按的值
 35InBlock.gif            return key;
 36ExpandedSubBlockEnd.gif    }

 37ExpandedBlockEnd.gif}

 38None.gif
 39None.gif//等待按键被释放, 若按键一直被按着,则使发光二极管8亮
 40None.gifvoid wait()
 41ExpandedBlockStart.gifContractedBlock.gifdot.gif{
 42InBlock.gif    while(t != 0xf0)
 43ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 44InBlock.gif        t = P3;
 45InBlock.gif        t = t & 0xf0;
 46InBlock.gif        light8 = 0;
 47ExpandedSubBlockEnd.gif    }

 48InBlock.gif    light8 = 1;
 49ExpandedBlockEnd.gif}

 50None.gif
 51None.gif//延时函数, 例i=10,则大概延时10ms.
 52None.gifvoid delay(unsigned char i)
 53ExpandedBlockStart.gifContractedBlock.gifdot.gif{
 54InBlock.gif    unsigned char j, k;
 55InBlock.gif    for(j = i; j > 0; j--)
 56ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 57InBlock.gif        for(k = 125; k > 0; k--);
 58ExpandedSubBlockEnd.gif    }

 59ExpandedBlockEnd.gif}

 60None.gif
 61None.gifvoid main()
 62ExpandedBlockStart.gifContractedBlock.gifdot.gif{
 63InBlock.gif    dula = 0//初始化dula和wela
 64InBlock.gif    wela = 0;
 65InBlock.gif    while(1
 66ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 67InBlock.gif        a = 0xfe//先检测第一行
 68InBlock.gif        for(count = 0; count < 4; count ++)
 69ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 70InBlock.gif            P3 = a;
 71InBlock.gif            t = P3 & 0xf0;    //读P3口
 72InBlock.gif            if(t != 0xf0)  //判断是否有键按下
 73ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
 74InBlock.gif                delay(10);    //延时10ms去抖动
 75InBlock.gif                t = P3 & 0xf0//再次检验是否有键按下
 76InBlock.gif                if(t != 0xf0)
 77ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
 78InBlock.gif                    switch(count) //判断哪一行有键被按下
 79ExpandedSubBlockStart.gifContractedSubBlock.gif                    dot.gif{
 80InBlock.gif                        case 0:
 81InBlock.gif                            key = getKey(t, 1); //获取第一行的哪一列键值
 82InBlock.gif                            break;
 83InBlock.gif                        case 1:
 84InBlock.gif                            key = getKey(t, 4);
 85InBlock.gif                            break;
 86InBlock.gif                        case 2:
 87InBlock.gif                            key = getKey(t, 7);
 88InBlock.gif                            break;
 89InBlock.gif                        case 3:
 90InBlock.gif                            if(t == 0xd0//检测是否第4行第2列有键被按下
 91InBlock.gif                                key = 0;
 92InBlock.gif                            break;
 93ExpandedSubBlockEnd.gif                    }

 94InBlock.gif                    wait();
 95InBlock.gif                    display(key);
 96InBlock.gif                    P1 = a;  //提示哪一行有键被按下
 97ExpandedSubBlockEnd.gif                }

 98ExpandedSubBlockEnd.gif            }

 99InBlock.gif            a = (a << 1| (a >> 7); //继续检测下一行, 循环左移一位实现
100ExpandedSubBlockEnd.gif        }

101ExpandedSubBlockEnd.gif    }

102ExpandedBlockEnd.gif}

呵呵, 我的专业很奇怪, 软件硬件都要掌握, 很多时候我都把握不住方向, 所以只能两样都要懂, 不过我还是觉得软件比较适合我.
感谢郭大哥的实验板, 也是靠着这块板, 我能快速对单片机产生很大兴趣.

 TX-1B实验板功能图 (目前已经被TX-1C代替了)

转载于:https://www.cnblogs.com/fengmk2/archive/2007/03/09/669715.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值