• 微信公众号:美女很有趣。 工作之余,放松一下,关注即送10G+美女照片!

52单片机独立按键输入

互联网 diligentman 2周前 (04-07) 8次浏览

一、原理

52单片机有四组I/O接口,每一组都可以用作独立输入输出。本项目将P1用作输入接口。每一个管脚接一个按键,当按键按下接通时,对应管脚被下拉为低电平;CPU对管脚状态进行扫描,检测输入状态,取得输入按键的位置,然后将按键编号显示在数码管上。

52单片机独立按键输入

二、设计步骤

1. 设计电路图,如图。

52单片机独立按键输入
提示:按键的检索关键词:button。

2. 按键输入对应的P1端口编码,如下表。

按键顺序 P1.7 P1.6 P1.5 P1.4 P1.3 P1.2 P1.1 P1.0 二进制 十六进制
0 1 1 1 1 1 1 1 0 11111110 FE
1 1 1 1 1 1 1 0 1 11111101 FD
2 1 1 1 1 1 0 1 1 11111011 FB
3 1 1 1 1 0 1 1 1 11110111 F7
4 1 1 1 0 1 1 1 1 11101111 EF
5 1 1 0 1 1 1 1 1 11011111 DF
6 1 0 1 1 1 1 1 1 10111111 BF
7 0 1 1 1 1 1 1 1 01111111 7F

关键点提示:①高位在前,低位在后;②连接各单元格字符用&符号;③二进制转十六进制函数BIN2DEX().

3. 编写c程序。
1. 按键位置编号识别函数

#define UCHAR unsigned char

/**
 * @brief 按键序号识别
 * 
 * @param n P1的输入编码。
 * @return UCHAR 按键返回0-7,无按键返回0xff
 */
UCHAR returnKey(UCHAR n)
{
    switch (n)
    {
    case 0xFE:
        return 0;
    case 0xFD:
        return 1;
    case 0xFB:
        return 2;
    case 0xF7:
        return 3;
    case 0xEF:
        return 4;
    case 0xDF:
        return 5;
    case 0xBF:
        return 6;
    case 0x7F:
        return 7;
    default:
        return 0xFF;
    }
}

2. 扫描按键输入,并将按键顺序显示到数码管上。

/**
 * @brief 扫描输入的按键并将序号显示在数码管上。
 * 
 */
void inputKeyScan()
{
    if (returnKey(P1) == 0xFF)
    {
        return ;
    } else {
        displayNum(returnKey(P1));
    }
    
}

3. 主函数调用扫描函数。

/**
 * @brief 主函数
 * 
 */
void main()
{
	while (1)
	{
        P1 = 0xFF;  // 吸收输入,必须先向P1输出高电平
        inputKeyScan(); // 扫描按键输入

        delayNms(5);    // 每隔5ms扫描一次
	}
}

三. 其它用到的函数

1. 数码管分别显示四个数字

const unsigned char HexBCD[] = {0xC0, 0xF9, 0xA4, 0xB0,
                                0x99, 0x92, 0x82, 0xF8,
                                0x80, 0x90, 0x88, 0x83,
                                0xC6, 0xA1, 0x86, 0x8E, 0x7F};

/**
 * @brief 分别在4根数码管上显示数字。每个数字的范围都是0-F。
 * 
 * @param n1 第一个数码管上显示的数字。
 * @param n2 第二个数码管上显示的数字。
 * @param n3 第三个数码管上显示的数字。
 * @param n4 第四个数码管上显示的数字。
 */
void display4N(UCHAR n1, UCHAR n2, UCHAR n3, UCHAR n4)
{
    P2 = 0x01; // 选择第一个数码管
    if (n1 >= 0 && n1 < 0x10)
        P0 = HexBCD[n1]; // 显示n1
    else
        P0 = 0xFF;
    delayNms(5);

    P2 = 0x02; // 选择第二个数码管
    if (n2 >= 0 && n2 < 0x10)
        P0 = HexBCD[n2]; // 显示n2
    else
        P0 = 0xFF;
    delayNms(5);

    P2 = 0x04; // 选择第三个数码管
    if (n3 >= 0 && n3 < 0x10)
        P0 = HexBCD[n3]; // 显示n3
    else
        P0 = 0xFF;
    delayNms(5);

    P2 = 0x08; // 选择第四个数码管

    if (n4 >= 0 && n4 < 0x10)
        P0 = HexBCD[n4]; // 显示n4
    else
        P0 = 0xFF;
    delayNms(5);
}

2. 数码管上显示指定数字

/**
 * @brief 显示给定的数n
 * 
 * @param n 给定的数n
 */
void displayNum(int n)
{
    UCHAR qianWei;
    UCHAR baiWei;
    UCHAR shiWei;
    UCHAR geWei;

    qianWei = n / 1000;
    baiWei = (n % 1000) / 100;
    shiWei = (n % 100) / 10;
    geWei = n % 10;

    if (qianWei == 0)
        qianWei = 0xff;
    
    if (qianWei == 0xff && baiWei == 0)
        baiWei = 0xff;

    if (qianWei == 0xff && baiWei == 0xff && shiWei == 0)
        shiWei = 0xff;

    display4N(qianWei, baiWei, shiWei, geWei);
}

 

思考题

1. 如果同时按下两个或者三个键,会怎么样?

2. 以上程序设计有哪些缺陷?

展开阅读全文

© 著作权归作者所有

举报

打赏

1


0 收藏

微信
QQ
微博

分享

作者的其它热门文章

对几种计算机语言的感受
ubuntu16.04禁用ALT+右键快捷键解决与blender等软件冲突
Ubuntu 16.04环境下php发送邮件配置
qmake 编译后执行命令


程序员灯塔
转载请注明原文链接:52单片机独立按键输入
喜欢 (0)