⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keyboard_int.c

📁 在这个实例中
💻 C
字号:
/* 中断唤醒的键盘扫描 源程序  加入抗抖动 */
#include "iom48v.h"
#include "macros.h"
#include "delay.h"
#include "led_dis.h"

#define Key_X_1 PORTC = 0b11011111          //扫描第1行键
#define Key_X_2 PORTC = 0b11101111          //扫描第2行键

#define Key_Scan_Port PINC                  //定义用于扫描键盘的端口
#define Key_Y_1 0b11110111                  //第1列上有键按下
#define Key_Y_2 0b11111011                  //第2列上有键按下
#define Key_Y_3 0b11111101                  //第3列上有键按下

#define Key_A 0x0A
#define Key_B 0x0B
#define Key_C 0x0C
#define Key_D 0x0D
#define Key_E 0x0E
#define Key_F 0x0F
#define NoKey 0x00

#define LedDisPort PORTD

unsigned char Key_Scan (void)                             //键盘扫描函数,扫描键盘一次并返回键值
{
/*-----------------------扫描第1行-----------------------*/
    Key_X_1;

    Delay_ms(1);

    if ((Key_Scan_Port|Key_Y_1)==Key_Y_1)
        return Key_A;
    else if ((Key_Scan_Port|Key_Y_2)==Key_Y_2)
        return Key_B;
    else if ((Key_Scan_Port|Key_Y_3)==Key_Y_3)
        return Key_C;

/*-----------------------扫描第2行-----------------------*/
    Key_X_2;

    Delay_ms(1);

    if ((Key_Scan_Port|Key_Y_1)==Key_Y_1)
        return Key_D;
    else if ((Key_Scan_Port|Key_Y_2)==Key_Y_2)
        return Key_E;
    else if ((Key_Scan_Port|Key_Y_3)==Key_Y_3)
        return Key_F;

    return NoKey;
}

unsigned char Key_Scan_Ant_Dither(void)                   //抗抖动的键盘扫描函数,扫描键盘并返回键值
{
    unsigned char TmpKeyValue=NoKey;

    TmpKeyValue=Key_Scan();

    if (TmpKeyValue==NoKey)
        return NoKey;

    Delay_ms(20);

    if (TmpKeyValue!=Key_Scan())
        return NoKey;

    return TmpKeyValue;
}


#pragma interrupt_handler pcint1_isr: iv_PCINT1
void pcint1_isr(void)                                    //引脚电平变化中断PCINT1中断服务函数
{
    SMCR&=0xFE;                                          //禁止休眠功能,以免误触发
    PCMSK1&=(~((1<<PCINT11)|(1<<PCINT10)|(1<<PCINT9)));  //禁止引脚电平变化中断,以免影响键盘扫描程序的运行
    PCICR&=(~(1<<PCIE1));
}

void main (void)
{
    unsigned char KeyValue=NoKey;
    unsigned int SleepTimer=0;

    DDRC=0xF1;                  //将键盘的"行"设置为输出,键盘的"列"设置为输入并开启了输入端的内部上拉电阻
    DDRB=0xFF;
    DDRD=0xFF;
    PORTC=0xFF;
    PORTB=0xFF;
    PORTD=0xFF;

    SEI();                     //允许全局中断

    LedDisPort=DisTab[0];      //上电后初始化显示"0"

    while(1)
    {
        KeyValue=Key_Scan_Ant_Dither();
        if (KeyValue!=NoKey)                                            //当有按键按下时,显示该键的键值
            {
                LedDisPort=DisTab[KeyValue];
                SleepTimer=0;                                           //并清0休眠计时器
            }
        else                                                            //当没有按键按下时,计算连续未操作的时间
            {
                SleepTimer++;                                           //休眠计时器自加以实现计时
                if (SleepTimer >= 1500)                                  //当连续3秒钟(近似值)没有按任何按键时,将进入休眠状态
                {
                    SleepTimer=0;                                       //清0休眠计时器,以便唤醒后继续计时
                    PORTC=0b11001111;                                   //将键盘的行(PC5,PC4)设置为输出"0"状态
                    PORTD=0x00;                                         //关闭数码管显示驱动以节省电能
                    PCMSK1|=((1<<PCINT11)|(1<<PCINT10)|(1<<PCINT9));    //使能PCINT9..11
                    PCICR|=(1<<PCIE1);                                  //使能第一组引脚电平变化中断
                    SMCR=0x05;                                          //设置掉电状态并使能休眠功能
                    asm("SLEEP");                                       //休眠单片机,进入掉电状态
                    PORTC=0xFF;											//休眠唤醒后将PC端口重置回初始化状态
                }
            }					//End Of Else
    }							//End Of While
}
//硬件环境:ATmeg48 单片机,CPU时钟1MHz
//软件环境:ICC AVR6.3以上

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -