无知794 2024-10-30 15:48 采纳率: 0%
浏览 52

51单片机矩阵键盘中断

51单片机,一、用矩阵键盘控制led灯模式切换,按下第一个按键,第一个模式循环完毕,按下第二个按键,第二个循环不能立马切换,需要长按切换。二、如何用矩阵键盘中使用中断,实现在第一个循环没完成时,按下第二个按键,第二个循环实现。

#include <REGX52.H>
#define uchar unsigned char
#define uint unsigned int 
void keyscan();
void keyscan1();
uchar i,K,num,temp;
void delay(uint z)
{
    uint x,y;
    for(x=z;x>0;x--)
      for(y=114;y>0;y--);
}


void timer0() interrupt 1
{
    TH0=(65536-50000)/256;
    TL0=(65536-50000)%256;
    K++;
}

void main()
{
    TMOD=0X01;
    TH0=(65536-50000)/256;
    TL0=(65536-50000)%256;
    EA=1;
    EX0=1;//外部中断
    IT0=1;//设置外部中断的触发方式
    while(1)
    {
        keyscan();
        keyscan1();
    }
}

void keyscan1()
{
    if(num==1) //模式1
        {
            P1=0xfe;    //初始状态将LED0点亮
            for(i=0;i<8;i++)//    1111 1110
            {
                P1=~(0x01<<i);     //将0000 0001左移i位,然后将结果取反赋值到P1口
                delay(200);     //大约延时200ms
            }
            for(i=1;i<8;i++)
            {
                P1=~(0x80>>i);     //将1右移i位,然后将结果取反赋值到P1口
                delay(200); 
            }    
        }
            if(num==2)
        {
            for(i=0;i<4;i++)
            {
                P1=~((0x01<<i)|(0x80>>i));//有两边向中间移动
                delay(200);
            }
            for(i=0;i<4;i++)
            {
                P1=~((0x10<<i)|(0x08>>i));//有中间向两边移动
                delay(200);
            }
        }
        
                if(num==3)
        {
                for(i=0;i<8;i++)
            {
                P1=0xFE<<i;     //将1111 1110左移i位,然后将结果赋值到P1口
                delay(200);     //大约延时100ms
            }
            P1=0xFF; //熄灭所有LED
            for(i=0;i<8;i++)
            {
                P1=~(0xFF>>i);     //将1111 1111右移i位,然后将结果取反赋值到P1口
                delay(200); 
        }    
        }
        if(num==4)
        {
             for(i=0;i<8;i++)
            {
                P1=0x7F>>i;      //从左向右移,灯不熄灭
                delay(200); 
            }
            P1=0xFF; 
            for(i=0;i<8;i++)
            {
                P1=~(0xFF<<i);//从右往左灯逐个熄灭
                delay(200); 
            }    
        } 
}
void keyscan()   //矩形键盘扫描函数
{
    P3=0xfe;   //让p3.0、p3.1、p3.2、p3.3等于0;p3.4、p3.5、p3.6、p3.7等于1
    temp=P3;   //用temp读取p3口当前的值
    temp=temp&0xf0;  //把temp的值和0xf0作与运算,即保持高四位不变,低四位为0
    if(temp!=0xf0)    //如果此时的temp不等于0xf0.说明有按键被按下了
    {
        delay(5);
        temp=P3; //如果有按键按下,temp重新读取P3口的值
        temp=temp&0xf0;
        if(temp!=0xf0)  //再次判断是否真的有按键被按下(即消除前沿抖动)
        {
            temp=P3;
            switch(temp)//让每一个键值和数码管显示的数对应起来
            {
                case 0xee:num=1;
                break;
                case 0xde:num=2;
                break;
                case 0xbe:num=3;
                break;
                case 0x7e:num=4;
                break;
          }
        if(temp!=0xf0)
        {
            temp=P3;
            temp=temp&0xf0;
        }
    }
}
P3=0xfd;
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
    delay(5);
    temp=P3;
    temp=temp&0xf0;
    while(temp!=0xf0)
    {
        temp=P3;
        switch(temp)
        {
            case 0xed:num=5;
            break;
            case 0xdd:num=6;
            break;
            case 0xbd:num=7;
            break;
            case 0x7d:num=8;
            break;
        }
        while(temp!=0xf0)
        {
            temp=P3;
            temp=temp&0xf0;
        }
    }
}
P3=0xfb;
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
    delay(5);
    temp=P3;
    temp=temp&0xf0;
    while(temp!=0xf0)
    {
        temp=P3;
        switch(temp)
        {
            case 0xeb:num=9;
            break;
            case 0xdb:num=10;
            break;
            case 0xbb:num=11;
            break;
            case 0x7b:num=12;
            break;
        }
        while(temp!=0xf0)
        {
            temp=P3;
            temp=temp&0xf0;
        }
    }
}
P3=0xf7;
temp=P3;
temp=temp&0xf0;
while(temp!=0xf0)
{
    delay(5);
    temp=P3;
    temp=temp&0xf0;
    while(temp!=0xf0)
    {
        temp=P3;
        switch(temp)
        {
            case 0xe7:num=13;
            break;
            case 0xd7:num=14;
            break;
            case 0xb7:num=15;
            break;
            case 0x77:num=16;
            break;
        }
        while(temp!=0xf0)
        {
            temp=P3;
            temp=temp&0xf0;
        }
    }
}

}

求指点,代码哪些问题

  • 写回答

1条回答 默认 最新

  • 做而论道_CS 2024-10-30 16:29
    关注

    一、用矩阵键盘控制led灯模式切换,
    按下第一个按键,第一个模式循环完毕,
    按下第二个按键,第二个循环不能立马切换,需要长按切换。

    二、如何用矩阵键盘中使用中断,
    实现在第一个循环没完成时,
    按下第二个按键,第二个循环实现。
    -------------------

    查询按键、执行按键功能,这两者,应该分开。

    比如:查询按键放在外部中断中、
       执行按键功能,放在主程序中。
    又比如:
       查询按键,放在主程序中、
       执行按键功能,放在定时中断中。
    
    
    评论

报告相同问题?

问题事件

  • 创建了问题 10月30日