当前位置:文档之家› 按键及显示实验

按键及显示实验

一、实验原理及电路1、LCD显示器是通过给不同的液晶单元供电,控制其光线的通过与否,从而达到显示的目的。

因此,LCD的驱动控制归于对每个液晶单元通断电的控制,每个液晶单元都对应着一个电极,对其通电,便可使用光线通过(也有刚好相反的,即不通电时光线通过,通电时光线不通过)。

,2、由于LCD已经带有驱动硬件电路,因此模块给出的是总线接口,便于与单片机的总线进行接口。

驱动模块具有八位数据总线,外加一些电源接口和控制信号。

而且还自带显示缓存,只需要将要显示的内容送到显示缓存中就可以实现内容的显示。

由于只有八条数据线,因此常常通过引脚信号来实现地址与数据线复用,以达到把相应数据送到相应显示缓存的目的。

实验电路图二、功能说明设计并实现一4×4键盘的接口,键盘与1602显示单元连接,编写实验程序扫描键盘输入,并将扫描结果送1602显示,键盘采用4×4键盘。

将键盘进行编号记作0—F当按下其中一个按键时将该按键对应的编号在一个1602显示出来,当按下下一个按键时便将这个按键的编号1602上显示出来实验框图四、实验代码#include <reg51.h>#define uchar unsigned char#define uint unsigned int#define lcd_data P3sbit lcd_EN=P2^2;sbit lcd_RW=P2^1;sbit lcd_RS=P2^0;uchar key,a;uchar sys_time1[]="good";uchar sys_time2[]="morning!";uchar sys_time3[]="play";uchar sys_time4[]="basketball!";uchar sys_time5[]="study";uchar sys_time6[]="hard!";unsigned char code key_code[]={0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xB7,0x77 };void delayms(uint ms){uchar t;while(ms--){for(t=0;t<120;t++);}}void delay_20ms(void){uchar i,temp;for(i = 20;i > 0;i--){temp = 248;while(--temp);temp = 248;while(--temp);}}void delay_38us(void){ uchar temp;temp = 18;while(--temp);}void delay_1520us(void){ uchar i,temp;for(i = 3;i > 0;i--){temp = 252;while(--temp);}}uchar lcd_rd_status( ) /*读取lcd1602的状态,主要用于判断忙*/{uchar tmp_sts; //声明变量tmp_stslcd_data = 0xff; //初始化P3口lcd_RW = 1; //RW =1 读lcd_RS = 0; //RS =0 命令,合起来表示读命令(状态)lcd_EN = 1; //EN=1,打开EN,LCD1602开始输出命令数据,100nS 之后命令数据有效tmp_sts = lcd_data; //读取命令到tmp_stslcd_EN = 0; //关掉LCD1602lcd_RW = 0; //把LCD1602设置成写return tmp_sts; //函数返回值tmp_sts}void lcd_wr_com(uchar command ) /*写一个命令到LCD1602*/{while(0x80&lcd_rd_status()); //写之前先判断LCD1602是否忙,看读出的命令的最高位是否为1,为1表示忙,继续读,直到不忙lcd_RW = 0;lcd_RS = 0; //RW=0,RS=0 写命令lcd_data = command; //把需要写的命令写到数据线上lcd_EN = 1;lcd_EN = 0; //EN输出高电平脉冲,命令写入}void lcd_wr_data(uchar wdata ) /*写一个显示数据到lcd1602*/{while(0x80&lcd_rd_status()); //写之前先判断lcd1602是否忙,看读出的命令的最高位是否为1,为1表示忙,继续读,直到不忙lcd_RW = 0;lcd_RS = 1; //RW=0,RS=1 写显示数据lcd_data = wdata ; //把需要写的显示数据写到数据线上lcd_EN = 1;lcd_EN = 0; //EN输出高电平脉冲,命令写入lcd_RS = 0;}void Init_lcd(void) /*初始化lcd1602*/{delay_20ms(); //调用延时lcd_wr_com(0x38); //设置16*2格式,5*8点阵,8位数据接口delay_38us(); //调用延时lcd_wr_com(0x0c); //开显示,不显示光标delay_38us(); //调用延时lcd_wr_com(0x01); //清屏delay_1520us(); //调用延时lcd_wr_com(0x06); //显示一个数据后光标自动+1}void show(){uchar i;Init_lcd(); //调用LCD初始化函数for(i=0;i<16;i++) //显示液晶的第一行{lcd_wr_com(0x80+i); //设置显示的位置if(sys_time1[i]==0x00) //字符串是否结束break;lcd_wr_data(sys_time1[i]);//送显示数据}for(i=0;i<16;i++) //显示液晶的第一行{lcd_wr_com(0xc0+i); //设置显示的位置if(sys_time2[i]==0x00) //判断第二行显示break;lcd_wr_data(sys_time2[i]); //送显示数据}}void show1(){uchar i;Init_lcd(); //调用LCD初始化函数for(i=0;i<16;i++) //显示液晶的第一行{lcd_wr_com(0x80+i); //设置显示的位置if(sys_time3[i]==0x00) //字符串是否结束break;lcd_wr_data(sys_time3[i]);//送显示数据}for(i=0;i<16;i++) //显示液晶的第一行{lcd_wr_com(0xc0+i); //设置显示的位置if(sys_time4[i]==0x00) //判断第二行显示break;lcd_wr_data(sys_time4[i]); //送显示数据}}void show2(){uchar i;Init_lcd(); //调用LCD初始化函数for(i=0;i<16;i++) //显示液晶的第一行{lcd_wr_com(0x80+i); //设置显示的位置if(sys_time5[i]==0x00) //字符串是否结束break;lcd_wr_data(sys_time5[i]);//送显示数据}for(i=0;i<16;i++) //显示液晶的第一行{lcd_wr_com(0xc0+i); //设置显示的位置if(sys_time6[i]==0x00) //判断第二行显示break;lcd_wr_data(sys_time6[i]); //送显示数据}}uchar rdkey() //键盘扫描函数{uchar scan1,scan2,keycode,j;P1=0x0f; //列线置低电平,行线输入状态scan1=P1; //读入行值if((scan1&0x0f)!=0x0f) //判断是否有按键按下{delayms(30); //调用延时程序去抖动scan1=P1; //读入行值if((scan1&0x0f)!=0x0f) //二次判断是否有按键按下{P1=0xf0; //列线作输入,行线置低电平scan2=P1; //读入列值keycode=scan1|scan2; //组合成键编码for(j=0;j<=15;j++) //循环16次{if(keycode== key_code[j])//查表得键值{key=j; //算出最后键值return(key); //返回键值}}}}else P1=0xff;return (16);}void main(){while(1){P1=0x0f;if((P1&0x0f)!=0x0f) //判断是否有键按下{a=rdkey(); //调用键盘扫描函数switch (a){case 0: show(); break;case 1: show1();break;case 2: show2();break;}}}}五、实验过程本实验仪提供了一个4×4的小键盘,向列扫描码地址(0e101H)逐列输出低电平,然后从行码地址(0e103H)读回,如果有键按下,则相应行的值应为低,如果无键按下,由于上拉的作用,行码为高.这样就可以通过输出的列码和读取的行码来判断按下的是什么键。

在判断有键按下后,要有一定的延时,防止键盘抖动。

判断完是哪个键按下后,就通过编程,使1602显示对应的内容。

六、实验小结我很清楚这个实验的目的,表面上我们最终仅仅只是实现了设计要求的基本功能,但我觉得,这次课程设计更加深刻的意义是——从这样一个最基本,简单的实验中,从这样一个完整的过程中我了解一种系统设计的流程,甚至说是一种思路,思维。

从最初拿到题目,分析设计要求以及实现的初步思路,然后去查阅资料进行更加具体的设计这次实验无疑要求我们团队协作,互相配合并且整体上比较全面的统筹设计。

于是,初步规划后,我们开始将系统要实现功能的各个模块单独开来用PROTEUS仿真,并最终将各个模块组合后整体调试。

整个过程中我们在仿真上花费了较长时间,因为知道仿真成功是实现真正硬件电路的基础,仿真是从根本上检验设计者的设计逻辑以及思路的,很好的仿真才能使得设计系统在实现要求功能的基础上更加稳定、简单。

在学习的过程中,也遇到了一些困难,比如开始的时候,由于发送端和接收端的通信协议没有做好,导致数据不能正确的传输,在解决问题的过程中,对于通信协议的实现有了深刻的认识。

相关主题