1602 键盘显示
- 格式:doc
- 大小:1015.50 KB
- 文档页数:37
项目:1602LCD显示电话拨号键盘按键设计者:陈小玲1602液晶显示模块指令驱动程序设计介绍液晶显示器以其微功耗、体积小、显示内容丰富、超薄轻巧的诸多优点,在各类仪表和低功耗系统中得到广泛的应用。
根据显示内容可以分为字符型液晶,图形液晶。
根据显示容量又可以分为单行16字,2行16字,两行20字等等。
这里介绍常用的字16字X2行的字符型液晶模块的使用方法。
这是一种通用模块。
与数码管相比该模块有如下优点:1.位数多,可显示32位,32个数码管体积相当庞大了2.显示内容丰富,可显示所有数字和大、小写字母3.程序简单,如果用数码管动态显示,会占用很多时间来刷新显示,而1602自动完成此功能。
1602采用标准的16脚接口,其中:(模块背面有标注)第1脚:VSS为地电源第2脚:VDD接5V正电源第3脚:V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度(建议接地,弄不好有的模块会不显示)第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。
第5脚:RW为读写信号线,高电平时进行读操作,低电平时进行写操作。
第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
第7~14脚:D0~D7为8位双向数据线。
第15~16脚:空脚(有的用来接背光)1602模块的设定,读写,与光标控制都是通过指令来完成,共有11条指令,如下:程序设计调试与实训:A键用于随机生成一道口诀题,数字键0-9用于输入结果(程序可限制最多只能输入俩位数),B键判断正误,如果正确则闪烁显示success,否则显示error, C键用于清除当前输入的答案,一遍重新输入,DJ键用于显示正确答案。
Proteus绘制的原理图编译的源代码://名称:1602LCD显示电话拨号键盘按键//说明:本例将电话拨号键盘上所拨号号码显示在1602液晶屏上。
main.c#include<reg52.h>#include"lcd.h"#define GPIO_KEY P1unsigned char KeyValue;//用来存放读取到的键值unsigned char KeyState;//用来存放按键状态unsigned char PuZh[]=" Pechin Science ";unsigned char dat[]="0123456789ABCDEF";void Delay10ms(); //延时50usvoid KeyDown(); //检测按键函数/******************************************************************************* * 函数名: main* 函数功能: 主函数* 输入: 无* 输出: 无*******************************************************************************/ void main(void){unsigned char i;LcdInit();KeyState=0;for(i=0;i<16;i++){// LcdWriteCom(0x80);LcdWriteData(PuZh[i]);}while(1){KeyDown();if(KeyState){KeyState=0;LcdWriteCom(0x80+0x40);LcdWriteData(dat[KeyValue]);}}}/******************************************************************************** 函数名: KeyDown* 函数功能: 检测有按键按下并读取键值* 输入: 无* 输出: 无*******************************************************************************/void KeyDown(void){char a;GPIO_KEY=0x0f;if(GPIO_KEY!=0x0f){Delay10ms();if(GPIO_KEY!=0x0f){KeyState=1;//测试列GPIO_KEY=0X0F;// Delay10ms();switch(GPIO_KEY){case(0X07): KeyValue=0;break;case(0X0b): KeyValue=1;break;case(0X0d): KeyValue=2;break;case(0X0e): KeyValue=3;break;// default: KeyValue=17; //检测出错回复17意思是把数码管全灭掉。
名称:LCD1602论坛:编写:shifang日期:2009.5修改:无内容:通过矩阵键盘输入,依次显示0-F16中字符引脚定义如下:1-VSS 2-VDD 3-V0 4-RS 5-R/W 6-E 7-14 DB0-DB7 15-BLA 16-BLK------------------------------------------------*/#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义#include<intrins.h>sbit RS = P2^4; //定义端口sbit RW = P2^5;sbit EN = P2^6;#define RS_CLR RS=0#define RS_SET RS=1#define RW_CLR RW=0#define RW_SET RW=1#define EN_CLR EN=0#define EN_SET EN=1#define DataPort P0#define KeyPort P1unsigned char code dofly_code[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};//转换成液晶显示的字符/*------------------------------------------------uS延时函数,含有输入参数unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编,大致延时长度如下T=tx2+5 uS------------------------------------------------*/void DelayUs2x(unsigned char t){while(--t);}/*------------------------------------------------mS延时函数,含有输入参数unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编void DelayMs(unsigned char t){while(t--){//大致延时1mSDelayUs2x(245);DelayUs2x(245);}}/*------------------------------------------------判忙函数------------------------------------------------*/ bit LCD_Check_Busy(void){DataPort= 0xFF;RS_CLR;RW_SET;EN_CLR;_nop_();EN_SET;return (bit)(DataPort & 0x80);}/*------------------------------------------------写入命令函数------------------------------------------------*/ void LCD_Write_Com(unsigned char com) {while(LCD_Check_Busy()); //忙则等待RS_CLR;RW_CLR;EN_SET;DataPort= com;_nop_();EN_CLR;}/*------------------------------------------------写入数据函数------------------------------------------------*/ void LCD_Write_Data(unsigned char Data) {while(LCD_Check_Busy()); //忙则等待RS_SET;EN_SET;DataPort= Data;_nop_();EN_CLR;}/*------------------------------------------------清屏函数------------------------------------------------*/void LCD_Clear(void){LCD_Write_Com(0x01);DelayMs(5);}/*------------------------------------------------写入字符串函数------------------------------------------------*/void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s) {if (y == 0){LCD_Write_Com(0x80 + x);}else{LCD_Write_Com(0xC0 + x);}while (*s){LCD_Write_Data( *s);s ++;}}/*------------------------------------------------写入字符函数------------------------------------------------*/void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data) {if (y == 0){LCD_Write_Com(0x80 + x);}elseLCD_Write_Com(0xC0 + x);}LCD_Write_Data( Data);}/*------------------------------------------------初始化函数------------------------------------------------*/void LCD_Init(void){LCD_Write_Com(0x38); /*显示模式设置*/DelayMs(5);LCD_Write_Com(0x38);DelayMs(5);LCD_Write_Com(0x38);DelayMs(5);LCD_Write_Com(0x38);LCD_Write_Com(0x08); /*显示关闭*/LCD_Write_Com(0x01); /*显示清屏*/LCD_Write_Com(0x06); /*显示光标移动设置*/DelayMs(5);LCD_Write_Com(0x0C); /*显示开及光标设置*/}/*------------------------------------------------按键扫描函数,返回扫描键值------------------------------------------------*/unsigned char KeyScan(void) //键盘扫描函数,使用行列反转扫描法{unsigned char cord_h,cord_l;//行列值中间变量KeyPort=0x0f; //行线输出全为0cord_h=KeyPort&0x0f; //读入列线值if(cord_h!=0x0f) //先检测有无按键按下{DelayMs(10); //去抖if((KeyPort&0x0f)!=0x0f){cord_h=KeyPort&0x0f; //读入列线值KeyPort=cord_h|0xf0; //输出当前列线值cord_l=KeyPort&0xf0; //读入行线值while((KeyPort&0xf0)!=0xf0);//等待松开并输出return(cord_h+cord_l);//键盘最后组合码值}}return(0xff); //返回该值}/*------------------------------------------------按键值处理函数,返回扫键值------------------------------------------------*/unsigned char KeyPro(void){switch(KeyScan()){case 0x7e:return 0;break;//0 按下相应的键显示相对应的码值case 0x7d:return 1;break;//1case 0x7b:return 2;break;//2case 0x77:return 3;break;//3case 0xbe:return 4;break;//4case 0xbd:return 5;break;//5case 0xbb:return 6;break;//6case 0xb7:return 7;break;//7case 0xde:return 8;break;//8case 0xdd:return 9;break;//9case 0xdb:return 10;break;//acase 0xd7:return 11;break;//bcase 0xee:return 12;break;//ccase 0xed:return 13;break;//dcase 0xeb:return 14;break;//ecase 0xe7:return 15;break;//fdefault:return 0xff;break;}}/*------------------------------------------------主函数------------------------------------------------*/void main(void){unsigned char i,j,num;LCD_Init();LCD_Write_Com(0x0F);//光标开,光标闪烁开LCD_Write_String(0,0,"Press the key !");while (1){num=KeyPro();if(num!=0xff){if((i==0)&&(j==0))//回到第一个字符时清屏LCD_Clear();//清屏LCD_Write_Char(0+i,0+j,dofly_code[num]);//依次显示输入字符i++;if(i==16)//如果第一行显示满,转到第二行{i=0;j++;if(j==2)//如果2行都显示满,清屏后重新从第一行显示{j=0;}}}}}。
摘要在日常生活中,我们经常要通过按键来实现对电子装置的控制,小到手表手机,中到电视电脑,大到各种复杂仪器,都需要通过按键来实现各种操作。
本次课程设计作为实践教学的一个重要环节,将以按键控制显示为主题,以1602液晶、MM74C922解码芯片、AT89C52单片机及其接口芯片为核心构造一个键盘控制显示系统,并使用Proteus软件对所设计的电路进行仿真,仿真结果是在1602液晶上显示所按下的键值。
关键词:Proteus仿真AT89C52 1602液晶MM74C922解码芯片第一章总体设计1.1电路结构分析本次设计的目标为单片机控制的键盘识别显示系统,主要采用AT89C52单片机作为核心,由矩阵键盘电路、译码芯片、液晶显示等模块构成,分别对按键信息和显示电路以及软、硬件各个部分进行控制;本设计采用C言编程来实现对单片机的控制。
实际运作时,单片机会将检测到的按键信号转换成数字,显示于1602液晶上。
系统主要结构可以拆分如下:①矩阵键盘:按键传送输入信息;此键盘采用的是4X4矩阵键盘,能输入0~9,+,—,=,空格,返回,清零。
②键盘识别:矩阵键盘连接的是MM74C922解码芯片,通过解码芯片来识别输入的按键位置。
③AT89C52:采用软件编程来实现按键信息的提取和转换;④1602液晶:用于显示最终被单片机转换过的按键信息。
由以上构思可以设计此按键显示电路。
1.2总体方案设计总体电路原理框图:如图 1.2所示图1.2总体电路原理方框图本次设计分两步来完成,第一步,解码芯片调试系统,将解码芯片接口连接到矩阵键盘作为AT89C52单片机的输入装置,然后以P2口作为输出端并连接一个数码管观察输出结果。
第二步,1602的液晶调试系统,此过程就是将数码管换成1602液晶在进行结果显示。
1.3蜂鸣器模块设计蜂鸣器模块设计如图 1.3所示图 1.3 蜂鸣器模块电路图蜂鸣器的驱动电流比较大一般要500MA~1000MA,所以不能直接接在AT82C52单片机的接口上,需要加一个三极管来进行驱动。
按键复用(1602液晶显示)按键复用(1602 液晶显示)AVR单片机单按键复用之程序AVR单片机中断法的按钮前一段就可以了,查询的居然卡住了。
先写一个51C的,在此基础上写了AVR GCC的,一直到今天才完成。
感觉二者还是有点区别的。
//查询法按键程序,单键复用。
P1.O接一按键,P1.1接一LED。
//11 05 13 E:\DPJ_C\OTHER\ONEKEY\ONEKEY.C#include <reg51.h>#define uchar unsigned charsbit LED1= P1^1;sbit LED2= P1^2;sbit KEY = P1^0;void delay(unsigned int ms ) {unsigned char i;while(ms--)for(i=0;i<123;i++);}void disp1(){LED1=1;}void disp2(){LED1=0;}void main(){uchar temp;while(1){while(!KEY){delay(10);if(KEY)temp=~temp;if(~temp)disp1();elsedisp2();}}}//查询法按键程序,单键复用。
PCO接一按键,PD0接一LED。
//11 05 13 E:\AVR\ONEKEY\onekey.c#include<avr/io.h>#include<util/delay.h>#define KEY PD0#define uchar unsigned charuchar temp,i;void disp1(){DDRC&=~_BV(PC0);//PB0端口低电平PORTC&=~_BV(PC0);//PB0高阻状态,LED无电流通过}void disp2(){DDRC|=_BV(PC0);//PC0端口高电平,输出PORTC&=~_BV(PC0);//PC0低电平输出,LED点亮}int main(){DDRD|=_BV(KEY); //PD0高电平,输出PORTD|=_BV(KEY);DDRD&=~_BV(KEY);while(1){while(!(PIND&_BV(KEY))){for(i=0;i<5;i++)_delay_ms(10);if((PIND&_BV(KEY)))//等待按键释放temp =~temp;if(temp==0xff)disp2();elsedisp1();}}}1602字符液晶详细资料和实例时间:2010-10-11 来源: 作者: 点击:816 字体大小:【大中小】1602字符液晶在实际的产品中运用的也比较多了,前几天留意了一下,发现宿舍门前的自动售水机就是采用的1602液晶进行显示的。
1602 LCD显示电话拨号键盘按键概述本文档介绍了1602 LCD显示电话拨号键盘按键的设计方案及其主要功能。
该方案主要由硬件部分和软件部分组成,硬件部分包括1602液晶显示屏、电话拨号键盘、Arduino板、面包板等;软件部分主要使用Arduino IDE编程,实现LCD屏幕显示、按键检测等功能。
该方案能够检测电话拨号键盘的按键状态并在1602 LCD显示屏上显示对应按键。
设计方案硬件部分硬件部分主要包括以下几个方面:1. 1602液晶显示屏1602液晶显示屏是本方案的显示设备,通过数根引脚与Arduino板相连。
在本方案中,主要利用它显示电话号码和被按下的按键。
2. 电话拨号键盘电话拨号键盘是本方案的主要输入设备,它可以检测到被按下的按键,并将这些信息通过引脚连接Arduino板。
3. Arduino板Arduino板是本方案的主要控制器,它和显示设备、输入设备之间互相连接,通过Arduino IDE编程,实现程序运行、数据传输等功能。
4. 面包板面包板主要是为了方便电路的连接和调试,以及充分利用现成的模块和元器件。
软件部分软件部分主要使用Arduino IDE编程,实现以下几个方面的功能:1. 显示屏幕显示利用Arduino IDE编程,控制1602液晶显示屏上显示电话号码、被按下的按键等相关信息。
2. 按键事件检测利用Arduino IDE编程,通过对电话拨号键盘输入端口的状态检测,实现对按键事件的识别。
主要功能1. 显示电话号码本方案所设计的1602 LCD显示屏,通过数根引脚与Arduino板相连。
在本方案中,主要利用它显示电话号码和被按下的按键。
2. 按键检测利用Arduino IDE编程,通过对电话拨号键盘输入端口的状态检测,实现对按键事件的识别。
当电话拨号键盘检测到按键事件,则通过Arduino板进行响应,并在1602 LCD显示屏上显示对应按键信息。
本文介绍了1602 LCD显示电话拨号键盘按键的设计方案及其主要功能。
#include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit RS=P2^6;sbit RW=P2^5;sbit lcden=P2^7;sbit s1=P1^1; //功能键sbit s2=P1^2; //加一键sbit s3=P1^3; //减一键sbit a=P1^4;sbit c1=P2^0; //功能键sbit c2=P2^1; //加一键sbit c3=P2^2; //减一键uchar count,s1num,c1num,i,j;char nian,yue,ri,shi,fen,miao;uchar code table[]=" 2011-08-18 THU";uchar code table1[]=" 23:59:53";uchar code week1[]="MON";uchar code week2[]="TUE";uchar code week3[]="WED";uchar code week4[]="THU";uchar code week5[]="FRI";uchar code week6[]="SAT";uchar code week7[]="SUN";/*****************************************************************************/ void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=250;y>0;y--);}/*****************************************************************************/ void write_com(uchar com) //写指令{RS=0;RW=0;lcden=0;P0=com;delay(5);lcden=1;delay(5);lcden=0;}/*****************************************************************************/void write_date(uchar date) //写数据{RS=1;RW=0;lcden=0;P0=date;delay(5);lcden=1;delay(5);lcden=0;}/*****************************************************************************/ void init(){uchar num;lcden=0;write_com(0x38); //显示模式设置write_com(0x0c); //显示开关write_com(0x06); //显示光标设置write_com(0x01); //显示清零write_com(0x80);for(num=0;num<16;num++){write_date(table[num]);delay(20);}write_com(0x80+0x40);for(num=0;num<13;num++){write_date(table1[num]);delay(20);}TMOD=0x01;TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1;ET0=1;TR0=1;}/*****************************************************************************/ void write_sfm(uchar add,uchar date) //秒,分,时计算{uchar shi,ge;shi=date/10;ge=date%10;write_com(0x80+0x40+add);write_date(0x30+shi);write_date(0x30+ge);}/*****************************************************************************/ void write_nyr(uchar add,uchar date) //月,日计算{uchar shi,ge;shi=date/10;ge=date%10;write_com(0x80+add);write_date(0x30+shi);write_date(0x30+ge);}/*****************************************************************************/ /*void write_nian(uchar add,uchar date) //千位计算{uchar shi,ge;// bai=date%1000/100;shi=date%100/10;ge=date%10;write_com(0x80+add);// write_date(0x30+qian);// write_date(0x30+bai);write_date(0x30+shi);write_date(0x30+ge);} *//*****************************************************************************/ void keyscan() //判断按键函数{a=0;if(s1==0) //判断功能键是否被按下{delay(5); //消抖if(s1==0){s1num++;while(!s1); //松手检测if(s1num==1) //功能键被按下一次{TR0=0; //时间停止write_com(0x80+0x40+12); //光标向前移一位write_com(0x0f); //光标闪烁}if(s1num==2) //功能键被按下两次{write_com(0x80+0x40+9);}if(s1num==3) //功能键被按下三次{write_com(0x80+0x40+6);}if(s1num==4) //功能键被按下四次{s1num=0;write_com(0x0c); //让光标不在闪烁TR0=1;}}}if(s1num!=0) //判断功能键是否被按下{if(s2==0) //判断加一键是否被按下{delay(5);if(s2==0) //确认加一键被按下{while(!s2);if(s1num==1) //判断指针指向“秒"{miao++;if(miao==60)miao=0;write_sfm(11,miao);write_com(0x80+0x40+11);}if(s1num==2) //判断指针指向“分"{fen++;if(fen==60)fen=0;write_sfm(8,fen);write_com(0x80+0x40+8);}if(s1num==3) //判断指针指向“时"{shi++;if(shi==24)shi=0;write_sfm(5,shi);write_com(0x80+0x40+5);}}}if(s3==0) //判断减一键是否被按下{delay(5);if(s3==0){while(!s3);if(s1num==1) //判断指针指向“秒"{miao--;if(miao==-1)miao=59;write_sfm(11,miao);write_com(0x80+0x40+11);}if(s1num==2) //判断指针指向“分"{fen--;if(fen==-1)fen=59;write_sfm(8,fen);write_com(0x80+0x40+8);}if(s1num==3) //判断指针指向“时"{shi--;if(shi==-1)shi=23;write_sfm(5,shi);write_com(0x80+0x40+5);}}}}}/*****************************************************************************/ void keyscan1() //调整日期{if(c1==0){delay(5);if(c1==0){c1num++;while(!c1);if(c1num==1) //指向”星期“{TR0=0; //时间停止write_com(0x80+15); //光标向前移一位write_com(0x0f); //光标闪烁}if(c1num==2) //指向”日“{write_com(0x80+11);}if(c1num==3) //指向”月“{write_com(0x80+8);}if(c1num==4) //指向”年“{write_com(0x80+5);}if(c1num==5){c1num=0;write_com(0x0c); //让光标不在闪烁TR0=1;}}}if(c1num!=0) //判断功能键是否被按下{if(c2==0) //判断加一键是否被按下{delay(5);if(c2==0) //防抖{while(!c2); //松手检测if(c1num==1) //指向“星期”{i++;if(i==8)i=1;switch(i){case 1:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week5[j]);}break;case 2:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week6[j]);}break;case 3:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week7[j]);}break;case 4:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week1[j]);}break;case 5:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week2[j]);}break;case 6:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week3[j]);}break;case 7:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week4[j]);}break;}}if(c1num==2) //指向”日“{ri++;if(ri==32)ri=1;write_nyr(10,ri);write_com(0x80+10);}if(c1num==3) //指向”月“{yue++;if(yue==13)yue=1;write_nyr(7,yue);write_com(0x80+7);}if(c1num==4) //指向”年“{nian++;write_nyr(4,nian);write_com(0x80+4);}}}if(c3==0) //减一功能键按{delay(5);if(c3==0){while(!c3);if(c1num==1) //指向“星”{i++;if(i==8)i=1;switch(i){case 1:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week3[j]);}break;case 2:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week2[j]);}break;case 3:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week1[j]);}break;case 4:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week7[j]);}break;case 5:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week6[j]);}break;case 6:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week5[j]);}break;case 7:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week4[j]);}break;}}if(c1num==2) //指向“日”{ri--;if(ri==0)ri=31;write_nyr(10,ri);write_com(0x80+10);}if(c1num==3) //指向“月”{yue--;if(yue==0)yue=12;write_nyr(7,yue);write_com(0x80+7);}if(c1num==4) //指向“年”{nian--;write_nyr(4,nian);write_com(0x80+4);}}}}}/*****************************************************************************/ void main(){init();while(1){keyscan();keyscan1();if(count==20) //定时1秒{count=0;miao++;if(miao==60){miao=0;fen++;if(fen==60){fen=0;shi++;if(shi==24){shi=0;ri++;i++;if(ri==32){ri=1;yue++;if(yue==13){yue=1;nian++;write_nyr(3,nian);}write_nyr(7,yue);}write_nyr(10,ri);if(i==8)i=1;switch(i){case 1:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week5[j]);}break;case 2:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week6[j]);}break;case 3:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week7[j]);}break;case 4:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week1[j]);}break;case 5:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week2[j]);}break;case 6:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week3[j]);}break;case 7:write_com(0x80+13); //移动指针for(j=0;j<3;j++){write_date(week4[j]);}break;}}write_sfm(5,shi);}write_sfm(8,fen);}write_sfm(11,miao);}}}/*****************************************************************************/ void timer0() interrupt 1{TH0=(65536-50000)/256;TL0=(65536-50000)%256;count++;}。
---------毕业论文(设计)题目__单片机课程设计________指导教师________ _________院系___ __________专业__ __________班级________ _________姓名______________________学号____ ___________2015年 9月 1 日至2015年 12月 7日(共12周)精品文档目录1.设计预达目标 (1)2.设计方案 (1)2.1单片机最小系统 (1)2.2输入按键系统 (2)2.3 1602LCD显示系统 (3)2.4设计原理图 (6)3. 分析与编程 (7)3.1系统流程图 (7)3.2 LCD显示程序流程图 (7)3.3 设计程序 (8)4.仿真 (15)5.在实现过程中遇到的问题及排除措施 (16)6.设计心得体会 (16)7.参考文献 (16)1602LCD显示电话拨号键盘按键摘要:介绍了基于单片机LCD1602显示屏的设计过程。
给出了其硬件原理图和系统仿真图。
关键词:单片机 1602LCD显示屏键盘系统一、设计预达目标要求以51单片机作为微控制器,通过1602LCD显示屏显示拨号键盘,键值包括数字0-9及“*”“#”等12个按键,数字显示为逐个显示方式。
二.设计方案首先构建单片机最小系统、键盘输入系统及1602LCD显示系统。
通过单片机扫描键值,将其结果输入到1602LCD显示屏上。
(一)单片机最小系统单片机最小系统主要由电源、复位、震荡电路以及扩展部分等部分组成。
1图2.1单片机最小系统(二)输入按键系统独立的键盘与单片机相连时,每个按键都需要单片机的一个I/O线,若按键较多时,占用的I/O口资源就会过多,为此就引入了矩阵键盘。
本次设计共有0~9、#、*共12个按键,因此引入3*4的矩阵键盘,共需要7个I/O口,7条线分别与单片机P3口相连。
{注:当作为输入时,上拉电阻将其电位拉高,若输入为低电平则可提供电流源;所以P0口如果作为输入时,处在高阻抗状态,只有外接一个上拉电阻才能有效。
摘要在日常生活中,我们经常要通过按键来实现对电子装置的控制,小到手表手机,中到电视电脑,大到各种复杂仪器,都需要通过按键来实现各种操作。
本次课程设计作为实践教学的一个重要环节,将以按键控制显示为主题,以1602液晶、MM74C922解码芯片、AT89C52单片机及其接口芯片为核心构造一个键盘控制显示系统,并使用Proteus软件对所设计的电路进行仿真,仿真结果是在1602液晶上显示所按下的键值。
关键词:Proteus仿真A T89C52 1602液晶MM74C922解码芯片第一章总体设计1.1电路结构分析本次设计的目标为单片机控制的键盘识别显示系统,主要采用AT89C52单片机作为核心,由矩阵键盘电路、译码芯片、液晶显示等模块构成,分别对按键信息和显示电路以及软、硬件各个部分进行控制;本设计采用C言编程来实现对单片机的控制。
实际运作时,单片机会将检测到的按键信号转换成数字,显示于1602液晶上。
系统主要结构可以拆分如下:①矩阵键盘:按键传送输入信息;此键盘采用的是4X4矩阵键盘,能输入0~9,+,—,=,空格,返回,清零。
②键盘识别:矩阵键盘连接的是MM74C922解码芯片,通过解码芯片来识别输入的按键位置。
③AT89C52:采用软件编程来实现按键信息的提取和转换;④1602液晶:用于显示最终被单片机转换过的按键信息。
由以上构思可以设计此按键显示电路。
1.2总体方案设计总体电路原理框图:如图 1.2所示图1.2总体电路原理方框图本次设计分两步来完成,第一步,解码芯片调试系统,将解码芯片接口连接到矩阵键盘作为AT89C52单片机的输入装置,然后以P2口作为输出端并连接一个数码管观察输出结果。
第二步,1602的液晶调试系统,此过程就是将数码管换成1602液晶在进行结果显示。
1.3蜂鸣器模块设计蜂鸣器模块设计如图 1.3所示图 1.3 蜂鸣器模块电路图蜂鸣器的驱动电流比较大一般要500MA~1000MA,所以不能直接接在AT82C52单片机的接口上,需要加一个三极管来进行驱动。
发声源程序如下:#define BEEP() P1^=0x80 //蜂鸣器定义void Sounder() //发生函数{INT8U i;for(i=0;i<100;i++){delay(3);BEEP();}}1.4电路图设计1.4.1解码芯片调试系统电路图如图1.3.1所示:图 1.4.1解码芯片调试系统电路图此电路图为解码芯片调试系统电路图,按键位置是由解码芯片进行识别。
当按下K0键时,解码芯片进行采集DCBA端输出0000,表示第一个键按下,OA允许输出端为高电平有效,此时蜂鸣器发声提示,数码管则显示0。
K9键按下时,解码芯片DCBA端输出0008,表示第九个键按下,OA允许输出端为高电平有效,此时蜂鸣器发声提示,数码管则显示9。
KF键按下时,解码芯片DCBA 端输出0015示第九个键按下,OA允许输出端为高电平有效,此时蜂鸣器发声提示,数码管则显示F。
仿真结果能完成上述功能,则证明调试成功。
1.4.2 总体电路图如图1.3.2所示图 1.4.2 总体电路图此电路为总体电路图设计,当有键按下时,解码芯片会对按键进行识别,并发送相应的代码到P3口,此时蜂鸣器发声提示,经过单片机的处理,按键的值会在1602液晶上进行显示。
如果仿真结果能完成上述功能,则证明调试成功。
第二章 硬件电路2.1 MM74C922解码芯片 2.1.1MM74C922特点及引脚功能MM74C922具有下列特点:1.功耗低,电压3—5V ;2.三态门输出,与LPTTL 兼容;3.输出锁存按下的最后的键;4.用一个电容器就可以消除键盘抖动;5.两键轮回;6.行具有上拉功能;7.具有芯片内或芯片外时钟;8.最大开关电阻为50K Ω。
MM74C922采用18脚双列直插封装,其引脚排列如图2.1.1所示。
各引脚功能如下:Y1—Y4为行键输入端;X1—X4为列键输入端;OSC 为振荡器的外接引线端,可用外部的输入脉冲或电容器;DA —DD 为数据输出端,可与微机直接接口;KBM 为键颤屏蔽端;OE _____为数据输出允许端,低电平有效;DAV为数据输出有效,高电平有效;VCC 为电源端, 接3—5V ;GND 为接地端。
VCC DA DC DD —OE DA V X1X2图2.1.1 MM74C922引脚排列图2.1.2 MM74C92真值表如表2.1.2所示键盘扫描可采用外部时钟或外接电容来执行。
译码器具有芯片的上拉电阻,使开关电阻可以高达50kΩ。
开关矩阵中不需要二极管就可以消除多重开关,内部消颤电路仅需要一个单一电容就可以实现。
当有键按下时,数据输出有效为高电平;当键释放后,数据输出有效返回到低电平。
即使有另外一个键按下,在正常消颤期间后,数据输出有效返回至高电平表明接受新的键输入。
在任何两个开关之间备有两键轮回功能。
即使某一键释放,内部锁存器仍然锁存住按下的最后的键值。
三态门输出便于总线的扩展和运行。
2.21602液晶2.2.1 1602液晶功能引脚如图2.2.1所示图 2.2.1 1602液晶功能引脚2.2.2液晶命令集及双行液晶DDRAM地址如表2.2.2所示表2.2.2 液晶命令集及双行液晶DDRAM地址RS为寄存器选择位RS=0时选择命令寄存/状态寄存器,RS=1时选择数据寄存器I/D=1递增,I/D=0递减S=0时显示屏不移动,S=1时,如果I/D=1且有字符写入时显示屏左移,否则右移D=1显示屏开开,D=0显示屏关C=1时光标处现在地址计数器所指的位置,C=0时光标不出现B=1时光标出现闪烁,B=0光标不闪烁S/C=0时,RL=0则光标左移,否则右移S/C=1时,RL=0则字符和光标左移,否则右移DL=1时数据长度为8位,DL=0时为使用D7~D4共4位,分两次发送一个字节N=0为单行显示,N=1时为双行显示F=1时为5x10点阵字体,F=0时为5x7点阵字体BF=1时LCD忙,BF=0时LCD就绪双行液晶的DDRAM地址2x20 LCD DDRAM(80~93/C0~E3)2.2.3基本操作时序1).读状态:输入:RS=L,W=H,E=H 输出:DB0~DB7=状态2)写指令:输入:RS=L,RW=L,DB0~DB7=指令码,E=高脉冲输出:无3) 读数据:输入:RS=H,RW=H,E=H 输出:DB0~DB7数据4) 写数据:输入:RS=H,RW=L,DB0~DB7数据,E=高脉冲输出:无2.2.3初始化过程1)延时15ms2)写指令38H(不检测忙信号)3)延时5ms4)写指令38H(不检测忙信号)5)延时5ms6)写指令38H(不检测忙信号)7)(以后每次写指令、读/写数据操作之前均需检测忙信号)8)写指令38H:显示模式设置9)写指令08H:显示关闭10)写指令01H:显示清屏11)写指令06H:显示光标移动设置12)写指令0CH:显示开及光标设置2.2.3读操作时序读操作时序如图2.2.4所示图 2.2.4读操作时序读操作程序如下:void Read_LCD_Command(INT8U cmd) //读命令{LCD_BUSY_WAIT();RS_0();RW_0();P2=cmd;delay(5);EN_1();EN_0();}void Read_LCD_Data(INT8U dat) //读数据{LCD_BUSY_WAIT();RS_1();RW_0();P2=dat;delay(5);EN_1();EN_0();}2.2.5写操作时序写操作时序图如图2.2.5图 2.2.5 写操作时序图写操作程序如下:void Write_LCD_Command(INT8U cmd) //写命令{LCD_BUSY_WAIT();RS_0();RW_0();P2=cmd;delay(3);EN_1();EN_0();}void Write_LCD_Data(INT8U dat) //写数据{LCD_BUSY_WAIT();RS_1();RW_0();P2=dat;delay(3);EN_1();EN_0();}2.3 AT89C52单片机AT89C52是一个低电压,高性能CMOS 8位单片机,片内含8k bytes的可反复擦写的Flash只读程序存储器和256 bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元,功能强大的A T89C52单片机可为您提供许多较复杂系统控制应用场合。
AT89C52有40个引脚,32个外部双向输入/输出(I/O)端口,同时内含2个外中断口,3个16位可编程定时计数器,2个全双工串行通信口,2个读写口线,AT89C52可以按照常规方法进行编程,也可以在线编程。
其将通用的微处理器和Flash存储器结合在一起,特别是可反复擦写的Flash存储器可有效地降低开发成本。
实际引脚连线的部分如图2.3图 2.3 AT89C52单片机2.4 数码管译码电路中常用的显示器有LED(数码管)和LCD(液晶显示器)。
这两种显示器都具有线路简单、耗电少、成本低、寿命长等优点。
本系统输出结果选用1个七段数码管显示。
数码管有共阴共阳之分,本系统采用共阴型。
LED的外形结构如图2.4,外部有10个引脚,其中GND脚为公共端也称位选端,其余8个引脚称为段选端,当要使某一位数码管显示某一数字((0-9中的一个)必须在这个数码管的段选端加上与数字显示数字对应的8位段选码(也称字形码),在位选端加上低电平即可。
图2.4 LED数码管结构如下表2.4即两种数码管中数字显示对应的段码:第三章解码芯片调试系统3.1 解码芯片调试系统的4X4矩阵键盘设计,接线图如3.1所示图3.1 解码芯片调试系统的4X4矩阵键盘设计电路图3.2 解码芯片的接口设计,如图3. 2所示解码芯片的A、B、C、D口接P1.0~P1.4, OE口接地始终保持拉低,OA口接P1.7发送允许信号,X1~X4,Y1~Y4,分别与矩阵键盘的X,Y端口相接。
图 3.2 解码芯片接口设计电路图3.3 数码管的接口设计,如图3.3所示数码管的a~g端接在P2.0~P2.7端作为输出显示图 3.3 数码管的接口设计电路图3.4解码芯片软件流程图解码芯片软件流程图如图3.4所示图 3.4 解码芯片调试系统软件流程图3.5 解码芯片调试系统源程序代码 #include <reg52.h>#define INT8U unsigned char #define INT16U unsigned int#define BEEP() P3^=0x80 //蜂鸣器定义#define Key_Pressed ((P1 & 0X80)==0X80) //判断是否有键按下 #define Key_NO (P1 & 0X0F) //判断键值 INT8U code SEG_CODE[]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71 };void delay(INT16U ms) //延时程序INT8U i,j;for(i=0;i<ms;i++){for(j=0;j<110;j++);}}void Sounder() //蜂鸣器{INT8U i;for(i=0;i<100;i++){delay(5);BEEP();}}void main(){P1=0XFF;P0=0x00;P2=0X00;P3=0XFF;while(1){if(Key_Pressed){P2=SEG_CODE[Key_NO]; //显示键值Sounder();}}此程序可以完成4X4矩阵键盘上任意键的显示即0~F的先显示,当有按键按下时,蜂鸣器会进行按键提示。