51单片机键盘检测
51单片机矩阵键盘扫描程序
{
TH0=(65536-2000)/256;//重新赋值2ms
TL0=(65536-2000)%256;
Display(0,8); //调用数码管扫描
}
/*------------------------------------------------
unsigned char code dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71};//显示段码值0~F
unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码
case 0xd7:return 11;break;//b
case 0xee:return 12;break;//c
case 0xed:return 13;break;//d
case 0xeb:return 14;break;//e
case 0xe7:return 15;break;//f
default:return 0xff;break;
}
}
/*------------------------------------------------
uS延时函数,含有输入参数unsigned char t,无返回值
unsigned char是定义无符号字符变量,其值的范围是
0~255这里使用晶振12M,精确延时请使用汇编,大致延时
长度如下T=tx2+5 uS
51单片机_独立按键检测
《51系列单片机_独立按键检测》此程序使用单片机89SC52//1、此程序实现独立按键的检测功能,每次按下按键key5时,数码管最后一位显示的数值加1,按键同时响蜂鸣器#include<reg52.h>sbitkey5 = P1^4;//独立按键sbitP3_6 = P3^6;//蜂鸣器控制端口unsigned char codeBitSet[8] ={0xfe, 0xfd, 0xfb, 0xf7,0xef, 0xdf, 0xbf, 0x7f};//用于设置(低电平位选)数码管的位选信号,从低到高对应8个数码管unsigned charcode NumberCode[16] ={0x3f, 0x06, 0x5b, 0x4f,0x66, 0x6d, 0x7d, 0x07,0x7f, 0x6f, 0x77, 0x7c,0x39, 0x5e, 0x79, 0x71,};//用于设置(共阴极)数码管的段选信号,从0~f共16个数值voiddelay_ms(unsigned int n){//软件延时函数,延时n毫秒unsigned int i, j;for(i=n;i>0;i--)for(j=110;j>0;j--);}voidbeep(int n){inti = n;//喇叭连续响n毫秒while(i>0)//向喇叭输入1000HZ的方波震荡源{P3_6 = 1;delay_ms(1);//0.5毫秒高电平P3_6 = 0;delay_ms(1);//0.5毫秒低电平i--;}}voidmain(){intnum=0;while(1){P2=BitSet[7];//选择最低位的数码管if(key5==0)//判断按键key5是否按下{delay_ms(10);//延时重新判断按键是否按下,延时消除抖动if(key5==0){num++;//每按下一次显示的数值加1beep(200);//喇叭响200毫秒if(num==16) num=0;while(!key5);//直到按键释放,按下时key5==0,持续循环}}P0=~NumberCode[num];}}//2、此程序实现独立按键的检测功能,key5和key6每次按下按键时,数码管次低位和最低位显示的数值加1,按键同时响蜂鸣器#include<reg52.h>sbit key5 = P1^4;sbit key6 = P1^5;sbit P3_6 = P3^6;unsigned char code BitSet[8] ={0xfe, 0xfd, 0xfb, 0xf7,0xef, 0xdf, 0xbf, 0x7f};//用于设置(低电平位选)数码管的位选信号,从低到高对应8个数码管unsigned char code NumberCode[16] ={0x3f, 0x06, 0x5b, 0x4f,0x66, 0x6d, 0x7d, 0x07,0x7f, 0x6f, 0x77, 0x7c,0x39, 0x5e, 0x79, 0x71,};//用于设置(共阴极)数码管的段选信号,从0~f共16个数值void delay_ms(unsigned int n){//软件延时函数,延时n毫秒unsigned int i, j;for(i=n;i>0;i--)for(j=110;j>0;j--);}void beep(int n){int i = n;//喇叭连续响n毫秒while(i>0)//向喇叭输入1000HZ的方波震荡源{P3_6 = 1;delay_ms(1);//0.5毫秒高电平P3_6 = 0;delay_ms(1);//0.5毫秒低电平i--;}}void main(){int num=0, num2=0;while(1){P2=BitSet[6];//选择最低位的数码管if(key5==0)//判断按键key5是否按下{delay_ms(10);//延时重新判断按键是否按下,延时消除抖动if(key5==0){num++;//每按下一次显示的数值加1beep(100);//喇叭响100毫秒if(num==16) num=0;while(!key5){P2=BitSet[6];//选择次低位的数码管P0=~NumberCode[num];delay_ms(3);P2=0xff;}}}};P2=BitSet[7];//选择最低位的数码管P0=~NumberCode[num2];delay_ms(3);P2=0xff;//直到按键释放,按下时key5==0,持续循环P0=~NumberCode[num];delay_ms(3);P2=0xff;}P2=BitSet[7];//选择最低位的数码管if(key6==0)//判断按键key6是否按下{delay_ms(10);//延时重新判断按键是否按下,延时消除抖动if(key6==0){num2++;//每按下一次显示的数值加1beep(100);//喇叭响100毫秒if(num2==16) num2=0;while(!key6){P2=BitSet[6];//选择次低位的数码管P0=~NumberCode[num];delay_ms(3);P2=0xff;P2=BitSet[7];//选择最低位的数码管P0=~NumberCode[num2];delay_ms(3);P2=0xff;};;//直到按键释放,按下时key6==0,持续循环}} P0=~NumberCode[num2];delay_ms(3);P2=0xff;。
51单片机4×4矩阵按键扫描方法
key=0xf0;//低四位为0
if(key==0xf0)//若无变化,证明按键松开
return 0;//返回0
else//否则,按键未松开
return 1;//返回1
}
//*********主函数*********//
int main()
{
key=0xff;//按键初始化
led=0xff;//关闭LED灯
//送至led显示
/*
eg:如果是第三行第二列按键按下
则第3个、第6(2列+4)个LED灯亮
如下图所示(Proteus仿真电路图)
*/
}
}
led_arry[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//数组定义,便于显示
//******检测是否有按键按下*****//
uchar Check_Button()
{
key=0x0f;//高四位为0
if(key==0x0f)//若无变化,证明无按键按下
return 0;//返回0
else//否则
return 1;//返回1
}
//********行检测********//
uchar Line[]={0x0e,0x0d,0x0b,0x07}; //那个按键按下,检测出的状态则对应数组中的第几个数
void Check_Line()
{
uchar i;
key=0x0f;//高四位为0
/*****4×4按键扫描******/
/***编程要点
1.首先检测是否有按键按下
2.若有按键按下,即进行行检测,列检测
3.行检测:高4位设为0,低4位为1,进行检测0x0f
51单片机矩阵键盘带去抖释放检测汇编
ORG 0000HLJMP MAINORG 0100HMAIN: ACALL KEYSCAN ;调用子函数MOV A,30H ;从30H单元取相应的数值MOV DPTR,#TABLEMOVC A,@A+DPTRMOV P2,AACALL DELAY20MSSJMP MAINMOV P1,#0FH ;线反转法MOV A,P1ANL A,#0FHMOV B,AMOV P1,#0F0HMOV A,P1ANL A,#0F0HORL A,BMOV 30H,ACJNE A,#0FFH, MASKVIB ;有键按下转去抖动RETMASKVIB: ACALL DELAY20MSMOV P1,#0FH ;再次检测MOV A,P1ANL A,#0FHMOV B,AMOV P1,#0F0HMOV A,P1ANL A,#0F0HORL A,BCJNE A,30H, QUITKEY;比较两次扫描键值RELEASE: MOV P1,#0FFH ;释放检测MOV A,P1CJNE A,#0FFH, RELEASE ;等待释放KEYPRO: MOV B,30H ;键值处理程序MOV DPTR,#KEYV ALUEMOV R7,#0FFHKEY1: INC R7MOV A,R7MOVC A,@A+DPTRCJNE A,B,KEY2MOV A, R7MOV 30H,A;键码保存SETB 20H ;键值有效标志位RETKEY2: CJNE A,#00H,KEY1 ;扫描键值结束标志QUITKEY: RET ;键扫描无效退出DELAY20MS: ;延时20MS子程序,使用40,41,42单元MOV 40H,#20 ;NEXT1: MOV 41H,#20NEXT2: MOV 42H,#248DJNZ 42H,$DJNZ 41H,NEXT2DJNZ 40H,NEXT1RETKEYV ALUE: DB 77H,7BH,7DH,7EH ;键码表DB 0B7H,0BBH,0BDH,0BEHDB 0D7H,0DBH,0DDH,0DEHDB 0E7H,0EBH,0EDH,0EEHDB 00HTABLE: DB 0C0H,0F9H,0A4H,0B0H ;共阳数码管编码表DB 99H,92H,82H,0F8HDB 80H,90H,88H,83HDB 0C6H,0A1H,86H,8EHEND矩阵键盘扫描子程序,使用P1口。
51单片机_矩阵按键检测
}
returnk;//返回扫描到的键值
}
void main()
{
int num=0, tmp;
while(1)
{
tmp = MatrixKeyscan();//扫描键盘判断是否有按键按下
if(tmp != -1) num = tmp;//当有按键按下时,将键值赋给num(无键按下时扫描键盘返回值-1)
《51系列单片机_矩阵按键检测》
此程序使用单片机89SC52
//1、此程序实现矩阵按键的检测功能,按下按键时,数码管显示按键的相应键值
#include<reg52.h>
voiddelay_ms(int n)//延时函数,延时n毫秒
{
inti, j;
for(i=0; i<n; i++)
for(j=0; j<110; j++);
}
voiddisplay(int num)//控制数码管按位输出显示数值num
{
charBitSet[8] =
{
0x7f, 0xbf, 0xdf, 0xef,
0xf7, 0xfb, 0xfd, 0xfe
};//用于设置(低电平位选)数码管的位选信号,从低到高对应8个数码管
charNumberCode[16] =
for(i=0; i<4; i++)
{
P1 = line[i];//将行扫描值逐个送至P1端口
tmp = P1;//再读取P1口的值
if(tmp != line[i])//若读取的数值不等于送入的行扫描值,表示有按键被按下
{
delay_ms(10);//延时,重新读取判断,确认有键按下
基于MCS-51单片机的独立按键和矩阵按键检测实验
实验三基于MCS-51单片机的独立按键和矩阵按键检测实验一、支撑课程目标目标1:掌握微机和单片机的基本原理、编程技术、中断技术、系统扩展、定时器、串行接口和其他输入/输出接口技术,并且了解典型的单片机应用系统的设计思想和实现方法。
目标2:初步具备自行拟定实验步骤、检查和故障排除、分析和综合实验结果以及撰写实验报告的能力。
目标4:掌握MCS-51单片机/STM32F103单片机系统仿真工具和仿真流程,了解常用实验仪器、设备的基本工作原理,了解其正确使用方法,具备利用电子仪器设备和专业仿真软件对复杂工程问题进行分析和设计的能力。
二、实验类型:验证型( )、设计型(√)、研究创新型()三、预期学生学习的成果1、具有典型按键检测电路原理及消除抖动的必要性的认知。
2、理解程序设计消除抖动的实现过程。
3、掌握独立按键的程序查询检测编程实现。
4、掌握独立按键的中断检测编程实现。
5、理解矩阵键盘的行列扫描检测原理,具有矩阵键盘软硬件设计综合能力。
四、实验原理1、典型按键检测电路典型的按键检测电路具备检测按键的条件:检测引脚处在键按下前和后,要有电平变化,否则按键无法检测。
电路组成包括电源、上拉电阻、按键、接地组成,按下前,检测引脚高电平,按下后检测引脚低电平。
电阻防止按下电源短路,如图1(a)。
GND(a)(b)图 1 按键典型电路及对应检测电压2、按键抖动及消除如图1(b),理想条件下,按键未按下,在检测I/O端口是高电平,按下以后,检测I/O端口是低电平,手松后,按键弹起,检测I/O端口是高电平。
整个按键过程出现高电平到低电平又到高电平,有下降沿,也有上升沿。
实际过程中,由于人手的抖动,检测端电压如图1(c),检测电压出现“毛刺”抖动,假设单片机检测高电平阈值为VH,低电平阈值为VL,一次按键就会出现多次高电平到低电平变化,存在按键误检测可能。
常用消除办法之一:一旦检测到低电平,延迟u毫秒,u选择大于20,再次判断检测端是否是低电平,如果是,就判定为1次按键。
51单片机的矩阵按键扫描的设计C语言程序
51单片机的矩阵按键扫描的设计C语言程序以下为一个基于51单片机的矩阵按键扫描的设计C语言程序:```c#include <reg51.h>//定义端口连接到矩阵键盘sbit col1 = P2^0;sbit col2 = P2^1;sbit col3 = P2^2;sbit row1 = P2^3;sbit row2 = P2^4;sbit row3 = P2^5;sbit row4 = P2^6;//声明按键函数char read_keypad(;void maiwhile (1)char key = read_keypad(; // 读取按键值//根据按键值进行相应操作switch(key)case '1'://第一行第一列按键逻辑//在此处添加相应的代码break;case '2'://第一行第二列按键逻辑//在此处添加相应的代码break;//继续处理其他按键//...default://未识别到按键break;}}//按键扫描函数char read_keypacol1 = 0; col2 = 1; col3 = 1; // 激活第一列if (row1 == 0) { // 第一行第一列按键被按下while (row1 == 0); //等待按键释放return '1'; // 返回按键值}if (row2 == 0) { // 第二行第一列按键被按下while (row2 == 0); //等待按键释放return '4'; // 返回按键值}if (row3 == 0) { // 第三行第一列按键被按下while (row3 == 0); //等待按键释放return '7'; // 返回按键值}if (row4 == 0) { // 第四行第一列按键被按下while (row4 == 0); //等待按键释放return '*'; // 返回按键值}col1 = 1; col2 = 0; col3 = 1; // 激活第二列//处理第二列的按键逻辑//...col1 = 1; col2 = 1; col3 = 0; // 激活第三列//处理第三列的按键逻辑//...return '\0'; // 返回空字符表示未检测到按键```以上代码中,我们使用51单片机的P2端口连接到矩阵键盘的列和行,通过扫描不同的列和检测行的状态来判断按键是否被按下。
51单片机的键盘扫描程序
一个51单片机的键盘扫描程序,算法简单有效/****************************************键盘_不采用定时器_不延时特点:按键在松手后有效,灵敏度高,消耗资源少,运行效率高独立键盘为:K01=P2^4;K02=P2^5;K03=P2^6;K04=P2^7;矩阵键盘为:行(上到下)_P2.3_P2.2_P2.1_P2.0列(左到右)_P2.7_P2.6_P2.5_P2.4提供的操作函数://独立键盘.无按键动作时其返回值num_key=0,否则返回按键号num_keyextern unsigned char keyboard_self();//矩阵键盘.无按键动作时其返回值num_key=0,否则返回按键号num_key****检测高四位extern unsigned char keyboard_matrix();****************************************/先看独立键盘(和矩阵键盘的算法一样)-----------------------------------------------------------------------#include<reg52.h>#include<intrins.h>//独立键盘.无按键动作时其返回值num_key=0,否则返回按键号num_keyextern unsigned char keyboard_self(){unsigned char num_key=0;//按键号unsigned char temp=0;//用于读取P2线上按键值static unsigned char temp_code=0;//保存按键值static unsigned char num_check=0;//低电平有效次数static unsigned char key_flag=0;//按键有效标识temp=P2&0xF0;//读取P2线数据if(temp!=0xF0)//低电平判断{num_check++;if(num_check==10)//连续10次(10ms)低电平有效,则认为按键有效{key_flag=1;//使能按键有效标识temp_code=temp;//保存按键值}}else//松手时判断{num_check=0;if(key_flag==1)//按键有效{key_flag=0;switch(temp_code)//读取按键号{case 0xE0: num_key=1;break;case 0xD0: num_key=2;break;case 0xB0: num_key=3;break;case 0x70: num_key=4;break;}}}return(num_key);}现在是矩阵键盘的-----------------------------------------------------------------------#include<reg52.h>#include<intrins.h>//矩阵键盘.无按键动作时其返回值num_key=0,否则返回按键号num_key****检测高四位extern unsigned char keyboard_matrix(){unsigned char num_key=0;//按键号unsigned char temp=0;//读取P2口线数据static unsigned char temp_code=0;//用于保存按键值static unsigned char temp_circle=0xFE;//保存P2线上的循环扫描值static unsigned char num_check=0;//低电平计数static unsigned char key_flag=0;//按键有效标识P2=temp_circle;//0xFXtemp=P2;//读取P2口线数据if(temp!=temp_circle)//有按键动作{num_check++;//低电平计数|逢低电平加1if(num_check==10)//连续10次(10ms)低电平有效{key_flag=1;//按键有效标识置1temp_code=temp;//保存按键值}}else//松手OR无按键动作,此时应该改变扫描线{num_check=0;if(key_flag==1)//按键有效判断{key_flag=0;switch(temp_code)//读取按键号{//P2^0线case 0xEE: num_key=1;break;case 0xDE: num_key=2;break;case 0xBE: num_key=3;break;case 0x7E: num_key=4;break;//P2^1线case 0xED: num_key=5;break;case 0xDD: num_key=6;break;case 0xBD: num_key=7;break;case 0x7D: num_key=8;break;//P2^2线case 0xEB: num_key=9;break;case 0xDB: num_key=10;break;case 0xBB: num_key=11;break;case 0x7B: num_key=12;break;//P2^3线case 0xE7: num_key=13;break;case 0xD7: num_key=14;break;case 0xB7: num_key=15;break;case 0x77: num_key=16;break;}}temp_circle=_crol_(temp_circle,1);//改变扫描线if(temp_circle==0xEF){temp_circle=0xFE;}}return(num_key);//返回按键号}/************************************************************************* 未按键时,扫描线一直变化。
一种实用的单片机按键检测方式
一种实用的单片机按键检测方式《手把手教你学51单片机》第八课讲解按键相关内容的时候,介绍了一种状态检测扫描按键的办法,既可以检测按键,又可以有效消抖。
但是部分同学以前没有接触过类似的思想和方式,所以可能接受起来有点难度,这里我再详细给讲解分析一下,如果教程第八课你已经彻底明白,那么这里可以不用再学习了,如果还模模糊糊,可以再巩固一下。
1、独立按键常用的按键电路有两种形式,独立式按键和矩阵式按键,独立式按键比较简单,它们各自与独立的输入线相连接,如下图所示。
4条输入KeyIn1、KeyIn2、KeyIn3、KeyIn4接到单片机的IO口上,当按键K1按下时,+5V通过电阻R1然后再通过按键K1最终进入GND形成一条通路,那么这条线路的全部电压都加到了R1这个电阻上,KeyIn1这个引脚就和GND等电位,是个低电平。
当松开按键后,线路断开,就不会有电流通过,那么KeyIn1和+5V就应该是等电位,是一个高电平。
我们就可以读取通过KeyIn1这个IO口的高低电平来判断是否有按键按下,独立按键的原理还是很简单的。
2、矩阵按键在某一个系统设计中,如果需要使用很多的按键时,做成独立按键会大量占用IO口,因此我们引入了矩阵按键的设计方式,如下图所示,用了8个IO口实现了16个按键检测的电路。
上图,一共有4组按键,我们只看其中一组,如下图所示。
大家认真看一下,如果KeyOut1输出一个低电平,KeyOut1就相当于是GND,是否相当于4个独立按键呢。
当然这时候KeyOut2、KeyOut3、KeyOut4都必须输出高电平,它们都输出高电平才能保证与它们相连的三路按键不会对这一路产生干扰,大家可以对照两张原理图分析一下。
同理,可以将KeyOut1,KeyOut3,KeyOut4都拉高,把KeyOut2拉低,来读取KEY5到KEY8的值。
关于按键扫描的具体程序部分,大家可以去参考教程,我这里只把一段摘出来给大家讲一下,部分同学对其中一条语句有所疑问。
51独立按键检测原理
51独立按键检测原理
51单片机独立按键检测原理是利用I/O口的输入功能,将按键的一端接地,另一端接I/O口。
在开始时给I/O口赋高电平,然后不断检测I/O口是否变为低电平。
如果按键按下,相当于I/O口通过按键与地相连,变成低电平,程序一旦检测到I/O口变为低电平就说明按键被按下,然后执行相应的指令。
由于使用的是弹性小按键,在按下时会有微观上的机械抖动,反应到电平就是高、低、高、低,抖动的长短与机械特性有关,一般在5~10ms。
所以在检测键盘是否按下时要加上去抖动操作。
如需了解更多关于51单片机独立按键检测原理的信息,建议查阅相关资料
或咨询专业人士。
用单片机中断来扫描键盘的程序
用单片机中断来扫描键盘的程序用单片机中断来扫描键盘的程序/*程序效果:用51单片机的中断来扫描键盘,按下按键,蜂鸣器响,数码管有相应的键值显示,按下E键继电器关,按下C键继电器开。
这与上一程序的功能相同,比上一程序简洁但理解相对困难些。
开发设计:/*/#include<reg52.h> //头文件#include<intrins.h>#define uchar unsigned char //宏定义#define uint unsigned intsbit jdq=P3^5; //位声明,驱动继电器管脚sbit fmq=P3^4; //位声明,驱动蜂鸣器管脚code uchar table[]={0x3f,0x06,0x5b,//数码管显示的数值0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};code uchar key_tab[17]={ //此数组为键盘编码0xed,0x7e,0x7d,0x7b, // 0,1,2,3,0xbe,0xbd,0xbb,0xde, // 4,5,6,7,0xdd,0xdb,0x77,0xb7, // 8,9,a, b,0xee,0xeb,0xd7,0xe7,0xff}; // c,d,e,f,uchar l_key=0x00; //定义变量,存放键值uchar l_keyold=0xff; //作为按键放开否的凭证void readkey(); //扫描键盘,获取键值void display(uchar *lp,uchar lc); //显示子函数void delay(); //延时子函数void main() //主函数{EA=1; //打开总中断EX0=1; //打开外部中断P0=0xf0; //键值高4位为高电平,低4位为低电平while(1){display(&l_key,1); //调用显示子函数if(l_key==14) //是否按下E键,是则关闭继电器jdq=1;if(l_key==12) //是否按下C键,是则打开继电器jdq=0;}}void key_scan() interrupt 0//外部中断0,0的优先级最高{EX0=0; //在读键盘时,关闭外部中断,防止干扰带来的多次中断TMOD&=0xf1; //设置定时器为工作方式1TH0=0x2e; //设置初值,为12毫秒,十进制值为11776TL0=0x00;ET0=1; //开启定时器中断0TR0=1; //启动定时器计数}void time0() interrupt 1 //定时器0的中断函数{TR0=0; //关闭定时器0readkey(); //定时12ms后产生中断,调用此函数,读取键值}void readkey() //扫描键盘子函数{uchar i,j,key; //定义局部变量j=0xfe; //设定初值key=0xff;for(i=0;i<4;i++) // 逐列扫描键盘{P0=j;if((P0&0xf0)!=0xf0) //有按键按下,高4位不可能全为1 {key=P0; //读取P0口的值,推出循环,否则循环下次break;}j=_crol_(j,1); //此函数的功能是:左移循环}if(key==0xff) //如果读取不到P0口的值,如干扰,则返回{l_keyold=0xff;P0=0xf0; // 恢复P0口的值,等待按键按下fmq=1;EX0=1; //在返回前,打开外部中断return;}fmq=0; //有按键按下,打开蜂鸣器if(l_keyold==key) // 检查按键放开否,如果相等表明没有放开{TH0=0x2e; //设置初值TL0=0x00;TR0=1; //继续启动定时器,检查按键放开否return;}TH0=0x2e;TL0=0;TR0=1; //启动定时器l_keyold=key; //获取键值,作为放开否的凭证for(i=0;i<17;i++) //查表获得相应的16进制值存放到l_key中{if(key==key_tab[i]){l_key=i;break;}}//程序运行到此,就表明有键值存放到l_key中,主程序//就可以检测键盘值并作相应的处理}void display(uchar *lp,uchar lc) //显示子函数{uchar i; //定义局部变量P1=0xf8; //点亮第一个数码管P2=0; //P2口为输出值for(i=0;i<lc;i++) //循环显示{P2=table[lp[i]]; //查表获得相应的要显示的数字的数码段delay(); //延时P2=0; //清零,准备显示下一个数值}}void delay() //延时子函数{_nop_();_nop_();_nop_();_nop_();_nop_();}如果程序无法编译,请删除所有前导空白.。
单片机原理及接口技术单片机的开关检测键盘输入与显示的接口设计
单片机原理及接口技术单片机的开关检测键盘输入与显示的接口设计单片机是一种集成了中央处理器、存储器和输入/输出接口的微型电子计算机,其核心是一个集成电路芯片。
它简单、灵活,用于控制电子设备和执行各种任务。
单片机有很多种,其中C51单片机是一种非常常用的型号。
在C51编程中,开关检测、键盘输入和显示是非常常见的接口设计。
接下来,将分别介绍它们的原理和实现方法。
1.开关检测:开关检测是指通过单片机检测开关的状态,以实现对开关的控制。
常见的开关检测方法有两种,一种是使用外部电阻和开关,通过检测电流或电压来判断开关状态;另一种是使用内部电阻和开关,通过检测电阻的值来判断开关状态。
具体实现方法如下:a.外部电阻和开关:检测开关状态的方法是连接一个电阻到开关,并将另一端连接到单片机的输入引脚。
当开关打开时,电阻与单片机输入引脚之间形成一条路径,使得输入引脚接收到高电平信号;当开关关闭时,电阻与单片机输入引脚之间断开,使得输入引脚接收到低电平信号。
b.内部电阻和开关:单片机的引脚通常具有内部上拉或下拉电阻。
当引脚配置为输入模式时,可以选择使能内部上拉或下拉电阻。
通过连接一个开关到引脚,并将另一端连接到电源或地,从而完成开关状态的检测。
当开关打开时,引脚被拉高,输入引脚接收到高电平信号;当开关关闭时,引脚被拉低,输入引脚接收到低电平信号。
2.键盘输入:键盘输入是指通过单片机接收和处理来自键盘的输入信息。
键盘通常是一种矩阵按键结构,可以通过多行多列的方式进行编码。
键盘输入的实现需要通过接口电路将键盘连接到单片机,并在程序中编写相应的扫描算法。
具体实现方法如下:a.键盘连接方式:键盘的行和列线分别连接到单片机的输出和输入引脚上。
行线和列线可以使用独立的引脚,也可以使用矩阵开关编码的方式进行连接。
b.扫描算法:扫描算法是通过逐行扫描和逐列检测的方式来实现键盘输入的。
具体步骤如下:1)将所有行引脚置为高电平,所有列引脚配置为输入模式。
51单片机04矩阵按键逐行扫描,行列扫描代码
矩阵键盘扫描原理方法一:逐行扫描:我们可以通过高四位轮流输出低电平来对矩阵键盘进行逐行扫描,当低四位接收到的数据不全为1的时候,说明有按键按下,然后通过接收到的数据是哪一位为0来判断是哪一个按键被按下。
方法二:行列扫描:我们可以通过高四位全部输出低电平,低四位输出高电平。
当接收到的数据,低四位不全为高电平时,说明有按键按下,然后通过接收的数据值,判断是哪一列有按键按下,然后再反过来,高四位输出高电平,低四位输出低电平,然后根据接收到的高四位的值判断是那一行有按键按下,这样就能够确定是哪一个按键按下了。
//行列扫描#include<reg51.h>#define GPIO_KEY P0#define GPIO_LCD P2unsigned char code a[17]={~0xfc,~0x60,~0xda,~0xf2,~0x66,~0xb6,~0xbe,~0xe0,~0xfe,~0xf6,~0xee,~0x3e,~0x9c,~0x7a,~0xde,~0x8e,~0x00}; //按位取反的用法void delay10ms();void keydown();//要与下面的定义一致void main(){GPIO_LCD=a[16];//初始化数码管while(1){keydown();}}void delay10ms(){unsigned char a,b;for(a=38;a>0;a--)for(b=130;b>0;b--);}void keydown()//检测按下,按下时需要消抖,检测松开,返回按键值//没有按键时保持{unsigned char n=0,key;GPIO_KEY=0x0f;if(GPIO_KEY!=0x0f)//读取按键是否按下{delay10ms(); //延时10ms消抖if(GPIO_KEY!=0x0f)//再次检测按键是否按下{GPIO_KEY=0x0f;//测试列switch(GPIO_KEY){case 0x07: key=0;break;case 0x0b: key=1;break;case 0x0d: key=2;break;case 0x0e: key=3;break;default : GPIO_LCD=a[16];}GPIO_KEY=0xf0;//测试行switch(GPIO_KEY){case 0x70: key=key;break;case 0xb0: key=key+4;break;case 0xd0: key=key+8;break;case 0xe0: key=key+12;break;default : GPIO_LCD=a[16];}GPIO_LCD=a[key];while(++n<5&&GPIO_KEY!=0xf0)//检测按键是否松开 {delay10ms();}}}}//逐行扫描#include<reg51.h>#define GPIO_KEY P0#define GPIO_LED P2unsigned char code a[17]={~0xfc,~0x60,~0xda,~0xf2,~0x66,~0xb6,~0xbe,~0xe0,~0xfe,~0xf6,~0xee,~0x3e,~0x9c,~0x7a,~0xde,~0x8e,~0x00}; //按位取反的用法void delay10ms();void keydown1();//要与下面的定义一致void main(){GPIO_LED=a[16];//初始化数码管while(1){keydown1();}}void keydown1(){unsigned char n=0,key;GPIO_KEY=0x0f;if(GPIO_KEY!=0x0f)//检测按键是否按下{delay10ms();//延时10ms消抖if(GPIO_KEY!=0x0f)//再次检测{GPIO_KEY=0x7f;//高四位轮流输出低电平 if(GPIO_KEY!=0x7f){switch(GPIO_KEY){case 0x77: key=0;goto AA;case 0x7b: key=1;goto AA;case 0x7d: key=2;goto AA;case 0x7e: key=3;goto AA;}}GPIO_KEY=0xbf;{switch(GPIO_KEY){case 0xb7: key=4;goto AA; case 0xbb: key=5;goto AA; case 0xbd: key=6;goto AA; case 0xbe: key=7;goto AA; }}GPIO_KEY=0xdf;if(GPIO_KEY!=0xdf){switch(GPIO_KEY){case 0xd7: key=8;goto AA; case 0xdb: key=9;goto AA; case 0xdd: key=10;goto AA; case 0xde: key=11;goto AA; }}GPIO_KEY=0xef;{switch(GPIO_KEY){case 0xe7: key=12;goto AA;case 0xeb: key=13;goto AA;case 0xed: key=14;goto AA;case 0xee: key=15;goto AA;}}GPIO_LED=a[16];goto BB;AA: GPIO_LED=a[key];BB: GPIO_KEY=0x0f;while(++n<5&&GPIO_KEY!=0x0f) delay10ms();//调用函数别忘记() }}}void delay10ms(){unsigned char a,b;for(a=38;a>0;a--)for(b=130;b>0;b--); }。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#define uchar unsigned char
#define uint unsigned int
unsigned char code aa[16]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,0x7f,0x6f,
while(temp!=0xf0)
{
temp=P1;
switch(temp)
{ case 0xee:num=0;break;
case 0xde:num=1;break;
while(P1!=0xfd);
temp=P1;
while(temp==0xfd)
{
delay(5);
temp=P1;
while(temp==0xfd)
sclk=0;
da=ss&ann;
sclk=1;
ann=ann>>1;
}
st=0;
st=1;
st=0;
}
void main()
{
while(1)
{
P1=0xfe;
while(temp==0xfe)
{delay(5);
temp=P1;
while(temp==0xfe)
{display(aa[num]);break;
case 0xbe:num=2;break;
case 0x7e:num=3;break;
} Leabharlann while(P1!=0xfe);
temp=P1;
{display(aa[num]);
break;
}
break;
}
temp=0xf0;
temp=P1&temp;
while(temp!=0xf0)
{
delay(5);
temp=0xf0;
temp=P1&temp;
case 0xdb:num=9;break;
case 0xbb:num=10;break;
case 0x7b:num=11;break;
}
while(P1!=0xfb);
temp=P1;
while(temp==0xf7)
{display(aa[num]);
break;
}
break;
}
break;}
}
}
break;
}
break;}
}
P1=0xfd;
temp=0xf0;
temp=P1&temp;
temp=0xf0;
temp=P1&temp;
while(temp!=0xf0)
{
temp=P1;
switch(temp)
{ case 0xe7:num=12;break;
case 0xd7:num=13;break;
break;}
}
P1=0xf7;
temp=0xf0;
temp=P1&temp;
while(temp!=0xf0)
{
delay(5);
0x77,0x7c,0x39,0x5e,0x79,0x71};
sbit da=P2^5;//串行数据数输入
sbit st=P2^6;//锁存时钟
sbit sclk=P2^7;//移位时钟
uchar temp,ann;
int num;
void delay(int z)
{
unsigned int t1,y;
{display(aa[num]);
break;
}
break;
}
break;}
}
temp=P1&temp;
while(temp!=0xf0)
{
temp=P1;
switch(temp)
{ case 0xeb:num=8;break;
}
}
P1=0xfb;
temp=0xf0;
temp=P1&temp;
while(temp!=0xf0)
{
delay(5);
temp=0xf0;
temp=P1;
while(temp==0xfb)
{
delay(5);
temp=P1;
while(temp==0xfb)
for(t1=z;t1>0;t1--)
for(y=110;y>0;y--);
}
int i;
void display(uchar ss)
{
da=0;
P0=0x00;
ann=0x80;
da=0;
for(i=0;i<8;i++)
{
case 0xb7:num=14;break;
case 0x77:num=15;break;
}
while(P1!=0xf7);
temp=P1;
while(temp==0xf7)
{
delay(5);
switch(temp)
{ case 0xed:num=4;break;
case 0xdd:num=5;break;
case 0xbd:num=6;break;
case 0x7d:num=7;break;
}
while(temp!=0xf0)
{
delay(5);
temp=0xf0;
temp=P1&temp;
while(temp!=0xf0)
{
temp=P1;