单片机学习小组
直播中

张敏

7年用户 1525经验值
私信 关注

如何对基于单片机的独立按键控制系统进行Proteus仿真呢

如何利用单片机去设计一种独立按键控制系统呢?如何对基于单片机的独立按键控制系统进行proteus仿真呢?

回帖(1)

张奕

2022-2-23 10:53:58

注意:要加上延时消抖功能(我对这个的理解:消抖是消除键盘的抖动,即假性按下键盘;延时是对键长按时,要延时等待键释放,再进行下一步处理)

电路设计




  • P1口高四位分别控制左列LED灯上移、左列LED灯下移、右列LED灯上移、右列LED灯下移
  • P0口接左列LED灯
  • P2口接右列LED灯



编写思路




  • 首先将P0,P2初始化为工作状态,即让每列的第一个灯亮起来
  • 进入工作循环状态:
    -> 判断是否有键按下:
    (有键按下 -> 消抖,延时20ms -> 再判断是否真的有键按下:
    (有键按下 -> 查找对应操作,进行处理 -> 处理完毕后,判断键是否释放:
    (释放 -> 继续循环;
    未释放 -> 等待释放,再回到判断是否有键按下)
    无键真的按下 -> 回到判断是否有键按下)
    无键按下 -> 回到判断是否有键按下)


汇编语言


ORG 0000H
LJMP START
ORG 0030H
START:MOV P0,#0FEH
          MOV P2,#0FEH
START0:MOV P1,#0FFH                ;读P1口:首先向P1口送1,为读P1口做准备
           MOV A,P1
           CJNE A,#0FFH,START1                ;判断是否有键按下
           AJMP NEXT
START1:ACALL DELAY0                ;延时20ms消抖
           MOV P1,#0FFH
           MOV A,P1
           CJNE A,#0FFH,JP1                ;再次确认是否真的有键按下
           AJMP NEXT
JP1:JNB ACC.4,LP1
        JNB ACC.5,LP2
        JNB ACC.6,LP3
        JNB ACC.7,LP4
        SJMP NEXT
LP1:MOV A,P0
        RR A
        MOV P0,A
        SJMP NEXT
LP2:MOV A,P0
        RL A
        MOV P0,A
        SJMP NEXT
LP3:MOV A,P2
        RR A
        MOV P2,A
        SJMP NEXT
LP4:MOV A,P2
        RL A
        MOV P2,A
NEXT:MOV P1,#0FFH
         MOV A,P1                ;再读P1的引脚
         CJNE A,#0FFH,NEXT                ;确认键是否释放,若没释放,则等待键释放
         SJMP START0
DELAY0:MOV R2,#70                ;20ms消抖子程序
D01:   MOV R3,#100
D02:   DJNZ R3,D02
           DJNZ R2,D01
           RET
           END

C语言


#include                 //定义特殊功能寄存器和位寄存器
#include                 //定义本征库函数,需要使用库中循环左右移位的函数
#define uchar unsigned char
#define uint unsigned int
***it L_UP = P1^4;                //定义按键
***it L_DOWN = P1^5;
***it R_UP = P1^6;
***it R_DOWN = P1^7;

void delay(uint x)                //定义延时xms函数
{
        uchar i;
        while(x--)
        {
                for(i = 0; i < 120; i++);
        }
}

int judge_ac()                //定义判断按键是否按下函数
{
        if(P1 != 0xFF) return 1;                //有键按下
        else return 0;                //无键按下或者键已释放
}

void main()
{
        P0 = 0xFE;P2 = 0xFE;                //初始化P0和P2,让第一个灯亮起来
        while(1)
        {
                if(judge_ac())                //有键按下
                {
                        delay(20);                //延时20ms消抖
                        if(judge_ac())                //判断是否真的有键按下
                        {
                                if(!L_UP)                P0 = _cror_(P0,1);
                                else if(!L_DOWN) P0 = _crol_(P0,1);
                                else if(!R_UP)         P2 = _cror_(P2,1);
                                else if(!R_DOWN) P2 = _crol_(P2,1);
                                while(judge_ac());                //等待键释放
                        }
                }
        }
}

注意:在C中用循环位移函数的话,必须要声明本征库函数intrins;且循环位移函数应该使用char型,不是int型。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分