键盘程序

合集下载

全功能按键程序,支持消抖,长按,组合按键,按两次,三次,四次等

全功能按键程序,支持消抖,长按,组合按键,按两次,三次,四次等
#define KEY_PORT_IN (~P1IN & KEY_PORT_VAL) // ndif // #ifdef __KEY_IDPT
// ---------------------------- end of __KEY_IDPT --------------------
// 同时使用独立按键和阵列键盘,需再定义以下函数(修改对应函数中key_pressed())
//INT8U keypad_pressed();
//INT8U check_keypad();
//INT8U get_keypad();
#endif /* #ifdef __KEY_ARRAY */
#define KEY_LOOP_CHECK 1
// 按键状态定义
#define FSM_NOKEY 0 // 按键状态,无按键
#define FSM_KEY_DOWN 1 // 按键状态,按下
#define FSM_KEY_SURE_HOLD 2 // 按键状态,一直按住
#define KEY_REPEAT_TIME 5 // 按键长按后的重复时间
#define KEY_LONGHOLD_TIME 50 // 按键按住多少时间开始算长按
#define KEY_HOLD_MAX 200 // 按键按住算超长按
#ifdef __KEY_USE_TIMER
// 使用定时器支持按键长按,定时(或者循环)消抖,组合按键
typedef struct
{
INT8U key_check_mode; // 是否在循环中检测按键的标志KEY_DELAY_CHECK或KEY_LOOP_CHECK

独立式键盘程序

独立式键盘程序

51单片机:键盘控制程序2009-11-14 16:12键盘控制1.功能说明:用八位指拨开关(DIP)作单片机的输入,控制输出端口连接的八只LED发光二极管。

如若DIP1开关为 ON(向右拨动)则LED1亮,其它开关作用同。

程序:LOOP: MOV A, P3 ; 从P3读入DIP开关值MOV P1, A ; 从P1输出03: JMP LOOP ; 无穷循环04: END ;程序结束2.功能说明:用DIP开关中的低4位作二进制的输入,控制输出端数码管显示器的输出。

程序:01: MOV DPTR,#TABLE ; 存表02: MOV P0, #0FFH ; LED全灭03: LOOP: MOV A, P3 ; 从P3口读入DIP开关值04: ANL A, #0FH ; 高4位清0,取低四位05: ACALL CHANG ; 转成七段显示码06: MOV P0, A ; 从P0输出07: JMP LOOP ; 转移LOOP处,循环08: CHANG: MOVC A,@A+DPTR ; 取码09: RET ; 返回转换显示码子程序10: TABLE: DB 0C0H, 0F9H, 0A4H, 0B0H ;11: DB 99H, 92H, 82H, 0F8H ;12: DB 80H, 90H, 88H, 83H ;13: DB 0C6H, 0A1H, 86H, 8EH ; 显示码表14: END ;程序结束3.功能说明:用两个按键开关K1和K2作输入,K1为电源指示灯开关,K2为工作指示灯开关。

分别控制电源指示灯(P1.0接的LED)和工作指示灯(P1.7接的LED)的接通和关闭。

接通电源时,电源指示灯是在亮的状态。

当按K2时,工作指示灯亮,电源指示灯灭。

按K1时,电源指示灯亮,工作指示灯灭。

程序:01: START: MOV P1, #11111110B ; P1.0所接LED亮02: JB P2.5 , $ ; 判断P2.5(K2键)是否为103: ON: MOV P1, #01111111B ; P1.7所接LED亮04: JNB P2.4, START ; 判断P2.4(K1键)是是否为005: JMP ON ; 未按K1键,则跳至ON06: END ;程序结束4.功能说明:由四个按键开关组成独立式键盘,控制灯左移、右移和闪烁。

基于STM32控制的智能键盘+程序

基于STM32控制的智能键盘+程序

基于STM32控制的智能键盘摘要:本设计选择STM32为核心控制元件,设计了用4个IO 口实现4*4矩阵键盘,使用C 语言进行编程。

矩阵式键盘提高效率进行按键操作管理有效方法,它可以提高系统准确性,有利于资源的节约,降低对操作者本身素质的要求。

关键词:STM32 矩阵键盘 ARM 显示电路1 引言随着21世纪的到来,以前的单个端口连接的按键已经不能满足人们在大型或公共场合的需求。

电子信息行业将是人类社会的高科技行业之一,4*4矩阵键盘设计师当今社会中使用的最广的技术之一。

4*4矩阵式键盘采用STM32为核心,主要由矩阵式键盘电路、显示电路等组成,软件选用C 语言编程。

STM32将检测到的按键信号转换成数字量,显示于数码管上。

该系统灵活性强,易于操作,可靠性高,将会有更广阔的开发前景。

2 总体设计方案该智能键盘电路由ARM 最小系统,矩阵键盘电路和显示电路组成,在常规的4*4矩阵键盘的基础上,通过改进实现了用4个IO 口完成4*4矩阵键盘。

2.1 总体设计框图本电路主要由3大部分电路组成:矩阵键盘电路、ARM 最小系统电路、按键显示电路。

其中ATM 最小系统主要由复位电路和时钟电路组成。

电路复位后数码管显示字符“—” 表示没有按键,显示电路由STM32的PD0—PD7来控制数码管显示是哪个按键按下。

总体设计方框图,如图1所示。

图1总体设计方框图STM32矩阵键盘电路时钟电路复位电路按键显示电路3 智能键盘设计原理分析3.1 STM32复位和时钟电路设计此电路主要是复位电路和时钟电路两部分,其中复位电路采用按键手动复位和上电自动复位组合,电路如图2(右)所示:其中14脚为STM32的复位端。

时钟电路如图2(左)所示:晶振采用的是8MHz和32.786KHz,8MKz分别接STM32的12脚和13脚,32.786KHz分别接STM32的8脚和9脚。

图2STM复位和时钟电路设计3.2 矩阵键盘电路的设计该电路的四个端子分别接STM32的PB12—PB15,电路如图3所示。

4X4矩阵式键盘输入程序

4X4矩阵式键盘输入程序

4*4键盘程序readkeyboard:begin: acall key_onjnz delayajmp readkeyboard delay:acall delay10msacall key_onjnz key_numajmp beginkey_num:acall key_panl a,#0FFhjz beginacall key_ccodepush akey_off:acall key_onjnz key_offpop aretkey_on: mov a,#00horl a,#0fhmov p1,amov a,p1orl a,#0f0hcpl aretkey_p: mov r7,#0efhl_loop:mov a,r7mov p1,amov a,p1orl a,#0f0hmov r6,acpl ajz nextajmp key_cnext: mov a,r7jnb acc.7,errorrl amov r7,aajmp l_looperror:mov a,#00hretkey_c:mov r2,#00hmov r3,#00hmov a,r6mov r5,#04hagain1:jnb acc.0,out1rr ainc r2djnz r5, again1out1: inc r2mov a,r7mov r5,#04hagain2:jnb acc.4,out2rr ainc r3djnz r5,again2out2: inc r3mov a, r2swap aadd a,r3retkey_ccode:push aswap aanl a,#0fhdec arl a ;行号乘4rl amov r7,apop aanl a,#0fhdec aadd a,r7retdelay10ms:anl tmod,#0f0horl tmod,#01hmov th0,#0d8hmov tl0,#0f0hsetb tr0wait:jbc tf0,overajmp waitclr tr0over:ret单片机键盘设计(二)从电路或软件的角度应解决的问题软件消抖:如果按键较多,硬件消抖将无法胜任,常采用软件消抖。

键盘驱动程序程鼐

键盘驱动程序程鼐

EDA技术课程设计任务书班级:姓名:程鼐学号:设计题目:键盘驱动程序一、设计目的进一步巩固理论知识,培养所学理论知识在实际中的应用能力;掌握EDA设计的一般方法;熟悉一种EDA软件,掌握一般EDA系统的调试方法;利用EDA软件设计一个电子技术综合问题,培养VHDL编程、书写技术报告的能力。

为以后进行工程实际问题的研究打下设计基础。

二、设计任务利用外接键盘实现键盘按键的选择,在8位动态七段数码管上实现按键扫描码的显示,在16X16点阵上实现按键字符的显示。

三、设计要求(1)通过对相应文献的收集、分析以及总结,给出相应课题的背景、意义及现状研究分析。

(2)通过课题设计,掌握计算机组成原理的分析方法和设计方法。

(3)学习按要求编写课程设计报告书,能正确阐述设计和实验结果。

(4)学生应抱着严谨认真的态度积极投入到课程设计过程中,认真查阅相应文献以及实现,给出个人分析、设计以及实现。

四、设计时间安排查找相关资料(1天)、设计并绘制系统原理图(2天)、编写VHDL程序(2天)、调试(2天)、编写设计报告(2天)和答辩(1天)。

五、主要参考文献[1] 江国强编著. EDA技术与实用(第三版). 北京:电子工业出版社,2011.[2] 曹昕燕,周凤臣.EDA技术实验与课程设计.北京:清华大学出版社,2006.5[3] 阎石主编.数字电子技术基础.北京:高等教育出版社,2003.[4] Mark Zwolinski. Digital System Design with VHDL.北京:电子工业出版社,2008[5] Alan B. Marcovitz Introduction to logic Design.北京:电子工业出版社,2003指导教师签字:年月日。

8255C键盘显示器程序

8255C键盘显示器程序

8255是Intel公司生产的可编程并行I/O接口芯片,有3个8位并行I/O 口。

具有3个通道3种工作方式的可编程并行接口芯片(40引脚)。

其各口功能可由软件选择,使用灵活,通用性强。

8255可作为单片机与多种外设连接时的中间接口电路。

8255作为主机与外设的连接芯片,必须提供与主机相连的3个总线接口,即数据线、地址线、控制线接口。

同时必须具有与外设连接的接口A、B、C口。

由于8255可编程,所以必须具有逻辑控制部分,因而8255内部结构分为3个部分:与CPU连接部分、与外设连接部分、控制部分。

1)与CPU连接部分根据定义,8255能并行传送8位数据,所以其数据线为8根D0~D7。

