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

📄 keykey.c

📁 用反转法实现快速高效的4*4键盘扫描
💻 C
字号:
#include <iom16v.h>
#include <macros.h>

#define uint  unsigned int
#define uchar unsigned char
#define F_cpu 7372800

#define K1_1 0  
#define K1_2 1  
#define K1_3 2  
#define K1_4 3  
#define K2_1 4    
#define K2_2 5  
#define K2_3 6  
#define K2_4 7  
#define K3_1 8  
#define K3_2 9  
#define K3_3 10  
#define K3_4 11  
#define K4_1 12  
#define K4_2 13  
#define K4_3 14  
#define K4_4 15  

//uchar Table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//0到9显示
uchar key_value=0;

/*-----------------------------------------------------------------
    延时程序计算方法
	计数个数j = 延时时间/6*晶振频率 - 1
-----------------------------------------------------------------*/
void Delay_ms(uint i)
{
 	uint j;
	while(i--)
	{
	 	j = 1228;//7.3728mhz 1ms延时
	    while(j--);
	}
}
//
void USART_Init(long int baud)
{
 uint temp;
 temp=F_cpu/baud/16-1;
 UBRRH=(uchar)(temp>>8); //写波特率寄存器
 UBRRL=(uchar)temp;//uchar为8位,它会截取16位temp数据中的低8位
 
 UCSRB=(1<<RXEN)|(1<<TXEN); //接收发送使能
 UCSRC=(1<<URSEL)|(0<<USBS)|(1<<UCSZ0)|(1<<UCSZ1);  //异步,1个停止位,8个数据位
}
void USART_Transmit(uchar data)
{
 while(!(UCSRA&(1<<UDRE)));  //等待数据发送完
 UDR=data;
}
//
#pragma interrupt_handler int0_isr:2
void int0_isr(void)
{
/*(1)当I/O口从输出方式改为输入方式后,应延时至少一个系统时钟周期再读
  (2)当I/O口外部引脚电平改变后,也要延时至少一个系统时钟周期后再读取*/ 
unsigned char key,keyl,keyh; 
asm("nop"); 
asm("nop");
Delay_ms(20);//延时消抖
keyl=PINB;//读取列值
  
PORTB=0b11110000;//将PORTB的状态取反 
DDRB=0b00001111;//将行列的输入输出模式调换 
asm("nop");
asm("nop");//此处一定要加两个nop,否则无法正确读取第一列按键
keyh=PINB;//读取行值 
key=keyl|keyh;//读取该键的键值  
 
switch (key)
{ 
 case 0b11101110:key_value=K1_1; break; 
 case 0b11101101:key_value=K1_2; break; 
 case 0b11101011:key_value=K1_3; break; 
 case 0b11100111:key_value=K1_4; break; 
 case 0b11011110:key_value=K2_1; break; 
 case 0b11011101:key_value=K2_2; break; 
 case 0b11011011:key_value=K2_3; break; 
 case 0b11010111:key_value=K2_4; break; 
 case 0b10111110:key_value=K3_1; break; 
 case 0b10111101:key_value=K3_2; break; 
 case 0b10111011:key_value=K3_3; break; 
 case 0b10110111:key_value=K3_4; break; 
 case 0b01111110:key_value=K4_1; break; 
 case 0b01111101:key_value=K4_2; break; 
 case 0b01111011:key_value=K4_3; break; 
 case 0b01110111:key_value=K4_4; break; 
 default: break; 
}
USART_Transmit((key_value/10)+'0');
USART_Transmit((key_value%10)+'0');
}
//
void main(void)
{
DDRD=0x00;//中断输入管脚要定义为输入
PORTD=0x00;
USART_Init(9600); //波特率9600 初始化串口
 
CLI(); 
GICR=0x40;//开中断0
MCUCR=0x02;//中断0,下降沿触发 
GIFR=0xC0;
SEI(); 
while(1)  
{ 
 PORTB=0b00001111;  
 DDRB=0b11110000;
} 
}

⌨️ 快捷键说明

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