📄 keyboard_int.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 + -