微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 大家好,我是菜鸟,想知道为什么按键一按下,单片机就停止工作了呢?求大神解答

大家好,我是菜鸟,想知道为什么按键一按下,单片机就停止工作了呢?求大神解答

时间:10-02 整理:3721RD 点击:
我做的4*4矩阵按键,每次按键按下显示一个数字,0~F显示,数码管依次显示出按键按下的数值,但是为什么按键一按下,单片机就停止工作了呢?能不能按键按下单片机继续工作,松开后再返回数值?这是程序,求大神解答
#include<reg51.h>
sbit P3_0 = P3^0;
code unsigned char seven_seg[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//数码管数字数组
code unsigned char key_scan[] = {0xef,0xdf,0xbf,0x7f};//让按键列线依次出现出现低电平,共需要4个扫描数据
code unsigned char key_num[] =         {
                                                                        0xee,0xed,0xeb,0xe7,         //0        1    2           3
                                                                        0xde,0xdd,0xdb,0xd7,        //4        5    6           7
                                                                        0xbe,0xbd,0xbb,0xb7,        //8        9   10   11
                                                                        0x7e,0x7d,0x7b,0x77                // 12 13 14  15
                                                                };                                                         //按键按下的键值
code unsigned char led_num[] =         {
                                                                        0xe1,0xe2,0xe4,0xe8,               //0        1      2           3
                                                                        0xd1,0xd2,0xd4,0xd8,        //4        5      6      7
                                                                        0xb1,0xb2,0xb4,0xb8,        //8         9    10    11
                                                                        0x71,0x72,0x74,0x78                // 12 13   14        15
                                                                };                                                         //按键按下的灯值
unsigned char XH[10];
unsigned char cp,cp1;
void delay(unsigned int x)        //延时函数
{
        while(x--);
}


void display(unsigned char xs)        //显示函数
{       
        P0 = 0xff;
        switch(cp)
        {
                case 0: P3_0 = 0;P3_0 = 1;P0 = 0x01;P3_0 = 0;P0 = seven_seg[xs];break;
                case 1: P3_0 = 0;P3_0 = 1;P0 = 0x02;P3_0 = 0;P0 = 0xbf;break;
                case 2: P3_0 = 0;P3_0 = 1;P0 = 0x04;P3_0 = 0;P0 = seven_seg[XH[1]];break;
                case 3: P3_0 = 0;P3_0 = 1;P0 = 0x08;P3_0 = 0;P0 = seven_seg[XH[2]];break;
                case 4: P3_0 = 0;P3_0 = 1;P0 = 0x10;P3_0 = 0;P0 = seven_seg[XH[3]];break;
                case 5: P3_0 = 0;P3_0 = 1;P0 = 0x20;P3_0 = 0;P0 = seven_seg[XH[4]];break;
                case 6: P3_0 = 0;P3_0 = 1;P0 = 0x40;P3_0 = 0;P0 = 0xbf;break;
                case 7: P3_0 = 0;P3_0 = 1;P0 = 0x80;P3_0 = 0;P0 = seven_seg[cp1];break;       
        }
        cp++;
        if(cp >= 8)
        cp = 0;                        
}
unsigned char key(void)        //按键函数
{
        unsigned char i,j;
        for(i = 0;i < 4;i++)
        {
                P2 = key_scan[i];
                if(P2 != key_scan[i])
                {
                        delay(300);                        //消除按键抖动,有按键确实按下
                        if(P2 != key_scan[i])        //如果有按键按下,P2口不是原来扫描数据
                        for(j = 0;j < 16;j++)        //让键盘行线输出扫描数据
                        {
                                if(P2 == key_num[j])
                                {
                                        while(P2 == key_num[j]) ;
                                        cp1++;                                 //4个显示的数的数组
                                        if(cp1 >= 4) cp1 = 4;       
                                        XH[cp1] = j;
                                        return(j);       
                                }                       
                        }
                }
        }
        return(6);               
}

void main(void)                //主函数
{
        unsigned char k; //定义一个变量k
        while(1)
        {         
               
                k = key();           //把扫描的值赋值给k
                display(k);           //显示k
                P1 = led_num[k];
        }                       
}

大家好,我是菜鸟

管理你的回复何解?

给你一个简单易懂的矩阵键盘程序试试,消抖、自锁、不会死。
unsigned char key(void)                                //按键函数
{
        unsigned char temp1,temp2,temp3;        //临时变量
        static bit sign=0;                                        //按键自锁标志
        static unsigned char count=0;                //消抖计数变量
        P2=0xf0;                                                        //先给P2赋一个初值
        if(P2!=0xf0)                                                 //判断P2不等于所赋初值,说明有健按下
        {
                if(sign==0)                                                //如果按键自锁标志为0
                {
                        count++;                                        //消抖计数
                        if(count>=100)                                //消抖计数自>=100,估算主循环周期调整
                        {                                                        //摒弃Delay延时方式,
                                count=100;                                //防止溢出
                                sign=1;                                        //按键自锁标志置1,键不抬起,按其他键无效
                                temp1=P2;                                //temp1保存高4位变化
                                P2=0x0f;                                //再给P2赋值0x0f
                                temp2=P2;                                //temp2保存低4位变化
                                temp3=temp2|temp1;                //temp3=高4位+低4位
                                return temp3;                        //返回键值                               
                        }
                }
        }
        else                                                                 //按键抬起
        {
                sign=0;                                                        //按键自锁标志清0
                count=0;                                                //消抖计数清0
        }
}

主要是你的按键检测代码逻辑问题,你设置了松手后才能继续往下执行,给你的感觉当然是单片机不工作了。其实单片机还在工作,只不过做的事情效率太低了。   至于解决办法,就让其他人来帮你把

没有别的意思,就是觉得挺好玩的

你这太不详细了……

嗯嗯,谢谢了

什么意思?

嗯嗯,我再好好改改

现在只会这么多,我再好好改改

我也不知道               


你的这个函数里面,问题很大

你的按键扫描程序中没有返回函数,所以你的程序执行逻辑错误哦!你试着把按键扫面部分加一个返回函数!

恩恩,谢啦,现在已经成功了

怎么了?可以详细点吗?

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top