完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
关于LCD1602与矩阵按键——按键按下时与按键释放时,效果不一致,且按下时乱码。向各位前辈取经!!主要的功能先介绍一下:当按键按下一个键时,lcd显示相应的数字。下面是代码 #include #define uchar unsigned char #define uint unsigned int uchar num[]="0123456789abcdef"; ***it LCD_RS=P2^6; ***it LCD_EN=P2^7; ***it LCD_rw=P2^5; void delay(uint n) //延时 { uint i,j; for(i=n;i>0;i--) for(j=110;j>0;j--); } void LCD_write_com(uchar com) // 写指令函数 { LCD_RS=0; //指令模式 P0=com; delay(5); // 通过延时实现数据传输时序 LCD_EN=1; //允许 delay(5); //使能信号持续一定时间高电平 LCD_EN=0; delay(5); } void LCD_write_data(uchar dat) { LCD_RS=1; //数据模式 P0=dat; delay(5); LCD_EN=1; delay(5); LCD_EN=0; delay(5); } void LCD_init() // LCD 设置 { LCD_RS=0; //指令模式 LCD_rw=0; LCD_write_com(0x38); //设置16x2显示,5x7点阵,8位数据接口 LCD_write_com(0x0c); //00001DCB D=1开显示 C=1显示光标 B=1光标闪烁 LCD_write_com(0x06); //000001NS N=1/0 光标+1/-1 S=1整屏(N=1)左移(N=0)右移 S=0 不移动 LCD_write_com(0x01); //清除屏幕显示 // LCD_write_com(0x80); } void display(uint x,uint y,uchar dat) //显示字符函数 { //y 为 行数选择项 x为显示位置 dat为显示的ASCII码值 uint address; if(y==1) address=0x80+x; else address=0xc0+x; LCD_write_com(address); LCD_write_data(dat); } uchar anasys_key(uchar serial, uchar rate) { switch (serial) { case 0xf7:return(rate+0); case 0xfb:return(rate+1); case 0xfd:return(rate+2); case 0xfe:return(rate+3); default:return(0x00); } } uchar getkey(void) { uint x; P1|=0xff; //高位强制置一 P1&=0x7f; // 扫描置零 if(((x=P1)&0x0f)!=0x0f){x|=0x80;return(anasys_key(x,0));} P1|=0xff; P1&=0xBf; if(((x=P1)&0x0f)!=0x0f){x|=0x40;return(anasys_key(x,4));} P1|=0xff; P1&=0xDf; if(((x=P1)&0x0f)!=0x0f){x|=0x20;return(anasys_key(x,8));} P1|=0xff; P1&=0xEf; if(((x=P1)&0x0f)!=0x0f){x|=0x10;return(anasys_key(x,12));} } void main() { uchar t,tt; delay(400); LCD_init(); // LCD_write_com(0x88); display(0,1,' '); while(1) { t=getkey(); delay(20); /*防抖动*/ tt=getkey(); if((t==tt)&&(t!=0xff)) { while(tt==getkey()); display(1,1,num[t]); //等待按键松开 } } } 这是按下时的图像 这是释放时的图像 |
|
相关推荐
4个回答
|
|
问题主要在按键扫描程序,键值不能锁定。修改如下:
#include #define uchar unsigned char #define uint unsigned int ***it LCD_RS=P2^6; ***it LCD_EN=P2^7; ***it LCD_rw=P2^5; uchar num[]="0123456789abcdefg_"; uchar key=16; //键值变量 /*******100us延时程序********/ void delay(uint x) { uint a,b; for(a=x;a>0;a--) for(b=10;b>0;b--); } /*******1602液晶屏写指令程序********/ void write_com(uchar com) { LCD_EN=0; //初始设置LCD_EN低电平 LCD_RS=0; //允许写指令 P0=com; //传递指令 delay(10); //延时1ms LCD_EN=1; //使能写入 delay(10); //延时1ms LCD_EN=0; //低跳变执行 } /*******1602液晶屏写数据程序********/ void write_date(uchar date) { LCD_EN=0; //初始设置LCD_EN低电平 LCD_RS=1; //允许写数据 P0 =date; //传递数据 delay(10); //延时1ms LCD_EN=1; //使能写入 delay(10); //延时1ms LCD_EN=0; //低跳变执行 } /*******1602液晶屏初始化程序********/ void init() //设置显示模式、 { LCD_rw=0; write_com(0x38);//设置16*2显示,5*7点阵,8位数据接口 write_com(0x01);//显示清零,数据指针清零 // write_com(0x0f);//设置开显示,显示光标,光标闪烁 // write_com(0x0e);//设置开显示,显示光标,光标不闪 write_com(0x0c);//设置开显示,不显光标 write_com(0x06);//设置写一个字符后地址指针加1 // write_com(0x07);//设置写一个字符后整屏左移 write_com(0x80);//数据指针初始化,设置显示初始位置 } void display(uint x,uint y,uchar dat) //显示字符函数 {//y 为 行数选择项 x为显示位置 dat为显示的ASCII码值 uint address; write_com(0x01); if(y==1) address=0x80+x; else address=0xc0+x; write_com(0x01); write_com(address); write_date(dat); } void key_scan() //矩阵键盘扫描函数 { uchar temp1,temp2,temp3; //临时变量 static bit sign=0; //按键自锁标志 static uchar count=0; //消抖计数变量 P1=0xf0; //先给P1赋一个初值 if(P1!=0xf0) //判断P1不等于所赋初值,说明有健按下 { if(sign==0) //如果按键自锁标志=0 { count++; //主循环消抖计数 if(count>=100) //消抖计数自>=100 { count=100; //防止溢出 sign=1; //按键自锁标志置1,键不抬起,按其他键无效 temp1=P1; //temp1反映高4位变化 P1=0x0f; //再给P1赋值0x0f temp2=P1; //temp2反映低4位变化 temp3=temp2|temp1; //temp3=高4位+低4位 switch(temp3) { case 0xee: key= 0; break; case 0xde: key= 1; break; case 0xbe: key= 2; break; case 0x7e: key= 3; break; case 0xed: key= 4; break; case 0xdd: key= 5; break; case 0xbd: key= 6; break; case 0x7d: key= 7; break; case 0xeb: key= 8; break; case 0xdb: key= 9; break; case 0xbb: key=10; break; case 0x7b: key=11; break; case 0xe7: key=12; break; case 0xd7: key=13; break; case 0xb7: key=14; break; case 0x77: key=15; break; } display(0,1,num[key]);//显示键值 } } } else //按键抬起 { sign=0; //按键自锁标志清0 count=0; //消抖计数清0 } } void main() { init(); write_com(0x88); display(0,1,num[key]); while(1) { key_scan(); } }
最佳答案
|
|
|
|
如何能够自己控制按下时 显示的字符或者说 如何保持 按下与释放时字符一致
|
|
|
|
首先,你这个按键检测的程序不标准,其次,按下按键可以显示 东西,说明,按下的那一刻,执行了
display(1,1,num[t]); 那么这个问题就好排查了,自己在研究一下,可以在这句话下面加个蜂鸣器或者LED看看是否确实是按下 执行了显示, 建议你这个按键程序这么写:
|
|
|
|
看你这显示挺正常的
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
479 浏览 0 评论
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-内核编译之初次编译
229 浏览 0 评论
334 浏览 0 评论
165 浏览 0 评论
《DNESP32S3使用指南-IDF版_V1.6》 第十六章 WATCH_DOG实验
496 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
11972 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-19 17:31 , Processed in 0.870475 second(s), Total 77, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号