由于8255具有3个通道A、B、C,所以只要两根地址线就能寻址A、B、C 口及控制寄存器,故地址线为两根A0~A1。

此外CPU要对8255进行读、写与片选操作,所以控制线为片选、复位、读、写信号。

各信号的引脚编号如下:(1)数据总线DB:编号为D0~D7,用于8255与CPU传送8位数据。

(2)地址总线AB:编号为A0~A1,用于选择A、B、C口与控制寄存器。

(3)控制总线CB:片选信号、复位信号RST、写信号、读信号。

当CPU 要对8255进行读、写操作时,必须先向8255发片选信号选中8255芯片,然后发读信号或写信号对8255进行读或写数据的操作。

2)与外设接口部分根据定义,8255有3个通道A、B、C与外设连接,每个通道又有8根线与外设连接,所以8255可以用24根线与外设连接,若进行开关量控制,则8255可同时控制24路开关。

各通道的引脚编号如下:(1)A口:编号为PA0~PA7,用于8255向外设输入输出8位并行数据。

(2)B口:编号为PB0~PB7,用于8255向外设输入输出8位并行数据。

(3)C口:编号为PC0~PC7,用于8255向外设输入输出8位并行数据,当8255工作于应答I/O方式时,C口用于应答信号的通信。

C8051键盘测试程序

C8051键盘测试程序

