找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1659|回复: 4
收起左侧

为何我的单片机矩阵键盘不论按那个键12864都只是显示1

[复制链接]
ID:653709 发表于 2019-12-9 19:12 | 显示全部楼层 |阅读模式
200黑币
#include "reg52.h"                         //此文件中定义了单片机的一些特殊功能寄存器
#include"intrins.h"

#define uint unsigned int         
#define uchar unsigned char
#define GPIO_KEY P1
#define lcd_data P0         //数据口
sbit lcd_psb = P3^2; //串/并口选择
sbit lcd_rw = P2^5;         //读写控制
sbit lcd_rs = P2^6;  //寄存器选择  0为指令  1为数据
sbit lcd_EN = P2^7;  //lcd使能信号(并口)
void lcd_wcmd(uchar cmd);
void delay(int ms);
void DisplayDdram(uchar *hz);
void lcd_wdata(uint dat);
uchar KeyValue;        //用来存放读取到的键值
void delay(int ms)
{
    while(ms--)
        {
uchar i;
          for(i=0;i<250;i++)  
           {
            _nop_();                        
                _nop_();
                _nop_();
                _nop_();
           }
        }
}

bit lcd_busy()
{

    bit result;
    P0=0X00;              //关掉数码管的信号。阻止数码管受到P0口信号的影响
lcd_rs = 0;
lcd_rw = 1;
lcd_EN = 1;
delay(1);
    result = (bit)(P0&0x80);
lcd_EN = 0;
    return(result);
}

void lcd_init(void)
{
        lcd_psb = 1;                //并口方式
        lcd_wcmd(0x34);                 //扩展指令
        delay(5);
        lcd_wcmd(0x30);                //基本指令
        delay(5);
        lcd_wcmd(0x0c);                 //显示光标开关
        delay(5);
        lcd_wcmd(0x01);                 //清除lcd的显示内容
        delay(5);
}

void lcd_wcmd(uchar cmd)
{
        while(lcd_busy());
        lcd_rs = 0;
        lcd_rw = 0;
        lcd_EN = 0;
        lcd_data=cmd;
        delay(1);
        lcd_EN = 1;
        delay(1);
        lcd_EN = 0;
}

void DisplayDdram(uchar *hz)
{
        while(*hz!= '\0')
        {
                lcd_wdata(*hz);//地址里面的值
                hz++;
        }
}

void lcd_wdata(uint dat)
{
        while(lcd_busy());
        lcd_rs = 1;
        lcd_rw = 0;
        lcd_EN = 0;
        lcd_data = dat;
        delay(1);
        lcd_EN = 1;
        delay(1);
        lcd_EN = 0;
}

void lcd_pos(uchar x,uchar y)
{
        uchar pos;
        if(x==0)
        {
                x = 0x80;
        }else if(x==1)
        {
                x= 0x90;
        }else if(x==2)
        {
                x = 0x88;
        }else if(x==3)
        {
                x = 0x98;
        }
        pos = x + y;
        lcd_wcmd(pos);
}


uchar KeyDown()
{
        GPIO_KEY=0x0f;
        if(GPIO_KEY!=0x0f)//读取按键是否按下
        {
                delay(10);//延时10ms进行消抖
                if(GPIO_KEY!=0x0f)//再次检测键盘是否按下
                {        
                        //测试列
                        GPIO_KEY=0X0f;
                        switch(GPIO_KEY)
                        {
                                case(0X07):KeyValue=0;break;
                                case(0X0b):KeyValue=1;break;
                                case(0X0d):KeyValue=2;break;
                                case(0X0e):KeyValue=3;break;
                        }
                        //测试行
                        GPIO_KEY=0Xf0;
                        switch(GPIO_KEY)
                        {
                                case(0X70):KeyValue=KeyValue;break;
                                case(0Xb0):KeyValue=KeyValue+4;break;
                                case(0Xd0): KeyValue=KeyValue+8;break;
                                case(0Xe0):KeyValue=KeyValue+12;break;
                        }        
                }
        }
                    return KeyValue;
}



