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