#include <c8051f000.h>#include <intrins.h>//----------------------------------------------------------------------------- #define uchar unsigned char#define uint unsigned int#define BAUDRATE#define SYSCLKvoid SYSCLK_Init (void);void delaynus(unsigned int q) ;void PORT_Init (void);void SPI0_Init (void);void LCD_Init(void);void SendSPIByte(unsigned char ch);void delaynms (unsigned int j);void writecom(unsigned char com);void writedata(unsigned char d);void writechar(unsigned char ua);void Write_COM(uchar ins);void lcden(datad);void LCD_set_xy( unsigned char x, unsigned char y );void LCD_write_string(unsigned char n);void lcd_key1(void);void lcd_key2(void);void lcd_key3(void);void lcd_key4(void);void UART0_Init (void);void presskey(void);//----------------------------------------------------------------------------- // Global CONSTANTS//----------------------------------------------------------------------------- sbit S3=P1^0;sbit S4=P1^1;sbit S5=P1^2;sbit S6=P1^3;sbit lcdcs=P3^0;unsigned char comd,kk,sdf,ppca;unsigned char virt_port,v,b,m;unsigned char lcd_data_count;unsigned char *lcdpoint;unsigned char qqq;unsigned char data8;unsigned int i;//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------void main(void){WDTCN = 0xde; // disable watchdog timerWDTCN = 0xad;SYSCLK_Init ();PORT_Init ();UART0_Init() ; // initialize crossbar and GPIOSPI0_Init ();LCD_Init() ;delaynms (20);delaynus (100);LCD_set_xy(0X00,0);delaynus (200);presskey();delaynus (200);LCD_write_string(16);delaynus (200);while(1){if(S3==0){Write_COM(0X01);delaynms (200);LCD_set_xy(0X00,0);delaynus (200);lcd_key1();delaynus (200);LCD_write_string(6);delaynus (200);}else if(S4==0){Write_COM(0X01);delaynms (200);LCD_set_xy(0X00,0);delaynus (200);lcd_key2();delaynus (200);LCD_write_string(6);delaynus (200);}else if(S5==0){Write_COM(0X01);delaynms (200);LCD_set_xy(0X00,0);delaynus (200);lcd_key3();delaynus (200);LCD_write_string(6);delaynus (200);}else if(S6==0){Write_COM(0X01);delaynms (200);LCD_set_xy(0X00,0);delaynus (200);lcd_key4();delaynus (200);LCD_write_string(6);delaynus (200);}else{}}}//-----------------------------------------------------------------------------// Initialization Subroutines//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------// PORT_Init//-----------------------------------------------------------------------------void PORT_Init (void){XBR0 = 0x27; // XBAR0: Initial Reset ValueXBR1 = 0x00; // XBAR1: Initial Reset ValueXBR2 = 0x5c; // XBAR2: Initial Reset ValuePRT0CF = 0x14; // Output configuration for P0PRT1CF = 0x10; // Output configuration for P3PRT3CF = 0x01; // Output configuration for P3}//-----------------------------------------------------------------------------// SYSCLK_Init//-----------------------------------------------------------------------------void SYSCLK_Init (void){OSCXCN = 0x67; // start external oscillator withfor (i=0; i < 256; i++) ; // XTLVLD blanking interval (>1ms)while (!(OSCXCN & 0x80)) ; // Wait for crystal osc. to settleOSCICN = 0x88; // select external oscillator as SYSCLK }//-----------------------------------------------------------------------------// SPI0_Init//-----------------------------------------------------------------------------void SPI0_Init (void){SPI0CFG = 0x07; // data sampled on 1st SCK rising edge SPI0CFG|=0xC0; //CKPOL =1;SPI0CN = 0x03; // Master mode; SPI enabled; flagsSPI0CKR = SYSCLK/2/2000000-1; // SPI clock <= 8MHz (limited by// EEPROM spec.)}//-----------------------------------------------------------------------------// UART0_Init//-----------------------------------------------------------------------------void UART0_Init (void){SCON = 0x50; // SCON: mode 1, 8-bit UART, enable RX TMOD = 0x20; // TMOD: timer 1, mode 2, 8-bit reload TH1 = -(SYSCLK/BAUDRATE/16); // set Timer1 reload value for baudrate TR1 = 1; // start Timer1CKCON |= 0x10; // Timer1 uses SYSCLK as time basePCON |= 0x80; // SMOD = 1TI = 1; // Indicate TX ready}//-----------------------------------------------------------------------------// LCD_Init//-----------------------------------------------------------------------------void LCD_Init(void) //向LCD送命令{// unsigned int xdata x;delaynms(100);datad=0x00;SendSPIByte(datad);delaynms(10);Write_COM(0x30);delaynms(10);Write_COM(0x30);delaynms(10);Write_COM(0x30);delaynms(10) ;Write_COM(0x28);delaynms(100);virt_port=0;SendSPIByte(virt_port);lcden(virt_port);Write_COM(0x01);delaynms(100);Write_COM(0x06);delaynms(10) ;Write_COM(0x0C);delaynms(500) ;}//----------------------------------------------------------------------------- // SendSPIByte//----------------------------------------------------------------------------- void SendSPIByte(unsigned char ch){ lcdcs=1;delaynus(100);SPIF = 0;SPI0DAT = ch;while (SPIF == 0);delaynus(100);lcdcs=0;delaynus(100);_nop_(); // 等待写结束}//----------------------------------------------------------------------------- // lcden//----------------------------------------------------------------------------- void lcden(datad){datad|=0x08;SendSPIByte(datad);datad&=0xf7;SendSPIByte(datad);}//----------------------------------------------------------------------------- // delaynms//----------------------------------------------------------------------------- void delaynms (unsigned int uu){unsigned int oo,ll;for (oo=0;oo<uu;oo++){for(ll=0;ll<1140;ll++);}}//----------------------------------------------------------------------------- // writechar//----------------------------------------------------------------------------- void writechar(unsigned char ua){uint j;uchar t,x;for(j=0;j<500;j++);datad|=0x02;SendSPIByte(datad);datad|=ua&0xf0;SendSPIByte(datad);datad|=0x08;SendSPIByte(datad);for(x=0;x<3;x++);datad&=0xf7;SendSPIByte(datad);for(x=0;x<3;x++);datad&=0x07;delaynus(100);SendSPIByte(virt_port);t|=ua&0x0f;datad|=t<<4;SendSPIByte(datad);for(x=0;x<3;x++);datad|=0x08;SendSPIByte(datad);for(x=0;x<3;x++);datad&=0xf7;SendSPIByte(datad);for(x=0;x<3;x++);datad=0x00;t=0x00;SendSPIByte(datad);}//----------------------------------------------------------------------------- // Write_COM//----------------------------------------------------------------------------- void Write_COM(uchar ins){uchar t;uint j;for(j=0;j<5000;j++); //用延时代替查询virt_port|=ins&0xf0;SendSPIByte(virt_port);//LCDE=1;virt_port|=0x08;SendSPIByte(virt_port);for(i=3;i>0;i--);virt_port&=~0x08;SendSPIByte(virt_port);virt_port&=0x07;SendSPIByte(virt_port);t=ins<<4;virt_port|=t&0xf0;SendSPIByte(virt_port);virt_port|=0x08;SendSPIByte(virt_port);for(i=3;i>0;i--);virt_port&=~0x08;SendSPIByte(virt_port);virt_port=0;SendSPIByte(virt_port);}//-----------------------------------------------------------------------------// LCD_set_xy//-----------------------------------------------------------------------------void LCD_set_xy( unsigned char x, unsigned char y ){unsigned char address;if (y == 0) address = 0x80 + x;elseaddress = 0xc0 + x;Write_COM(address);}//-----------------------------------------------------------------------------// LCD_write_string//-----------------------------------------------------------------------------void LCD_write_string(unsigned char n){unsigned char data1;for(n;n>0;n--){data1=*lcdpoint;writechar(data1);delaynms(100);lcdpoint++;delaynus(10);}}//-----------------------------------------------------------------------------// presskey//-----------------------------------------------------------------------------void presskey(void){unsigned char xdata DDCdata[16]={0x50,0x4c,0x45,0x41,0x53,0x45,0x20,0x50,0x52,0x45,0x53,0x53,0x20,0x4b,0x4 5,0x59};lcdpoint=&DDCdata;}//-----------------------------------------------------------------------------// lcd_key1//-----------------------------------------------------------------------------void lcd_key1(void){unsigned char xdata key1ok[6]={0x53,0x33,0x20,0x4f,0x4b,0x21};lcdpoint=&key1ok;}//-----------------------------------------------------------------------------// lcd_key2//-----------------------------------------------------------------------------void lcd_key2(void){unsigned char xdata key2ok[6]={0x53,0x34,0x20,0x4f,0x4b,0x21};lcdpoint=&key2ok;}//-----------------------------------------------------------------------------// lcd_key3//-----------------------------------------------------------------------------void lcd_key3(void){unsigned char xdata key3ok[6]={0x53,0x35,0x20,0x4f,0x4b,0x21};lcdpoint=&key3ok;}//-----------------------------------------------------------------------------// lcd_key4//-----------------------------------------------------------------------------void lcd_key4(void){unsigned char xdata key4ok[6]={0x53,0x36,0x20,0x4f,0x4b,0x21};lcdpoint=&key4ok;}//-----------------------------------------------------------------------------// delaynus//-----------------------------------------------------------------------------void delaynus(unsigned int q) //N us延时函数{for (i=0;i<q;i++){_nop_();}}本程序已经完全调试通过,欢迎参考。

