本文包含原理图、PCB、源代码、封装库、中英文PDF等资源
您需要 登录 才可以下载或查看,没有账号?注册会员
×
下面我们来动手编写4X4矩阵键盘的程序,按键检测程序如下
程序中我们先设置连接矩阵键盘的PD口的高四位为输出口(作为行线),低四位为输入口(作为列线),然后先控制第一根行线输出低电平(其余行线输出高电平),逐列检测4根列线的电平状态,如果其中一根列线为低电平,那么这根列线与设置为输出低电平的行线交叉出的按键就是被按下的按键,计算出按键编码。如果这一行所有列线都为高电平,说明该行没有按键按下,那么接下来控制第二根行线输出低电平继续检测,直到设置第四根行线为低电平。
-
- unsigned char i,j;
- DDRD = 0xf0; //设置PD高四位为输出口,低四位为输入口
- PORTD = 0x00; // 初始运行输出全为0
- if((PIND & 0x0f) == 0x0f) return 16; // 判断有无按键动作,没有,返回0
- else
- {
- Delayms(20); //按键消抖
- if((PIND & 0x0f) == 0x0f) return 16; //再次判断是否有按键动作
- else
- {
- for(i = 4;i < 8;i++) //逐行输出0
- {
- PORTD = ~(1 << i) | 0x0f; //第i行输出0
- for(j = 0;j < 4;j++)
- {
- if((PIND & (1 << j)) == 0) //逐列检测
- KeyNumber = (i - 4) * 4 + j; //计算键值
- }
- }
- return KeyNumber; //
复制代码
完整代码
- #include <AVR/io.h> //io端口寄存器配置文件,必须包含
- #include <util/delay.h> //GCC中的延时函数头文件
- unsigned char Led_Disbuf[17]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
- 0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xff}; //共阳极
- unsigned char KeyNumber;
- //函数声明
- void HC595_Send_Data(unsigned char byte);
- void Delayus(unsigned int lus); //us延时函数
- void Delayms(unsigned int lms); //ms延时函数
- unsigned char Read_Key(void); // 读取键值
- int main(void) //GCC中main文件必须为返回整形值的函数,没有参数
- {
- PORTB = 0X00; //PORTB输出低电平,使LED熄灭
- DDRB = 0XFF; //配置端口PB全部为输出口
- PORTG = 0x00;
- DDRG |= (1 << PG0) | (1 << PG1) | (1 << PG2) | (1 << PG4);
- KeyNumber = 16; //开始没有按键按下,不显示
- while(1)
- {
- if(!(Read_Key() == 16))
- {
- PORTB = Led_Disbuf[KeyNumber];
- HC595_Send_Data(0x01); //选通位选端口
- Delayms(20); //延时
- //HC595_Send_Data(0x00); //位选通关闭
- }//读取键值
- }
- }
- //us级别的延时函数
- void Delayus(unsigned int lus)
- {
- while(lus--)
- {
- _delay_loop_2(3); //_delay_loop_2(1)是延时4个时钟周期,参数为3则延时12
- //个时钟周期,本实验用12M晶体,则12个时钟周期为12/12=1us
- }
- }
- //ms级别的延时函数
- void Delayms(unsigned int lms)
- {
- while(lms--)
- {
- Delayus(1000); //延时1ms
- }
- }
- //4*4矩阵键盘扫描,PD高四位为行输出口,低四位为列输入口
- unsigned char Read_Key(void)
- {
- unsigned char i,j;
- DDRD = 0xf0; //设置PD高四位为输出口,低四位为输入口
- PORTD = 0x00; // 初始运行输出全为0
- if((PIND & 0x0f) == 0x0f) return 16; // 判断有无按键动作,没有,返回0
- else
- {
- Delayms(20); //按键消抖
- if((PIND & 0x0f) == 0x0f) return 16; //再次判断是否有按键动作
- else
- {
- for(i = 4;i < 8;i++) //逐行输出0
- {
- PORTD = ~(1 << i) | 0x0f; //第i行输出0
- for(j = 0;j < 4;j++)
- {
- if((PIND & (1 << j)) == 0) //逐列检测
- KeyNumber = (i - 4) * 4 + j; //计算键值
- }
- }
- return KeyNumber; //
- }
- }
- }
- //发送一个字节
- void HC595_Send_Data(unsigned char byte)
- {
- unsigned char i;
- for(i = 0;i < 8;i++)
- {
- if(byte & 0x80)
- {
- PORTG |= (1 << PG2);
- }
- else
- {
- PORTG &= ~(1 << PG2);
- }
- byte <<=1;
- PORTG |= (1 << PG0); //上升沿数据移位
- //Delayus(10);
- PORTG &= ~(1 << PG0);
- }
- PORTG |= (1 << PG1);
- //Delayus(10);
- PORTG &= ~(1 << PG1);
- }
复制代码 |