标题: ATmega16计算器 [打印本页]

作者: mijhzy    时间: 2019-6-11 22:00
标题: ATmega16计算器
#define No_key     255
#define K1_1    1
#define K1_2    2
#define K1_3    3
#define K1_4    4
#define K2_1    5
#define K2_2    6
#define K2_3    7
#define K2_4    8
#define K3_1    9
#define K3_2    0
#define K3_3    10
#define K3_4    11
#define K4_1    12
#define K4_2    13
#define K4_3    14
#define K4_4    15
#define Key_mask    0b00001111

unsigned char read_keyboard()
{   
    static unsigned char key_state = 0, key_value, key_line;
    unsigned char key_return = No_key,i;
   
    switch (key_state)
    {
        case 0:
            key_line = 0b00001000;
            for (i=1; i<=4; i++)                    // 扫描键盘
            {   
                PORTD = ~key_line;                    // 输出行线电平
                PORTD = ~key_line;                    // 必须送2次!!!
                key_value = Key_mask & PIND;        // 读列电平
                if (key_value == Key_mask)
                    key_line <<= 1;                // 没有按键,继续扫描
                else
                {
                    key_state++;                    // 有按键,停止扫描
                    break;                        // 转消抖确认状态
                }
            }
            break;
        case 1:
            if (key_value == (Key_mask & PIND))        // 再次读列电平,
            {
                switch (key_line | key_value)        // 与状态0的相同,确认按键
                {                                // 键盘编码,返回编码值
                    case 0b00001110:
                        key_return = K1_1;
                        break;
                    case 0b00001101:
                        key_return = K1_2;
                        break;
                     case 0b00001011:
                        key_return = K1_3;
                        break;
                    case 0b00000111:
                        key_return = K1_4;
                        break;   
                     case 0b00011110:
                        key_return = K2_1;
                        break;
                     case 0b00011101:
                        key_return = K2_2;
                        break;
                    case 0b00011011:
                        key_return = K2_3;
                        break;
                    case 0b00010111:
                        key_return = K2_4;
                        break;
                     case 0b00101110:
                        key_return = K3_1;
                        break;
                     case 0b00101101:
                        key_return = K3_2;
                        break;
                    case 0b00101011:
                        key_return = K3_3;
                        break;
                    case 0b00100111:
                        key_return = K3_4;
                        break;
                    case 0b01001110:
                        key_return = K4_1;
                        break;
                    case 0b01001101:
                        key_return = K4_2;
                        break;
                    case 0b01001011:
                        key_return = K4_3;
                        break;
                     case 0b01000111:
                        key_return = K4_4;
                        break;
                }
                key_state++;                // 转入等待按键释放状态
            }
            else
                key_state--;                // 两次列电平不同返回状态0,(消抖处理)
            break;                        
        case 2:                            // 等待按键释放状态
            PORTD = 0b00000111;            // 行线全部输出低电平
            PORTD = 0b00000111;            // 重复送一次
            if ( (Key_mask & PIND) == Key_mask)
                key_state=0;                // 列线全部为高电平返回状态0
            break;
    }
    return key_return;
}

作者: admin    时间: 2019-6-12 06:29
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1