4×4键盘扫描程序

4×4键盘扫描程序

键盘程序假设P2.0-P2.3为H0-H3,P2.4-P2.7为L0-L3 (列) L0 L1 L2 L3(行) H0 0 1 2 3H1 4 5 6 7H2 8 9 A BH3 C D E F首先,行为P2口的低四位,而列为高四位。

P0口为数码管输出口。

第一种思路就是逐行逐列判断法。

#include<reg51.h>#include<intrins.h>#define uint unsigned int#define uchar unsigned charuchar code table[17] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf};//八段数码管对应0-F值. uchar temp;void Delay_1ms(uint i)//1ms延时{uint x, j;for(j=0;j<i;j++)for(x=0;x<=148;x++);}void delay()//消除按键抖动延时{int i,j;for(i=0; i<=10; i++)for(j=0; j<=2; j++);}uchar Keyscan(void){uchar i,j,row,col;temp=P2&0xf0;for(i=0; i<4; i++){if(!(temp&(0x10<<i)))row=i;}P2=0x0f;temp=P2&0x0f;for(j=0; j<4; j++){if(!(temp&(0x01<<j)))col=j;}return (row+col*4);}void Main(void){uchar Key_Value=16; //读出的键值uchar i=0;while(1){P2 = 0xf0;temp=P2;if(temp != 0xf0){Delay_1ms(80); //按键消抖if(temp != 0xf0){Key_Value = Keyscan();}Delay_1ms(350); //按键消抖}P0 = table[Key_Value];//P0口输出数据到数码管}次读取结果组合起来就可以得到当前按键的特征编码。

按键程序

