单片机屏幕显示及键盘
- 格式:pdf
- 大小:78.67 KB
- 文档页数:4
基于51单片机的USB键盘设计与实现
一、背景介绍
USB键盘是近些年来随着计算机科技发展而出现的一种新型输入设备。
它采用USB接口,是电脑设备接口标准由PS/2接口更换而来的,可以满
足现代电脑日益增长的输入需要。
现代联想主板,微星主板都采用了USB
接口出现,同时USB接口也可以有效投放鼠标、USB外置设备等。
是一种
非常有效的替代方案。
本文的主要目的是基于51单片机的USB键盘设计与实现,在此基础上,可以得出一个具有良好性能的USB键盘,它将成为计算机用户所不可
或缺的输入设备之一
二、功能要求
B键盘的硬件部分,采用51单片机作为核心,屏幕模块和按键
模块作为主要的输入设备。
2.支持USB1.1/2.0标准,能够兼容主流的主板及不同接口的设备,
实现多种输入功能并支持多种操作系统。
3.按键部分及其他硬件设计,需考虑到键盘的灵敏度、机械结构的耐
用性、按键的设计及密度等多方面因素,以提高使用者的操作方便性。
4.软件设计,在51单片机上实现USB键盘的驱动程序,在根据不同
接口的主板及设备对应的协议、功能及数据格式等配置相应的控制程序,
以保证其能够实现对应的输入功能。
三、硬件设计
1.主控:采用51单片机作为主控。
51下面是51单片机使用4×4矩阵键盘的汇编程序,并在数码管的最后一位显示一个字符:```ORG 0 ;程序从地址0开始MOV P1,#0FFH ;P1口设置为输入口MOV P0,#0FH ;P0口设置为输出口LOOP:MOV A,P1 ;读取P1口的值CJNE A,#0FFH,KEY_PRESSED ;判断是否有按键按下SJMP LOOP ;如果没有按键按下,继续循环KEY_PRESSED:MOV R0,A ;保存按键的值CLR P0.0 ;选定行0MOV A,P1ANL A,#0F0H ;按位与运算,保留列位的值CJNE A,#0F0H,COL0 ;判断是否有按键按下在第0列MOV A,#'0' ;如果在第0列按下按键,则A的值为0JMP DISP ;跳转到显示程序COL0:CLR P0.1 ;选定行1MOV A,P1ANL A,#0F0HCJNE A,#0E0H,COL1 ;判断是否有按键按下在第1列MOV A,#'1' ;如果在第1列按下按键,则A的值为1JMP DISP ;跳转到显示程序COL1:CLR P0.2 ;选定行2MOV A,P1ANL A,#0F0HCJNE A,#0D0H,COL2 ;判断是否有按键按下在第2列MOV A,#'2' ;如果在第2列按下按键,则A的值为2JMP DISP ;跳转到显示程序COL2:CLR P0.3 ;选定行3MOV A,P1ANL A,#0F0HCJNE A,#0B0H,COL3 ;判断是否有按键按下在第3列MOV A,#'3' ;如果在第3列按下按键,则A的值为3JMP DISP ;跳转到显示程序COL3:CLR P0.4 ;选定行4MOV A,P1ANL A,#0F0H4MOV A,#'4' ;如果在第4列按下按键,则A的值为4 JMP DISP ;跳转到显示程序COL4:CLR P0.5 ;选定行5MOV A,P1ANL A,#0F0HCJNE A,#0B0H,COL5 ;判断是否有按键按下在第5列 MOV A,#'5' ;如果在第5列按下按键,则A的值为5 JMP DISP ;跳转到显示程序COL5:CLR P0.6 ;选定行6MOV A,P1ANL A,#0F0HCJNE A,#0D0H,COL6 ;判断是否有按键按下在第6列 MOV A,#'6' ;如果在第6列按下按键,则A的值为6 JMP DISP ;跳转到显示程序COL6:CLR P0.7 ;选定行7MOV A,P1ANL A,#0F0HCJNE A,#0E0H,COL7 ;判断是否有按键按下在第7列 MOV A,#'7' ;如果在第7列按下按键,则A的值为7 JMP DISP ;跳转到显示程序COL7:MOV A,#00HJMP EXIT ;如果没有按下任何键,退出程序DISP: ;数码管显示程序MOV R1,#100B ;延时计数器初始化MOV P2,A ;把按键值存入P2口MOV A,#07HANL A,P0 ;从P0口读取选定的行值MOV P0,A ;根据选定的行值输出相应的值ACALL DELAY ;调用延时程序MOV P0,#0FH ;关闭所有行DJNZ R1,$ ;当延时计数器不为0时,继续延时MOV A,#0FHMOV P0,A ;清除所有显示JMP LOOP ;跳转回主程序EXIT:MOV P2.7,1 ;在数码管的最后一位显示字符1SJMP EXIT ;无限循环DELAY: ;延时程序MOV R2,#75DMOV R3,#200D DELAY3:DJNZ R3,$DJNZ R2,DELAY2 RET```。
目录1 课程设计概述和要求 (1)1.1 课程设计要求与任务 (2)1.2 课程设计思路 (2)1.3 课程设计需要配置的环境 (3)2 系统设计 (3)2.1 设计框图 (3)2.2 元件解析 (3)2.2.1 LCD12864芯片……………………………………………………………42.2.2 AT89C51芯片 (5)2.2.3 其他部件 (6)2.2.4 电路分析 (7)3 软件设计 (12)3.1 程序流程图 (12)3.2 程序代码 (12)4 系统的仿真与调试 (13)4.1 硬件调试 (13)4.2 软件调试 (14)4.3 软硬件调试 (14)5 总结 (14)附录1:程序代码附录2:12864LCD显示计算器键盘按键实验Proteus仿真图1 课程设计概述和要求1.1 课程设计任务与要求设计任务:利用AT89C51单片机结合12864LCD显示器设计计算器键盘按键。
设计要求1:本设计实现一个12864LCD显示12864LCD显示器设计计算器键盘按键2.利用AT89C51控制整个电路来实现. 显示12864LCD显示器设计计算器键盘按键,系统主要包括硬件和软件两部分。
重点就是各部分硬件的连接设计以及程序的编写。
本章讲述的就是系统硬件的设计,其中包括各模块的器件选择和电路设计。
将计算器按键上的信息传送至AT89C51主芯片之中,利用P2端口使之显示于12864LCD液晶显示屏上。
1.2 课程设计目的思路1、先把与题目有关的芯片资料找到,熟悉一下芯片资料2、把此程序的电路图看懂,了解一下它的实现原理,以及实现的功能。
3、分析一下此程序的各部分的功能,各零件的工作原理。
4、对程序进行调试,分析调试结果,观察并得出结论。
1.3 课程设计需要配置的环境1、一台主机,一台显示器2、Keil uVision3/Keil uVision4 应用程序软件3、ISIS 7 Professional 仿真软件4、老师交给的仿真电路图,及案例5、纸张,以及一些参考资料2 系统设计2.1.设计框图框图设计是为了能够从整体上把握系统的各个大的模块以及各个模块之间的联系。
基于单片机的LED大屏幕显示系统设计引言:随着科技的不断发展,LED大屏幕在现代生活中得到越来越广泛的应用。
本文将介绍一种基于单片机的LED大屏幕显示系统的设计方案。
一、需求分析1.需要一个显示屏幕较大的系统,以便能够在远距离外也能清晰看到信息。
2.需要一个可以远距离控制显示内容的系统。
3.显示内容可以动态变化,能够显示文字、图片、动画等多种形式。
4.系统需要易于维护和操作。
二、系统设计1.硬件设计为了满足显示屏幕大的需求,我们可以选择一个高分辨率的LED显示屏。
为了控制显示内容,我们可以选择一款强大且易于操作的单片机作为控制主板。
同时,还需要一个电源模块来提供电力。
2.软件设计为了实现动态变化的显示内容,我们需要设计一个用户界面,使用户能够通过输入设备(例如键盘、遥控器等)来输入显示内容。
同时,还需要一个软件模块来实现内容的转换和发送。
单片机需要能够接收和解析输入的指令,并按照指令来动态更新显示内容。
三、详细设计1.硬件设计选择合适的LED显示屏幕,可以根据需求选择合适的尺寸和分辨率。
设计一个控制主板,使用单片机作为核心控制模块,通过与电源模块的配合,提供稳定的电力供应。
同时,还需要与显示屏幕的接口板连接,实现信息的传输。
2.软件设计设计用户界面,可以使用图形界面,使用户能够直观地操作系统。
通过输入设备输入指令,在单片机上设计相应的软件模块,实现接收、解析和处理指令的功能。
根据指令来更新显示内容。
四、系统实现1.硬件实现按照硬件设计方案进行组装和连接。
选择合适的单片机和电源模块,根据显示屏幕的接口要求进行连接,确保电路连接正确无误。
2.软件实现设计用户界面,根据用户的需求和喜好进行界面的设计。
实现并调试单片机的软件模块,确保接收、解析和处理指令的功能正常运行。
五、系统测试在完成系统实现后,需要进行一系列的测试,以确保系统的正常工作和稳定性。
可以进行功能测试、稳定性测试、兼容性测试等,以保证系统的可靠性和稳定性。
1 系统硬件介绍本设计通过单片机实现喇叭播放音乐和LCD液晶显示文字、图片、动画,并通过键盘进行控制操作,实现功能的选择。
单片机使用AT89C55WD芯片,容有20K字节可编程闪烁存储器,能存放做够的程序容量。
LCD使用128*64液晶屏,通过控制驱动器,能显示图片和文字。
另外使用I2C总线扩展,I2C总线是一种用于IC器件之间连接的二线制总线。
它通过SDA(串行数据线)及SCL(串行时钟先)两根线在连到总线上的器件之间传送信息,并根据地址识别每个器件,不管是单片机、存储器、LCD驱动器还是键盘接口。
1.1 单片机简介所谓单片机,通俗的来讲,就是把中央处理器CPU(Central Processing Unit),存储器(memory),定时器,I/O(Input/Output)接口电路等一些计算机的主要功能部件集成在一块集成电路芯片上的微型计算机。
单片机又称为“微控制器MCU”。
中文“单片机”的称呼是由英文名称“Single Chip Microcomputer”直接翻译而来的。
顾名思义,这种计算机的最小系统只用了一片集成电路,即可进行简单运算和控制。
因为它体积小,通常都藏在被控机械的“肚子”里。
它在整个装置中,起着有如人类头脑的作用,它出了毛病,整个装置就瘫痪了。
现在,这种单片机的使用领域已十分广泛,如智能仪表、实时工控、通讯设备、导航系统、家用电器等。
各种产品一旦用上了单片机,就能起到使产品升级换代的功效,常在产品名称前冠以形容词——“智能微电脑型”,如智能型热水器等。
本设计用到的单片机是AT89C55WD,下面就以AT89C55WD为例,结合本设计所用到的内容,简单介绍一下单片机的基础知识。
1.1.1 AT89C55WD简介AT89C55WD是一个低电压,高性能CMOS 8 位单片机,片内含有20KB 的可重写快速闪存存储器和只读程序和256 bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,引脚兼容工业标准芯片,采用通用编程方式,片内置通用8位中央处理器和Flash存储单元,内置功能强大的微处理器的AT89C55WD可为您提供许多高性价比的解决方案,适用于多数嵌入式应用系统。
单片机实验五报告_单片机键盘实验一、实验目的本次单片机键盘实验的主要目的是让我们深入了解单片机与键盘的接口技术,掌握如何通过编程实现对键盘输入的检测和响应,从而提高我们在单片机应用开发中的实际操作能力。
二、实验原理在单片机系统中,键盘通常是作为输入设备使用的。
常见的键盘有独立式键盘和矩阵式键盘两种类型。
独立式键盘是每个按键单独占用一根 I/O 线,其优点是电路简单,编程容易,但缺点是占用较多的 I/O 口资源。
矩阵式键盘则是将按键排列成矩阵形式,通过行线和列线的交叉来识别按键。
这种方式可以有效地节省 I/O 口资源,但电路和编程相对复杂一些。
在本次实验中,我们采用了矩阵式键盘。
其工作原理是通过逐行扫描或者逐列扫描的方式,检测行线和列线的电平状态,从而确定按下的按键。
三、实验设备及材料1、单片机开发板一块2、计算机一台3、编程软件(如 Keil C51)4、下载工具(如 STCISP)四、实验步骤1、硬件连接将矩阵式键盘与单片机的 I/O 口进行连接,注意行线和列线的对应关系。
连接好电源和地线,确保硬件电路正常工作。
2、软件编程打开编程软件,创建一个新的工程。
编写初始化程序,包括设置 I/O 口的工作模式、中断等。
编写键盘扫描程序,通过循环扫描行线和列线的电平状态,判断是否有按键按下。
当检测到按键按下时,根据按键的编码执行相应的操作,如在数码管上显示按键值、控制 LED 灯的亮灭等。
3、编译和下载对编写好的程序进行编译,检查是否有语法错误。
如果编译成功,使用下载工具将程序下载到单片机中。
4、实验调试观察硬件电路的工作状态,看是否有异常现象。
按下不同的按键,检查程序的响应是否正确。
如果出现问题,通过调试工具(如单步调试、断点调试等)查找并解决问题。
五、实验代码以下是本次实验的部分关键代码:```cinclude <reg51h>//定义键盘的行和列define ROW_NUM 4define COL_NUM 4//定义行线和列线的端口sbit ROW1 = P1^0;sbit ROW2 = P1^1;sbit ROW3 = P1^2;sbit ROW4 = P1^3;sbit COL1 = P1^4;sbit COL2 = P1^5;sbit COL3 = P1^6;sbit COL4 = P1^7;//定义按键值的编码unsigned char code KeyCodeMapROW_NUMCOL_NUM ={{'1','2','3','A'},{'4','5','6','B'},{'7','8','9','C'},{'','0','','D'}};//键盘扫描函数void KeyScan(){unsigned char i, j, temp;unsigned char keyValue = 0;//逐行扫描for (i = 0; i < ROW_NUM; i++){//先将所有行线置高电平ROW1 = ROW2 = ROW3 = ROW4 = 1;//将当前行线置低电平switch (i){case 0: ROW1 = 0; break;case 1: ROW2 = 0; break;case 2: ROW3 = 0; break;case 3: ROW4 = 0; break;}//读取列线的电平状态temp = COL1 | COL2 | COL3 | COL4;//如果有列线为低电平,则表示有按键按下if (temp!= 0xF0){//延迟去抖动delay_ms(10);//再次读取列线的电平状态temp = COL1 | COL2 | COL3 | COL4; if (temp!= 0xF0){//确定按下的按键for (j = 0; j < COL_NUM; j++){if ((temp &(1 << j))== 0){keyValue = KeyCodeMapij;break;}}//执行相应的操作switch (keyValue){case '1'://具体操作break;case '2':break;//其他按键的操作}}}}}//主函数void main(){while (1){KeyScan();}}```六、实验结果及分析在实验过程中,我们成功地实现了对矩阵式键盘的输入检测,并能够根据不同的按键执行相应的操作。
单片机矩阵键盘设计方案一、设计目标设计一个8行8列的矩阵键盘,每个按键都有一个唯一的键码,能够正常读取用户的按键输入,并将按键对应的键码显示在LCD屏幕上。
二、硬件设计硬件设计包括键盘电路和显示电路两部分。
1.键盘电路设计矩阵键盘的硬件设计主要包括键盘矩阵、行扫描电路和列读取电路。
键盘矩阵由8行8列的按键构成,每个按键都连接到一个由二极管组成的矩阵。
行扫描电路使用8位输出的GPIO口,根据行的值来选通对应的行组。
列读取电路使用8位输入的GPIO口,根据列的值来读取对应的列组。
2.显示电路设计三、软件设计软件设计主要包括初始化设置、按键检测、键码解析和显示处理四个部分。
1.初始化设置首先需要对GPIO口进行初始化设置,将扫描行的GPIO口设置为输出模式,将读取列的GPIO口设置为输入模式。
同时需要对LCD屏幕进行初始化设置,设置显示模式、光标位置等参数。
2.按键检测循环扫描每一行,当其中一行被选通时,读取每一列的值。
如果其中一列的值为低电平,则表示对应的按键被按下。
将按下的按键的行和列的值保存下来,用于后续的键码解析。
3.键码解析根据行和列的值,通过查表的方式找到对应的键码。
将键码保存下来,用于后续的显示处理。
4.显示处理将键码传送给LCD屏幕,通过LCD屏幕的驱动芯片进行解析和显示。
根据LCD屏幕的显示方式,可以选择逐行显示或者按需显示的方式。
四、优化设计在以上基本设计方案的基础上,可以进行一些优化设计,以提高系统的性能和可靠性。
1.消除按键抖动按键在实际使用中会存在抖动现象,需要通过软件滤波来消除。
可设置一个适当的延时,当检测到按键按下后,延时一段时间再进行键码解析,只有在延时之后仍然检测到按键按下,才认为是一个有效的按键。
2.防止冲突按键由于矩阵键盘的性质,可能存在一些按键组合会产生冲突的情况。
可以通过硬件设计和软件处理来解决。
在硬件上,可以增加二极管来隔离不同的按键。
在软件上,可以通过扫描算法和按键排除的方式来避免冲突。
敬告:没有51单片机基础的人请慎重下载高质量实用性51单片机STC15W系列程序(3),STC8A系列可参考STC15单片机PCF8563时钟芯片LCD1602显示4×4键盘设置时间程序/**************************************************/ main主函数程序:#include "Library.h"unsigned char code orgval[7]={0x00,0x00,0x00,0x20,0x01,0x04,0x20,};unsigned char set_buf[13]={0,0,0,0,0,0,1,0,0,0,0,0,0,}; unsigned char t_buf[7];unsigned char t_rec[7];unsigned char time_buf[15];unsigned char x_value;unsigned char y_value;bit enter_flag;bit tmr200ms_flag=0;void Write_original(unsigned char *originalval);void Timer0_config(unsigned int ms);void Display_time(unsigned char *tm_buf);void main(){unsigned char sec_bkp;unsigned char testbuf[7];P1M1 &= 0x3F; P1M0 &= 0x3F;P2M1 &= 0x3F; P2M0 &= 0x3F;P5M1 &= 0xF3; P5M0 &= 0xF3;P4M1 &= 0x0F; P4M0 &= 0x0F;P2M1 &= 0xE5; P2M0 &= 0xE5;P0M1 = 0x00; P0M0 = 0x00;Timer0_config(1);LCD1602_init();EA = 1;//F0 = 0;//LCD1602_wbyte(0,0,"hi",sizeof("hi")-1);//test LCD1602//P0 = 0xFF;Read_time(0x02,testbuf);if(testbuf[0]&0x80){Write_original(orgval);}while(1){Key_driver();if(tmr200ms_flag){tmr200ms_flag=0;Read_time(0x02,t_rec);//Display_time(t_buf);//test}if(enter_flag==0){if(sec_bkp!=t_rec[0]){sec_bkp = t_rec[0];Display_time(t_rec);}}}}void Display_time(unsigned char *tm_buf){time_buf[0] = ((tm_buf[2])>>4)+'0';time_buf[1] = ((tm_buf[2])&0x0F)+'0';time_buf[2] = ':';time_buf[3] = ((tm_buf[1])>>4)+'0';time_buf[4] = ((tm_buf[1])&0x0F)+'0';time_buf[5] = ':';time_buf[6] = ((tm_buf[0])>>4)+'0';time_buf[7] = ((tm_buf[0])&0x0F)+'0';LCD1602_wbyte(0,0,time_buf,8);time_buf[0] = 0x02 + '0';time_buf[1] = 0x00 + '0';time_buf[2] = (tm_buf[6]>>4)+'0';time_buf[3] = (tm_buf[6]&0x0F)+'0';time_buf[4]= '-';time_buf[5] = (tm_buf[5]>>4)+'0';time_buf[6] = (tm_buf[5]&0x0F)+'0';time_buf[7]= '-';time_buf[8] = (tm_buf[3]>>4)+'0';time_buf[9] = (tm_buf[3]&0x0F)+'0';LCD1602_wbyte(0,1,time_buf,10);time_buf[0] = (tm_buf[4]&0x0F)+'0';LCD1602_wbyte(10,0,time_buf,1);}void Write_original(unsigned char *originalval) {Display_time(originalval);Write_time(0x02,originalval);}void KeyAction(unsigned char kc){unsigned int tmp;if(kc==0x26)//up{}else if(kc==0x28)//down{}else if(kc==0x25)//left:set x,y{if(enter_flag){if(y_value==0){if(x_value<10){x_value++;if(x_value==7){x_value = 10;}}else{x_value = 0;y_value = 1;}}else if(y_value==1){if(x_value<9){x_value++;}else{x_value = 0;y_value = 0;}}Setcursor(x_value,y_value);}}else if(kc==0x27)//right:set value{if(enter_flag){if(y_value==0){if(x_value==0||x_value==1){if(x_value==0){if(set_buf[0]<2){set_buf[0]++;}else{set_buf[0]=0;}}else if(x_value==1){if(set_buf[1]<9){set_buf[1]++;}else{set_buf[1]=0;}}if((set_buf[0]==2)&&(set_buf[1]>3)){set_buf[1] = 0;}t_buf[2] =( set_buf[0]<<4) |( set_buf[1]&0x0F);}else if(x_value==3||x_value==4){if(x_value==3){if(set_buf[2]<5){set_buf[2]++;}else{set_buf[2]=0;}}else if(x_value==4){if(set_buf[3]<9){set_buf[3]++;}else{set_buf[3]=0;}}t_buf[1] =(set_buf[2]<<4 )|( set_buf[3]&0x0F);}else if(x_value==6||x_value==7){if(x_value==6){if(set_buf[4]<5){set_buf[4]++;}else{set_buf[4]=0;}}else if(x_value==7){if(set_buf[5]<9){set_buf[5]++;}else{set_buf[5]=0;}}t_buf[0] = (set_buf[4]<<4 )|( set_buf[5]&0x0F);}else if(x_value==10){if(set_buf[6]<7){set_buf[6]++;}else{set_buf[6] = 0x01;}t_buf[4] = set_buf[6]&0x0F; }}else if(y_value==1){if(x_value==2||x_value==3){if(x_value==2){if(set_buf[7]<9){set_buf[7]++;else{set_buf[7]=0;}}else if(x_value==3){if(set_buf[8]<9){set_buf[8]++;}else{set_buf[8]=0;}}t_buf[6] = (set_buf[7]<<4)|( set_buf[8]);}else if(x_value==5||x_value==6){if(x_value==5){if(set_buf[9]<1){set_buf[9]++;else{set_buf[9]=0;}}else if(x_value==6){if(set_buf[10]<9){set_buf[10]++;}else{set_buf[10]=0;}if((set_buf[9]==1)&&(set_buf[10]>2)){set_buf[10] = 0;}}t_buf[5] = (set_buf[9]<<4)| set_buf[10];}else if(x_value==8||x_value==9){if(x_value==8){if(set_buf[11]<3){set_buf[11]++;}else{set_buf[11]=0;}}else if(x_value==9){if(set_buf[12]<9){set_buf[12]++;}else{set_buf[12]=0;}if((set_buf[11]==3)&&(set_buf[12]>0)&&((t_buf[5]==0x04)| |(t_buf[5]==0x06)||(t_buf[5]==0x09)||(t_buf[5]==0x11))){set_buf[12] = 0;}elseif((set_buf[11]==3)&&(set_buf[12]>1)){set_buf[12] = 0;}}t_buf[3] = (set_buf[11]<<4)|set_buf[12];}if((t_buf[5]==0x02)&&(t_buf[3]>=0x29)){tmp = set_buf[7]*10 + set_buf[8];tmp = tmp + 2000;if((tmp%4==0)&&(tmp%100!=0)){t_buf[3] = 0x29;}else{t_buf[3] = 0x28;}}if(((t_buf[5]==0x04)||(t_buf[5]==0x06)||(t_buf[5]==0x09) ||(t_buf[5]==0x11))&&(t_buf[3]==0x31)){t_buf[3]=0x30;}}Display_time(t_buf);}}else if(kc==0xC0)//esc{OffCursor();Setcursor(0,0);enter_flag = 0;}else if(kc==0x0D)//enter{if(enter_flag==0){enter_flag = 1;OnCursor();Setcursor(0,0);}else{enter_flag = 0;OffCursor();Setcursor(0,0);Write_time(0x02,t_buf); }}else{}}void Timer0_config(unsigned int ms){unsigned long tmp;tmp = (MAIN_Fosc*ms)/1000;tmp = 65536 - tmp;TL0 = (unsigned char)tmp;TH0 = (unsigned char)(tmp>>8);TMOD &= 0xF0;AUXR |= 0x80;ET0 = 1;TR0 = 1;}void Timer0_interrupt() interrupt 1{static unsigned int tmr200ms=0;Key_scan();tmr200ms++;if(tmr200ms>500){tmr200ms = 0;tmr200ms_flag=1; }}/**************************************************/ PCF8563程序及简要说明:/*****************************1.IIC-bus slave address:read A3h and write A2h2.16 8-bit registers3.Binary coded Decimal->BCD4.registers describe1>Control_status_1 address 00h-> 0000 00002>Control_status_2 address 01h-> 0000 00003>VL_seconds address 02h-> VL 000(5) 0000(9)defualt VL = 14>Minutes address 03h-> x 000(5) 0000(9)5>Hours address 04h-> xx 00(2) 0000(9)6>Days address 05h-> xx 00(3) 0000(9)7>Weekdays address 06h-> xxxx x000(6):000->sunday 110->saturday8>Century_months address 07h-> 0xx 0(1) 0000(9)9>Years address 08h-> 0000(9) 0000(9)->99Access time for read/write operations->start->slave address->data/data...->stop->10>~13> alarm registers omitted:default value,min_alarm->0b1000 0000, hour_alarm->0b1000 0000,day_alarm->0b1000 0000,week_alarm->0b1000 0000,14> clkout control register omitted:default value,0b1000 0000,15>Timer_control address 0Eh->default value,0b0000 0000,16>Tiemr address 0Fh->default value,0b0000 0000*******************************/ #include "Library.h"//struct t_truct//{// unsigned char sec;// unsigned char min;// unsigned char hor;// unsigned char day;// unsigned char mon;// unsigned int year;// unsigned char week;//};void Delay1us() //@11.0592MHz {unsigned char i;_nop_();_nop_();i = 8;while (--i);}void IIC_start(){SDA = 1;SCL = 1;Delay1us();SDA = 0;Delay1us();SCL = 0;}void IIC_stop(){SCL = 0;SDA = 0;Delay1us();SCL = 1;Delay1us();SDA = 1;Delay1us();}unsigned char IIC_readAck(){unsigned char val;unsigned char mask;SDA = 1;for(mask=0x80;mask!=0;mask>>=1) {Delay1us();SCL = 1;if(SDA)val |= mask;elseval &= ~mask;Delay1us();SCL = 0;}SDA = 0;Delay1us();SCL = 1;Delay1us();SCL= 0;return val;}unsigned char IIC_readNack(){unsigned char val;unsigned char mask;SDA = 1;for(mask=0x80;mask!=0;mask>>=1) {SCL = 1;Delay1us();if(SDA)val |= mask;elseval &= ~mask;SCL = 0;Delay1us();}SDA = 1;Delay1us();SCL = 1;Delay1us();SCL= 0;return val;}bit IIC_write(unsigned char dat) {unsigned char mask;bit ack;for(mask=0x80;mask!=0;mask>>=1) {//Delay1us();if((dat&mask)==0)SDA = 0;elseSDA = 1;Delay1us();SCL = 1;Delay1us();SCL = 0; ////////}SDA = 1;Delay1us();//SCL = 0;SCL = 1;ack = SDA;Delay1us();// SCL = 1;// Delay1us();SCL = 0;return ~ack;}void Read_time(unsigned char addr,unsigned char *tm_buf) { do{IIC_start();if(IIC_write(0xA2))break;IIC_stop();}while(1);IIC_write(addr);IIC_start();//or IIC_stop()IIC_write(0xA3);tm_buf[0] = IIC_readAck();tm_buf[1] = IIC_readAck();tm_buf[2] = IIC_readAck();tm_buf[3] = IIC_readAck();tm_buf[4] = IIC_readAck();tm_buf[5] = IIC_readAck();tm_buf[6] = IIC_readNack();IIC_stop();}void Write_time(unsigned char addr,unsigned char *tm_buf) {do{IIC_start();if(IIC_write(0xA2))break;IIC_stop();}while(1);IIC_write(addr);IIC_write(tm_buf[0]);IIC_write(tm_buf[1]);IIC_write(tm_buf[2]);IIC_write(tm_buf[3]);IIC_write(tm_buf[4]);IIC_write(tm_buf[5]);IIC_write(tm_buf[6]);IIC_stop(); }/**************************************************/4×4键盘程序:#include "Library.h"/**********************************if enter key down 3second ,into time setting mode,else calculator mode**********************************/unsigned char code keycode[4][4]={{0x31,0x32,0x33,0x26},//up{0x34,0x35,0x36,0x28},//down{0x37,0x38,0x39,0x25},//left{0x30,0xC0,0x0D,0x27},//right};unsigned char keysta[4][4]={{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1},};//bit enter3s;//down 3svoid Key_scan(){static unsigned char keyout = 0;static unsigned char keybuf[4][4]={{0x0F,0x0F,0x0F,0x0F},{0x0F,0x0F,0x0F,0x0F},{0x0F,0x0F,0x0F,0x0F},{0x0F,0x0F,0x0F,0x0F},};unsigned char i;keybuf[keyout][0]=(keybuf[keyout][0]<<1)|keyin_1;keybuf[keyout][1]=(keybuf[keyout][1]<<1)|keyin_2;keybuf[keyout][2]=(keybuf[keyout][2]<<1)|keyin_3;keybuf[keyout][3]=(keybuf[keyout][3]<<1)|keyin_4;for(i=0;i<4;i++){if((keybuf[keyout][i]&0x0F)==0x00){keysta[keyout][i] = 1;}else if((keybuf[keyout][i]&0x0F)==0x0F){keysta[keyout][i] = 0;}}keyout++;keyout &= 0x03;switch(keyout){case 0:keyout_4=1;keyout_1=0;break;case 1:keyout_1=1;keyout_2=0;break;case 2:keyout_2=1;keyout_3=0;break;case 3:keyout_3=1;keyout_4=0;break;default:break;}}void Key_driver(){unsigned char i,j;static unsigned char stabkp[4][4]={{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1},};for(i=0;i<4;i++){for(j=0;j<4;j++){if(stabkp[i][j]!=keysta[i][j]){if(stabkp[i][j]==0){KeyAction(keycode[i][j]); }}stabkp[i][j] = keysta[i][j]; }}}/**************************************************/ LCD1602程序:#include "Library.h"void LCD1602_rsta(){unsigned char tmp;P0 = 0xFF;//this is a mustrs = 0;rw = 1;do{en = 1;//Delay1us();tmp = P0;//Delay1us();en = 0;}while(tmp&0x80);}void LCD1602_wdat(unsigned char dat){LCD1602_rsta();rs=1;rw=0;P0 = dat;en = 1;//Delay1us();en = 0;}void LCD1602_wcmd(unsigned char cmd){LCD1602_rsta();rs=0;rw=0;P0 = cmd;en = 1;//Delay1us();en = 0;}void Setcursor(unsigned char x,unsigned char y){if(y==0)x = x + 0x00;else if(y==1)x = x + 0x40;LCD1602_wcmd(x|0x80);}void LCD1602_wbyte(unsigned char x,unsigned char y,unsigned char *buf,unsigned char buf_len){Setcursor(x,y);while(buf_len>0){LCD1602_wdat(*buf++); buf_len--;}}void OnCursor(){LCD1602_wcmd(0x0F);}void OffCursor(){LCD1602_wcmd(0x0C);}void LCD1602_init(){// Delay15ms();// LCD1602_wcmd(0x38);// Delay5ms();LCD1602_wcmd(0x38);// LCD1602_wcmd(0x08);LCD1602_wcmd(0x06);LCD1602_wcmd(0x0C);LCD1602_wcmd(0x01);}/**************************************************/Library.h#ifndef _Library_H#define _Library_H#include "STC15.h"#include "intrins.h"#define MAIN_Fosc 11059200L//PCF8563sbit SCL = P1^6;sbit SDA = P1^7;//sbit SDA = P5^3;//sbit SCL = P5^2;void Read_time(unsigned char addr,unsigned char *tm_buf); void Write_time(unsigned char addr,unsigned char *tm_buf); void Delay1us();//4x4Keysbit keyin_1 = P2^7;sbit keyin_2 = P2^6;sbit keyin_3 = P5^3;sbit keyin_4 = P5^2;sbit keyout_1 = P4^7;sbit keyout_2 = P4^6;sbit keyout_3 = P4^5;sbit keyout_4 = P4^4;void Key_driver();void Key_scan();void KeyAction(unsigned char kc);//LCD1602sbit rs = P2^4;sbit rw = P2^3;sbit en = P2^1;void LCD1602_init();void LCD1602_wbyte(unsigned char x,unsigned char y,unsigned char *buf,unsigned char buf_len);void OnCursor();void OffCursor();void Setcursor(unsigned char x,unsigned char y);void LCD1602_wdat(unsigned char dat);#endif。
C51单片机键盘检测原理以及实现首先,在做软件之前确定硬件。
明确键盘类型:弹性按键:按下时闭合,松手后自动断开。
如电脑键盘自锁式按键:按下时闭合,且自动锁住。
一边用于开关在I/O 口检测触电电压时应该考虑按键抖动问题,一般按键抖动为5~10ms左右,具体与其机械特性有关,所以要加检测抖动环节,可以用软件或者去抖动芯片硬件处理,当然通常用延时方法处理。
注意正确连接引脚。
下面是一个简单的4 按键独立键盘程序,在51hei 开发板的数码管上操作。
完整的源代码下载51hei/f/jpdd.rar 数值为0~59 变化,开始显示00 按key1 数值加1,按key2 数值减1,按key3 数值归0,按key4 数值每秒加1。
#includereg52.h#define uchar unsigned char#define unit unsigned intsbit key1=P3 ;sbit key1=P3;sb it key1=P3;sb it key1=P3;sb it dula=P2;sb it wela=P2;uch a r code table[]={0x3f,0x06.0x5b,0x4f,0x66,0x6d,0x7d,0x070x7f,0x6f,0x77,0x7c0x39,0x5e,0 x79,0x71};void delayms(unit);uchar numt0,unm;void display(uchar numdis) //定义一个显示的函数,分个位十位,用来显示{uchar shi,ge; //然后用轮流显示发,利用人眼图像残留分别显示shi=numdis/10; //上面的numdis 表示num 这个显示的数ge=numdis%10; //numdis 由下面主函数num 赋值dula=1;P0=table[shi]; dula=0;P0=0xff;wela=1;P0=0xfe;wela=0;delayms(5);dula=1;P0=table[ge];dula=0;P0 =0xff;wela=1;P0=0xfe;wela=0;delayms(5);}void delayms(unit xms) //自定义延迟环节{unit i,j;for(i=xms,i0,i--);for(j=110,j0,j--);}void init() //初始化函数,保证程序正常运行{TMOD=0x01;TH0=(65536-45872)/256;TL0=(65536-458720%256;EA=1;ET=0;}tips:感谢大家的阅读,本文由我司收集整编。