void main()
{
    uchar q;        
   lcd_init();
while(1)
{        
     q=KeyDown();                   //按键判断函数
        lcd_pos(2,1);
switch(q)
{
case 0:DisplayDdram("1");break;
case 1:DisplayDdram("2");break;
case 2:DisplayDdram("3");break;
case 3:DisplayDdram("4");break;
case 4:DisplayDdram("5");break;
case 5:DisplayDdram("6");break;
case 6:DisplayDdram("7");break;
case 7:DisplayDdram("8");break;
case 8:DisplayDdram("9");break;
case 9:DisplayDdram("10");break;
case 10:DisplayDdram("11");break;
case 11:DisplayDdram("12");break;
        }
        delay(1000);        
        lcd_wcmd(0x01);        
}
}

最佳答案

查看完整内容

更据你的程序改了一下 亲测可用。使用时把后缀名rar改成.c或者txt
回复

使用道具 举报

ID:90663 发表于 2019-12-9 19:12 | 显示全部楼层
更据你的程序改了一下 亲测可用。使用时把后缀名rar改成.c或者txt

main.rar

3.91 KB, 下载次数: 13

评分

参与人数 1黑币 +60 收起 理由
admin + 60 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:235200 发表于 2019-12-9 23:30 | 显示全部楼层
因为switch(q)的分类未包含所有可能出现的情况
回复

使用道具 举报

ID:213173 发表于 2019-12-10 07:47 | 显示全部楼层
显示单字符用单引号,字符串用双引号。
回复

使用道具 举报

ID:660858 发表于 2019-12-10 18:54 | 显示全部楼层
     这个是我之前实验做出来程序

*******************************************************************************/
#include<reg52.h>
void delay(unsigned char t);
bit key_certain(void);
/*******************************************************************************
*          实现功能:4×4键盘检测                                                                                            
*        现象描述:按下4×4按键数码管上显示相应的值
*                          K1(0)  K2(1)  K3(2)  K4(3)  K9(8)   K10(9)  K11(A)  K12(B)
*                          K5(4)  K6(5)  K7(6)  K8(7)  K13(C)  K14(D)  K15(E)  K16(F)          *
*******************************************************************************/
sbit wei1=P0^7;//位定义数码管用到的片选,高电平有效
unsigned char code tab[ ]={0x3f, 0x06, 0x5b, 0x4f,
                                                   0x66, 0x6d, 0x7d, 0x07,
                                               0x7f, 0x6f, 0x77, 0x7c,
                                                   0x39, 0x5e, 0x79, 0x71};//0到F的16个键植

/*******************************************************************************
*   名称 : Main()                                                                                                                           *
*******************************************************************************/
void main(void)//主函数
{       
        unsigned char key, j ,k, s;
        while(1)
          {
                   if(key_certain()== 1)                //确定键被按下后,扫描是那个键被按下
                   {   
                    P2=0xfe;                                //送第一行为低电平
                        k=0xfe;                                        //保留这次扫描数值,备移位用
                    for(j=0;j<4;j++)                //四次扫描处理
                    {       
              s=P2&0xf0;                        //屏蔽低四位,取高四位,根据s数值确定那一列,根据扫描的j行确定行数,
                          switch(s)
                                {
                                        case 0xe0: key=4*j+0; break;        //第1列
                                            case 0xd0: key=4*j+1; break;        //第2列
                                         case 0xb0: key=4*j+2; break;        //第3列
                                         case 0x70: key=4*j+3; break;        //第4列
                                         default:        break;
                                }
                          k=(k<<1)|0x01;                //循环扫描,
                          P2=k;                                        //每次仅向一行送0扫描
             }//for
                   }//if       
                      P1=tab[key];                                //数据送数码管显示数据口
                wei1=0;                                                        //选中片选

                delay(10);
          }//while
}
/*******************************************************************************
* 名称 : delay()
*******************************************************************************/
void delay(unsigned char t)//延时函数
{
        unsigned char a;
        while( --t != 0)
        {
                  for(a=0;a<125;a++);
    }
}
/*******************************************************************************
* 名称 : 判断键的否被按下,通过返回值确定
*******************************************************************************/
bit key_certain(void)//判断键的否被按下,通过返回值确定
{
        P2=0xf0;
        if(P2!=0xf0)
           {
            delay(20);
             if(P2 != 0xf0)//延时去抖动,再次确认键被按下,键按下返回值为1,否则为0
                     return 1;
             else
                     return 0;
    }
        else
             return 0;
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表