hrefspace

 找回密码
 立即注册
搜索
热搜: PHP PS 程序设计
查看: 418|回复: 0

自学AVR单片机十六(4X4矩阵键盘的程序设计)

[复制链接]

573

主题

585

帖子

1858

积分

版主

Rank: 7Rank: 7Rank: 7

积分
1858
发表于 2024-2-9 20:04:51 | 显示全部楼层 |阅读模式
下面我们来动手编写4X4矩阵键盘的程序,按键检测程序如下
程序中我们先设置连接矩阵键盘的PD口的高四位为输出口(作为行线),低四位为输入口(作为列线),然后先控制第一根行线输出低电平(其余行线输出高电平),逐列检测4根列线的电平状态,如果其中一根列线为低电平,那么这根列线与设置为输出低电平的行线交叉出的按键就是被按下的按键,计算出按键编码。如果这一行所有列线都为高电平,说明该行没有按键按下,那么接下来控制第二根行线输出低电平继续检测,直到设置第四根行线为低电平。
  1. unsigned char i,j;DDRD = 0xf0;           //设置PD高四位为输出口,低四位为输入口PORTD = 0x00;         // 初始运行输出全为0if((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;       //
复制代码
完整代码
  1. #include <[url=http://www.mcuzx.net]AVR[/url]/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; // 初始运行输出全为0if((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行输出0for(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); }
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|hrefspace

GMT+8, 2024-5-5 05:26 , Processed in 0.063782 second(s), 21 queries .

Powered by hrefspace X3.4 Licensed

Copyright © 2022, hrefspace.

快速回复 返回顶部 返回列表