按键程序
我用C51做的键盘程序,望大家批砖
作者:hexiaoxiao栏目:单片机
我用C51做的键盘程序,望大家批砖
该程序没有被仿真过,可能有一些错误.不过编译是;intrins.h>
#include<reg51.h>
#define uCHAR unsigned CHAR
if(state!=0x0F) //&Oacute;&ETH;&frac14;ü°&acute;&Iuml;&Acirc;
{
SWITCH(state)
{
case 0x0E:
key=(0x4-i)*0x4+0x1;
break;
case 0x0D:
key=(0x4-i)*0x4+0x2;
break;
case 0x0B:
{
delayms();
if((P0&0x0f)!=0x0f) //确认有键按下
{
for(i=0;i<4;i++) //扫描4行
{
P0=m; //从P0.4=0(第一行)开始扫描
if(KEY_A==0) //列1有效
{
h=h+1; //算出列1键盘值
flag0=1;
while(KEY_A==0) //等待按键松开
11楼:>>参与讨论
作者:fushaobing于2005-4-15 17:32:00发布:
--------------------------------------------------------------------------------
TO xwj:
你的意思是不是这样:把键盘扫描放在定时中断子程序中(定时周期约10ms),可以用两次中断的时间间隔来去抖动,可以引入“键龄”的概念来实现连击的处理(在中断中使键龄减1)。例如,如果设“键龄=25”,则每25*10=250ms操作一次按键。

矩阵键盘源程序(详细)

矩阵键盘源程序(详细)
}
}
//延时子程序
//12MHz晶振,AT89S52 : 1ms
//测试结果:n=1, 1.015ms; n=10, 10.006ms;
void delay(unsigint i,j;
for(i=0;i<n;i++)
{
for(j=0;j<123;j++)
//NumBuffer[3]=(((KEY_PORT & 0xF0)^0xF0)>>4);
NumBuffer[2]=(((KEY_PORT & 0xF0))>>4);
switch(keycode)
{
case 0x7E: keycode=0; break;
case 0xBE: keycode=1; break;
{
case 0: //有按键按下吗?
if(keypad_0==keypad_0_DOWN)
{
mKey0SwapTask=1;
mKey0Value=kbdKeyRead(); //读键值
}
break;
case 0xDE: keycode=2; break;
case 0xEE: keycode=3; break;
case 0x7D: keycode=4; break;
case 0xBD: keycode=5; break;
case 0xDD: keycode=6; break;
NumDisplayIndex=0;
}
}
//按键矩阵扫描子程序
void kbdScan(void)
{
#define keypad_0 kbdIsKeyDown() //定义端口

《键盘程序设计》课件

《键盘程序设计》课件

键盘性能调试
01
02
03
04
调整按键响应速度
根据个人使用习惯,调整按键 的响应速度。
调整按键触发力度
调整按键的触发力度,使其更 适合个人手感。
调整背光亮度
如果键盘带有背光,调整背光 亮度以满足不同使用场景。
调整音量调节
如果键盘带有音量调节功能, 确保其能正常工作。
键盘故障排除
检查连接线
确保键盘连接线无破损、无松动,尝试更换 连接线排除故障。
按键开关设计
每个按键对应一个开关, 通过电路连接实现按键触 发。
接口设计
提供USB、PS/2等接口, 方便与电脑连接。
键盘材料选择
按键材料
选择手感舒适、耐用、不易磨损的材料,如硅胶或橡胶。
外壳材料
选择轻便、坚固、耐用的材料,如ABS塑料或金属。
线材选择
选择质量好、耐用的线材,确保键盘与电脑之间的连接稳定可靠 。
重置键盘默认设置
检查键盘的驱动程序是否为最新版本,必要 时更新驱动程序。
软件驱动更新
尝试将键盘恢复出厂设置,看是否能解决问 题。
专业维修
如以上方法均无效,可寻求专业维修人员的 帮助。
05
键盘设计案例分析
机械键盘设计案例
总结词
机械键盘是采用机械轴作为开关的键盘,具有手感好、寿命长的特点。
详细描述
机械键盘的按键下方通常有一个独立的机械轴,当按下按键时,机械轴会触发开关,产生相应的信号。由于每个 按键都有独立的机械轴,因此机械键盘的手感通常比薄膜键盘更加出色,按键的响应也更加迅速。此外,由于机 械键盘的机械轴结构复杂,因此其寿命通常比薄膜键盘更长。
03
键盘软件编程
键盘扫描程序编写

SMbus键盘通行程序

SMbus键盘通行程序
SI=0;
break;
case SMB_MRDACK:
if(k>=3)
AA=0;
REG[k-1]=SMB0DAT;
SI=0;
break;
case SMB_MRDBNACK://数据字节收到,nack已发出
REG[k-1]=SMB0DAT;
#define AD_SystemReg 0x00 //键盘控制芯片系统寄存器地址
#define AD_KEY 0x01 //键值寄存器地址
#define AD_RepeatCnt 0x02 //连击次数寄存器
#define AD_Functionkey 0x03 //功能键寄存器
STA=1;
SI=0;
break;
//case SMB_MTDBNACK:
// STO=1;
// STA=1;
// SI=0;
// break;
case SMB_MRADDACK://从地址+R已发出,等待接收数据
// AA=0;//收到字节后发送nack
STO=1;
SM_BUSY=0;
AA=1;
SI=0;
break;
default:
STO=1;
SM_BUSY=0;
break;
}
k++;
}
SM_BUSY=0;
SI=0;
SLAW=CHIP|WRITE;
SLAR=CHIP|READ;
EA=1; //开中断
while(1);
// SLA_READ();
}
/////////////////////////函数定义区/////////////////////////////////////////

键盘测试程序

键盘测试程序

[cpp]view plaincopyprint?1. #include<reg52.h>2. #define uchar unsigned char3. #define uint unsigned int4. s bit dula=P3^0;5. s bit wela=P3^1;6. #define keyport (P1)7. #define keystate0 0 //按键确认状态8. #define keystate1 1 //按键无动作状态9. c har keystate=1; //按键状态初始化为按键无动作状态10. uchar keynum=0;11. void delayms(uint x) //1ms12. {13. uint y,z;14. for(y=x;y>0;y--)15. for(z=111;z>0;z--);16. }17. uchar code table[]={ //共阳数码管18. 0xc0,0xf9,0xa4,0xb0,19. 0x99,0x92,0x82,0xf8,20. 0x80,0x90,0x88,0x83,21. 0xc6,0xa1,0x86,0x8e};22. void smg()23. {24. dula=0;25. wela=0;26. P2=0x01;27. wela=1;28. wela=0;29. P2=table[keynum];30. dula=1;31. dula=0;32. delayms(1);33.34. P2=0x02;36. wela=0;37. P2=table[keynum];38. dula=1;39. dula=0;40. delayms(1);41.42. P2=0x04;43. wela=1;44. wela=0;45. P2=table[keynum];46. dula=1;47. dula=0;48. delayms(1);49.50. P2=0x08;51. wela=1;52. wela=0;53. P2=table[keynum];54. dula=1;55. dula=0;56. delayms(1);57.58. P2=0x10;59. wela=1;60. wela=0;61. P2=table[keynum];62. dula=1;63. dula=0;64. delayms(1);65.66. P2=0x20;67. wela=1;68. wela=0;69. P2=table[keynum];71. dula=0;72. delayms(1);73.74. P2=0x40;75. wela=1;76. wela=0;77. P2=table[keynum];78. dula=1;79. dula=0;80. delayms(1);81.82. P2=0x80;83. wela=1;84. wela=0;85. P2=table[keynum];86. dula=1;87. dula=0;88. delayms(1);89. }90. void keyscan()91. {92. uchar temp1,temp2,column,row;93. switch(keystate)94. {95. case keystate0: //keystate0,按键按下确认状态,下一状态为keystate1(按键无动作状态)96. keyport=0x0f;97. temp1=keyport;98. keyport=0xf0;99. temp2=keyport;100. if((temp1|temp2)!=0xff)101. {102. temp1|=temp2;103. if(!(temp1&0x80))104. row=3;105. else106. if(!(temp1&0x40))107. row=2;108. else109. if(!(temp1&0x20))110. row=1;111. else112. if(!(temp1&0x10))113. row=0;114. if(!(temp1&0x08))115. column=3;116. else117. if(!(temp1&0x04))118. column=2;119. else120. if(!(temp1&0x02))121. column=1;122. else123. if(!(temp1&0x01))124. column=0;125. keynum=column*4+row;126. while(!(keyport==0x0f|keyport==0xf0));127. keystate=keystate1;128. break;129.130. }131. else132. keystate=keystate1;133. break;134. case keystate1: //keystate1,按键无动作状态,下一状态为keystate0(按键无动作状态)135. keyport=0x0f;136. temp1=keyport;137. keyport=0xf0;138. temp2=keyport; 139. if((temp1|temp2)!=0xff) 140. {141. keystate=keystate0; 142. }143. else144. keystate=keystate1; 145. break;146. }147. }148. void main()149. {150. while(1)151. {152. keyscan();153. smg();154. }155. }。

键盘工作流程

键盘工作流程

键盘工作流程下载温馨提示:该文档是我店铺精心编制而成,希望大家下载以后,能够帮助大家解决实际的问题。

文档下载后可定制随意修改,请根据实际需要进行相应的调整和使用,谢谢!并且,本店铺为大家提供各种各样类型的实用资料,如教育随笔、日记赏析、句子摘抄、古诗大全、经典美文、话题作文、工作总结、词语解析、文案摘录、其他资料等等,如想了解不同资料格式和写法,敬请关注!Download tips: This document is carefully compiled by theeditor. I hope that after you download them,they can help yousolve practical problems. The document can be customized andmodified after downloading,please adjust and use it according toactual needs, thank you!In addition, our shop provides you with various types ofpractical materials,such as educational essays, diaryappreciation,sentence excerpts,ancient poems,classic articles,topic composition,work summary,word parsing,copy excerpts,other materials and so on,want to know different data formats andwriting methods,please pay attention!键盘工作流程一、前期准备阶段。

在开展键盘工作之前,要做好充分的准备。

1. 明确需求:首先要清楚了解使用键盘的目的和具体需求,比如是用于办公打字、游戏竞技还是其他特定用途。

USB键盘驱动程序

USB键盘驱动程序

USB键盘驱动程序什么是USB键盘驱动程序?USB键盘驱动程序是指用于控制和操作连接到计算机的USB键盘的软件。

它可以让计算机识别和响应键盘上的按键操作,并将其转换为文本或控制命令等计算机可以理解的语言。

USB键盘驱动程序的工作原理USB键盘驱动程序的工作原理是与USB控制器通信,将USB键盘发送的数据转换成可识别和处理的格式。

当用户在键盘上按下一个按键时,键盘会发送一个信号到USB控制器,控制器将该信号传递给USB键盘驱动程序。

驱动程序解析该信号并将其转换为相应的字符代码或控制命令,并将其传输到计算机操作系统的键盘输入队列中。

USB键盘驱动程序的类型USB键盘驱动程序通常分为两种类型:内核驱动程序和用户空间驱动程序。

内核驱动程序内核驱动程序运行在计算机的内核空间中,可以直接访问硬件设备和操作系统资源。

它通常具有较高的性能和稳定性,并具有良好的兼容性。

内核驱动程序可以提供对USB键盘的完整支持,包括高级功能和按键映射等。

用户空间驱动程序用户空间驱动程序运行在计算机的用户空间中,它通过调用内核空间提供的API来与USB键盘进行通信。

用户空间驱动程序通常具有较高的灵活性和可定制性,但对于一些高级功能和安全性较高的应用程序可能不够稳定和可靠。

USB键盘驱动程序的安装和卸载USB键盘驱动程序通常随着操作系统安装而一同安装。

可以通过设备管理器来检查并安装或更新键盘驱动程序。

对于需要卸载键盘驱动程序的情况,可以通过设备管理器或控制面板中的程序和功能来卸载。

USB键盘驱动程序的更新和维护USB键盘驱动程序通常需要定期更新以适应新的操作系统版本和硬件设备。

更新键盘驱动程序可以解决一些已知的问题,并提高键盘的性能和稳定性。

可以通过设备管理器或厂商官方网站下载并更新键盘驱动程序。

在日常使用过程中,USB键盘驱动程序也需要进行维护和保养。

可以定期清除键盘上的灰尘和污垢,检查键盘连接处的电缆和接口,并避免键盘接触水和阳光直射等因素。

经典的矩阵键盘扫描程序

经典的矩阵键盘扫描程序

经典的矩阵键盘扫描程序查找哪个按键被按下的方法为:一个一个地查找。

先第一行输出0,检查列线是否非全高;否则第二行输出0,检查列线是否非全高;否则第三行输出0,检查列线是否非全高;如果某行输出0时,查到列线非全高,则该行有按键按下;根据第几行线输出0与第几列线读入为0,即可判断在具体什么位置的按键按下。

下面是具体程序:void Check_Key(void){unsigned char row,col,tmp1,tmp2;tmp1 = 0x10; //tmp1用来设置P1口的输出,取反后使P1.4~P1.7中有一个为0for(row=0;row<4;row++) // 行检测{P1 = 0x0f; // 先将p1.4~P1.7置高P1 =~tmp1; // 使P1.4~p1.7中有一个为0tmp1*=2; // tmp1左移一位if ((P1 & 0x0f) < 0x0f) // 检测P1.0~P1.3中是否有一位为0,只要有,则说明此行有键按下,进入列检测{tmp2 = 0x01; // tmp2用于检测出哪一列为0for(col =0;col<4;col++) // 列检测{if((P1 & tmp2)==0x00) // 该列如果为低电平则可以判定为该列{key_val =key_Map[ row*4 +col ]; // 获取键值,识别按键;key_Map为按键的定义表return; // 退出循环}tmp2*=2; // tmp2左移一位}}}} //结束这是一种比较经典的矩阵键盘识别方法,实现起来较为简单,程序短小精炼。

4*4矩阵键盘扫描程序/*设置行线为输入线,列线为输出线*/uchar KeyScan(); //按键扫描子程序void delay10ms(); //延时程序uchar key_free(); //等待按键释放程序void key_deal(); //键处理程序//主程序void main(){while(1){KeyScan();key_free();key_deal();}}//按键扫描子程序uchar KyeScan(){unsigned char key,temp;P1=0xF0;if(P1&0xF0!=0xF0){delay10ms(); //延时去抖动if(P1&0xF0!=0xF0){P1=0xFE; //扫描第一列temp=P1;temp=temp&0xF0;if(temp!=0xF0) //如果本列有键按下{switch(temp){case 0xE0: //第一行有键按下key=1;break;case 0xD0: //第二行有键按下key=4;break;case 0xB0: //第三行有键按下key=8;break;case 0x70: //第四行有键按下key=12;break;}}P1=0xFD; //扫描第二列temp=P1;temp&=0xF0;if(temp!=0xF0){switch(temp){case 0xE0: //第一行有键按下key=1;break;case 0xD0: //第二行有键按下key=5;break;case 0xB0: //第三行有键按下key=9;break;case 0x70: //第四行有键按下key=13;break;}}P1=0xFb; //扫描第三列temp=P1;temp&=0xF0;if(temp!=0xF0){switch(temp){case 0xE0: //第一行有键按下key=2;break;case 0xD0: //第二行有键按下key=6;break;case 0xB0: //第三行有键按下key=10;break;case 0x70: //第四行有键按下key=14;break;}}P1=0xF7; //扫描第四列temp=P1;temp&=0xF0;if(temp!=0xF0){switch(temp){case 0xE0: //第一行有键按下key=3;break;case 0xD0: //第二行有键按下key=7;break;case 0xB0: //第三行有键按下key=11;break;case 0x70: //第四行有键按下key=15;break;}}}return(key);}}//延时程序void delay10ms(){unsigned char i,j;for(i=0;i<10;b++)for(j=0;j<120;j++)//延时1ms{}}//等待按键释放程序uchar key_free(){key=key_scan(); //取扫描到的键值P1=0xF0;//置行线全为高电平,列线全为低电平wheile(P1&0xF0!=0xF0) //如果仍有键按下{}return(key);//返回键值}51单片机矩阵键盘扫描、数码管显示键值实验/***********************************************程序名称:矩阵键盘扫描显示键值简要说明:P1口接矩阵键盘:低四位列,高四位行使用共阳型数码管:P0口输出数码管段码,P2口输出数码管位码编写:***********************************************/#include <AT89x52.h>#define uchar unsigned char;uchar key_val=0; //定义键值,初始默认为0uchar code TAB[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xC6,0xa1,0x86,0x8 e}; //0~F共阳数码管显示段码/*****按键扫描*****/void Check_Key(void){unsigned char row,col,tmp1,tmp2;tmp1 = 0x10; //tmp1用来设置P1口的输出,取反后使P1.4~P1.7中有一个为0for(row=0;row<4;row++) // 行检测{P1 = 0x0f; // 先将p1.4~P1.7置高P1 =~tmp1; // 使P1.4~p1.7中有一个为0tmp1*=2; // tmp1左移一位if ((P1 & 0x0f) < 0x0f) // 检测P1.0~P1.3中是否有一位为0,只要有,则说明此行有键按下,进入列检测{tmp2 = 0x01; // tmp2用于检测出哪一列为0for(col =0;col<4;col++) // 列检测{if((P1 & tmp2)==0x00) // 该列如果为低电平则可以判定为该列{key_val = row*4 +col; // 获取键值,识别按键return; // 退出循环}tmp2*=2; // tmp2左移一位}}}}/*****主函数,显示键值*****/void main(){P2=0x00; //位码,这里全部置低,点亮8位数码管(见视频效果)while(1){Check_Key();P0=TAB[key_val]; //显示}}实验7 矩阵按键识别技术矩阵按键部分由16个轻触按键按照4行4列排列,连接到JP50端口。

韦东山单片机独立按键程序

韦东山单片机独立按键程序

韦东山单片机独立按键程序
按键分类与输入原理按键按照结构原理科分为两类,一类是触
点式开关按键,如机械式开关、导电橡胶式开关灯;另一类是无触点式开关按键,如电气式按键,磁感应按键等。

前者造价低,后者寿命长。

目前,微机系统中最常见的是触点式开关按键。

在单片机应用系统中,除了复位按键有专门的复位电路及专一的复位功能外,其他按键都是以开关状态来设置控制功能或输入数据的。

当所设置的功能键或数字键按下时,计算机应用系统应完成该按键所设定的功能,键信息输入时与软件结构密切相关的过程。

对于一组
键或一个键盘,总有一个接口电路与CPU相连。

CPU可以采用查询或中断方式了解有无将按键输入,并检查是哪一个按键按下,将该键号送人累加器,然后通过跳转指令转入执行该键的功能程序,执行完成后再返回主程序。

按键结构与特点微机键盘通常使用机械触点式按键开关,其主
要功能式把机械上的通断转换为电气上的逻辑关系。

也就是说,它能提供标准的TTL逻辑电平,以便于通用数字系统的逻辑电平相容。

机械式按键再按下或释放时,由于机械弹性作用的影响,通常伴随有一定的时间触点机械抖动,然后其触点才稳定下来。

抖动时间的长短与开关的机械特性有关,一般为5-10ms。

在触点抖动期间检测按键的
通与断,可能导致判断出错,即按键一次按下或释放错误的被认为是多次操作,这种情况是不允许出现的。

为了克服你、按键触点机械抖动所致的检测误判,必须采取消抖措施。

按键较少时,可采用硬件消
抖;按键较多式,采用软件消抖。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

51单片机键盘程序
键盘是由若干按钮组成的开关矩阵,它是单片机系统中最常用的输入设备,用户能通过键
盘向计算机输入指令、地址和数据。

一般单片机系统中采和非编码键盘,非编码键盘是由
软件来识别键盘上的闭合键,它具有结构简单,使用灵活等特点,因此被广泛应用于单片
机系统。

按钮开关的抖动问题
组成键盘的按钮有触点式和非触点式两种,单片机中应用的一般是由机械触点组成的。


下图中,当开
<键盘结构图>
关S未被按下时,P1。

0输入为高电平,S闭合后,P1。

0输入为低电平。

由于按钮是机械触点,当机械触点断开、闭合时,会有抖动动,P1。

0输入端的波形如图2所示。

这种抖
动对于人来说是感觉不到的,但对计算机来说,则是完全能感应到的,因为计算机处理的
速度是在微秒级,而机械抖动的时间至少是毫秒级,对计算机而言,这已是一个“漫长”的
时间了。

前面我们讲到中断时曾有个问题,就是说按钮有时灵,有时不灵,其实就是这个
原因,你只按了一次按钮,可是计算机却已执行了多次中断的过程,如果执行的次数正好
是奇数次,那么结果正如你所料,如果执行的次数是偶数次,那就不对了。

为使CPU能正确地读出P1口的状态,对每一次按钮只作一次响应,就必须考虑如何去除
抖动,常用的去抖动的办法有两种:硬件办法和软件办法。

单片机中常用软件法,因此,
对于硬件办法我们不介绍。

软件法其实很简单,就是在单片机获得P1。

0口为低的信息后,
不是立即认定S1已被按下,而是延时10毫秒或更长一些时间后再次检测P1。

0口,如果
仍为低,说明S1的确按下了,这实际上是避开了按钮按下时的抖动时间。

而在检测到按
钮释放后(P1。

0为高)再延时5-10个毫秒,消除后沿的抖动,然后再对键值处理。

不过
一般情况下,我们常常不对按钮释放的后沿进行处理,实践证明,也能满足一定的要求。

当然,实际应用中,对按钮的要求也是千差万别,要根据不一样的需要来编制处理程序,
但以上是消除键抖动的原则。

键盘与单片机的连接
1、通过1/0口连接。

将每个按钮的一端接到单片机的I/O口,另一端接地,这是最简单的办法,如图3所示是实验板上按钮的接法,四个按钮分别接到P3.2 、P3.3、P3.4和P3.5。

对于这种键各程序能采用持续查询的办法,功能就是:检测是否有键闭合,如有键闭合,
则去除键抖动,判断键号并转入对应的键处理。

下面给出一个例程。

其功能很简单,四个
键定义如下:
P3.2:开始,按此键则灯开始流动(由上而下)
P3.3:停止,按此键则停止流动,所有灯为暗
P3.4:上,按此键则灯由上向下流动
P3.5:下,按此键则灯由下向上流动
UpDown EQU 00H ;上下行标志StartEnd EQU 01H ;起动及停止标志LAMPCODE EQU 21H ;存放流动的数据代码ORG 0000H
AJMP MAIN
ORG 30H
MAIN:
MOV SP,#5FH
MOV P1,#0FFH
CLR UpDown ;启动时处于向上的状态CLR StartEnd ;启动时处于停止状态
MOV LAMPCODE,#0FEH ;单灯流动的代码LOOP:
ACALL KEY ;调用键盘程序
JNB F0,LNEXT ;如果无键按下,则继续ACALL KEYPROC ;不然调用键盘处理程序LNEXT:
ACALL LAMP ;调用灯显示程序
AJMP LOOP ;反复循环,主程序到此结束
DELAY:
MOV R7,#100
D1: MOV R6,#100
DJNZ R6,$
DJNZ R7,D1
RET
;----------------------------------------延时程序,键盘处理中调用
KEYPROC:
MOV A,B ;从B寄存器中获取键值
JB ACC.2,KeyStart ;分析键的代码,某位被按下,则该位为1(因为在键盘程序中已取反)JB ACC.3,KeyOver
JB ACC.4,KeyUp
JB ACC.5,KeyDown
AJMP KEY_RET
KeyStart:
SETB StartEnd ;第一个键按下后的处理
AJMP KEY_RET
KeyOver:
CLR StartEnd ;第二个键按下后的处理
AJMP KEY_RET
KeyUp: SETB UpDown ;第三个键按下后的处理AJMP KEY_RET
KeyDown:
CLR UpDown ;第四个键按下后的处理
KEY_RET:RET
KEY:
CLR F0 ;清F0,表示无键按下。

ORL P3,#00111100B ;将P3口的接有键的四位置1 MOV A,P3 ;取P3的值
ORL A,#11000011B ;将其余4位置1
CPL A ;取反
JZ K_RET ;如果为0则一定无键按下
ACALL DELAY ;不然延时去键抖
ORL P3,#00111100B
MOV A,P3
ORL A,#11000011B
CPL A
JZ K_RET
MOV B,A ;确实有键按下,将键值存入B中
SETB F0 ;设置有键按下的标志
K_RET:
ORL P3,#00111100B ;此处循环等待键的释放
MOV A,P3
ORL A,#11000011B
CPL A
JZ K_RET1 ;直到读取的数据取反后为0说明键释放了,才从键盘处理程序中返回AJMP K_RET
K_RET1:
RET
D500MS: ;流水灯的延迟时间
PUSH PSW
SETB RS0
MOV R7,#200
D51: MOV R6,#250
D52: NOP
NOP
NOP
NOP
DJNZ R6,D52
DJNZ R7,D51
POP PSW
RET
LAMP:
JB StartEnd,LampStart ;如果StartEnd=1,则启动MOV P1,#0FFH
AJMP LAMPRET ;不然关闭所有显示,返回
LampStart:
JB UpDown,LAMPUP ;如果UpDown=1,则向上流动MOV A,LAMPCODE
RL A ;实际就是左移位而已
MOV LAMPCODE,A
MOV P1,A
LCALL D500MS
AJMP LAMPRET
LAMPUP:
MOV A,LAMPCODE
RR A ;向下流动实际就是右移
MOV LAMPCODE,A
MOV P1,A
LCALL D500MS
LAMPRET:
RET
END
以上程序功能很简单,但它演示了一个单片机键盘处理程序的基本思路,程序本身很简单,也不很实用,实际工作中还会有好多要考虑的因素,比如主循环每次都调用灯的循环程序,会造成按钮反应“迟钝”,而如果一直按着键不放,则灯不会再流动,一直要到松开手为止,等等,大家能仔细考虑一下这些问题,再想想有什么好的解决办法。

2、采用中断方式:如图4所示。

各个按钮都接到一个与非上,当有任何一个按钮按下时,都会使与门输出为低电平,从而引起单片机的中断,它的好处是不用在主程序中持续地循
环查询,如果有键按下,单片机再去做对应的处理。

相关文档
最新文档