完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
include
#include #include ***it RS=P2^0; //寄存器选择位,将RS位定义为P2.0引脚 ***it RW=P2^1; //读写选择位,将RW位定义为P2.1引脚 ***it E=P2^2; //使能信号位,将E位定义为P2.2引脚 ***it BF=P1^7; //忙碌标志位, #define NO_KEY_PRESS 0xff /***************************************************** ***************************************************/ unsigned char code tab[]={0xb7,0xee,0xde,0xbe,0xed,0xdd,0xbd,0xeb,0xdb,0xbb}; unsigned char code num[]={"0123456789"}; unsigned long num1,num2,alg; unsigned char flag; void delay(1) { unsigned char i,j; for(i=0;i<10;i++) for(j=0;j<15;j++); } /***************************************************** ***************************************************/ void delay(unsigned char n) { unsigned char i; for(i=0;i } /***************************************************** 函数功能:判断液晶模块的忙碌状态 返回值:result。result=1,忙碌;result=0,不忙 ***************************************************/ unsigned char BusyTest(void) { bit result; RS=0; //根据规定,RS为低电平,RW为高电平时,可以读状态 RW=1; E=1; //E=1,才允许读写 _nop_(); //空操作 _nop_(); _nop_(); _nop_(); //空操作四个机器周期,给硬件反应时间 result=BF; //将忙碌标志电平赋给result E=0; return result; } /***************************************************** 函数功能:将模式设置指令或显示地址写入液晶模块 入口参数:dictate ***************************************************/ void WriteInstruction (unsigned char dictate) { while(BusyTest()==1); //如果忙就等待 RS=0; //根据规定,RS和R/W同时为低电平时,可以写入指令 RW=0; E=0; //E置低电平(根据表8-6,写指令时,E为高脉冲, // 就是让E从0到1发生正跳变,所以应先置"0" _nop_(); _nop_(); //空操作两个机器周期,给硬件反应时间 P1=dictate; //将数据送入P1口,即写入指令或地址 _nop_(); _nop_(); _nop_(); _nop_(); //空操作四个机器周期,给硬件反应时间 E=1; //E置高电平 _nop_(); _nop_(); _nop_(); _nop_(); //空操作四个机器周期,给硬件反应时间 E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令 } /***************************************************** 函数功能:指定字符显示的实际地址 入口参数:x ***************************************************/ void WriteAddress(unsigned char x) { WriteInstruction(x|0x80); //显示位置的确定方法规定为"80H+地址码x" } /***************************************************** 函数功能:将数据(字符的标准ASCII码)写入液晶模块 入口参数:y(为字符常量) ***************************************************/ void WriteData(unsigned char y) { while(BusyTest()==1); RS=1; //RS为高电平,RW为低电平时,可以写入数据 RW=0; E=0; //E置低电平(根据表8-6,写指令时,E为高脉冲, // 就是让E从0到1发生正跳变,所以应先置"0" P1=y; //将数据送入P0口,即将数据写入液晶模块 _nop_(); _nop_(); _nop_(); _nop_(); //空操作四个机器周期,给硬件反应时间 E=1; //E置高电平 _nop_(); _nop_(); _nop_(); _nop_(); //空操作四个机器周期,给硬件反应时间 E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令 } /***************************************************** 函数功能:对LCD的显示模式进行初始化设置 ***************************************************/ void LcdInitiate(void) { delay(15); //延时15ms,首次写指令时应给LCD一段较长的反应时间 WriteInstruction(0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口 delay(5); //延时5ms WriteInstruction(0x38); delay(5); WriteInstruction(0x38); delay(5); WriteInstruction(0x0c); //显示模式设置:显示开,有光标,光标闪烁 delay(5); WriteInstruction(0x06); //显示模式设置:光标右移,字符不移 delay(5); WriteInstruction(0x01); //清屏幕指令,将以前的显示内容清除 delay(5); } unsigned char keyscan() //键盘扫描,返回扫描值 { unsigned char temp1,temp2,key; P0=0xf0; if(P0!=0xf0) { delay(10); if(P0!=0xf0) { temp1=P0; P0=0x0f; _nop_();_nop_();_nop_(); temp2=P0; key=temp1|temp2; while(P0!=0x0f); return key; } } return NO_KEY_PRESS; } unsigned char key_inquiry()//对键盘扫描值译码并显示 { unsigned char i,key; key=keyscan(); if(key!=NO_KEY_PRESS) { if(flag)//按等于号若再次计算则将之前的数值清零 { WriteInstruction(0x01); delay(5); flag=0; } switch(key) { case 0x7e:WriteData('+');return '+'; case 0x7d:WriteData('-');return '-'; case 0x7b:WriteData('*');return '*'; case 0x77:WriteData(0xfd);return '/'; case 0xd7:WriteAddress(0x40);WriteData('=');return '='; case 0xe7:WriteInstruction(0x01);num1=0;num2=0;break;//CE default:break; } for(i=0;i<10;i++) { if(key==tab[i]) { WriteData(num[i]); return i; } } } return NO_KEY_PRESS; } void count()//对计算进行处理,并显示计算后的结果 { unsigned char key,i=0,a[9]; unsigned long num0; key=key_inquiry(); if((key=='+')||(key=='-')||(key=='*')||(key=='/')) { num2=num1; num1=0; alg=key; } if(key<10) { num1=num1*10+key; } if(key=='=') { WriteAddress(0x41); switch(alg)//对算法进行处理 { case '+':num0=num1+num2; break; case '-': if(num2>num1) num0=(num2-num1); if(num2 WriteData('-'); num0=num1-num2; } break; case '*':num0=(num1*num2);break; case '/': if(num1>0) num0=(num2/num1); else WriteData('e'); break; default:num0=0;break; } //显示计算结果 if(0==num0) { if(0!=alg) WriteData('0'); else num0=num1; } while(num0>0) { i++; a[i]=num0%10; //WriteData(num[num0%10]); num0=num0/10; } for(;i>0;i--) { WriteData(num[a[i]]); } num1=0;num2=0;alg=0; flag=1; } } void main(void) //主函数 { num1=0;num2=0; LcdInitiate(); //调用LCD初始化函数 WriteAddress(0x00); while(1) { count(); } }
|
|
相关推荐
3个回答
|
|
本帖最后由 DDL123 于 2016-5-1 21:51 编辑
#include #include #include ***it RS=P2^0; //寄存器选择位,将RS位定义为P2.0引脚 ***it RW=P2^1; //读写选择位,将RW位定义为P2.1引脚 ***it E=P2^2; //使能信号位,将E位定义为P2.2引脚 ***it BF=P1^7; //忙碌标志位, #define NO_KEY_PRESS 0xff /***************************************************** ***************************************************/ unsigned char code tab[]={0xb7,0xee,0xde,0xbe,0xed,0xdd,0xbd,0xeb,0xdb,0xbb}; unsigned char code num[]={"0123456789"}; unsigned long num1,num2,alg; unsigned char flag; //void delay() //{ // unsigned char i,j; // for(i=0;i<10;i++) // for(j=0;j<15;j++); //} /***************************************************** ***************************************************/ void delay(unsigned char n) { unsigned char i,j; for(i=0;i } /***************************************************** 函数功能:判断液晶模块的忙碌状态 返回值:result。result=1,忙碌;result=0,不忙 ***************************************************/ bit BusyTest(void) { bit result=0; RS=0; //根据规定,RS为低电平,RW为高电平时,可以读状态 RW=1; E=1; //E=1,才允许读写 _nop_(); //空操作 _nop_(); _nop_(); _nop_(); //空操作四个机器周期,给硬件反应时间 result=BF; //将忙碌标志电平赋给result E=0; return result; } /***************************************************** 函数功能:将模式设置指令或显示地址写入液晶模块 入口参数:dictate ***************************************************/ void WriteInstruction (unsigned char dictate) { while(BusyTest()==1); //如果忙就等待 RS=0; //根据规定,RS和R/W同时为低电平时,可以写入指令 RW=0; E=0; //E置低电平(根据表8-6,写指令时,E为高脉冲, // 就是让E从0到1发生正跳变,所以应先置"0" _nop_(); _nop_(); //空操作两个机器周期,给硬件反应时间 P1=dictate; //将数据送入P1口,即写入指令或地址 _nop_(); _nop_(); _nop_(); _nop_(); //空操作四个机器周期,给硬件反应时间 E=1; //E置高电平 _nop_(); _nop_(); _nop_(); _nop_(); //空操作四个机器周期,给硬件反应时间 E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令 } /***************************************************** 函数功能:指定字符显示的实际地址 入口参数:x ***************************************************/ void WriteAddress(unsigned char x) { WriteInstruction(x|0x80); //显示位置的确定方法规定为"80H+地址码x" } /***************************************************** 函数功能:将数据(字符的标准ASCII码)写入液晶模块 入口参数:y(为字符常量) ***************************************************/ void WriteData(unsigned char y) { while(BusyTest()==1); RS=1; //RS为高电平,RW为低电平时,可以写入数据 RW=0; E=0; //E置低电平(根据表8-6,写指令时,E为高脉冲, // 就是让E从0到1发生正跳变,所以应先置"0" P1=y; //将数据送入P0口,即将数据写入液晶模块 _nop_(); _nop_(); _nop_(); _nop_(); //空操作四个机器周期,给硬件反应时间 E=1; //E置高电平 _nop_(); _nop_(); _nop_(); _nop_(); //空操作四个机器周期,给硬件反应时间 E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令 } /***************************************************** 函数功能:对LCD的显示模式进行初始化设置 ***************************************************/ void LcdInitiate(void) { delay(15); //延时15ms,首次写指令时应给LCD一段较长的反应时间 WriteInstruction(0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口 delay(5); //延时5ms WriteInstruction(0x38); delay(5); WriteInstruction(0x38); delay(5); WriteInstruction(0x0c); //显示模式设置:显示开,有光标,光标闪烁 delay(5); WriteInstruction(0x06); //显示模式设置:光标右移,字符不移 delay(5); WriteInstruction(0x01); //清屏幕指令,将以前的显示内容清除 delay(5); } unsigned char keyscan() //键盘扫描,返回扫描值 { unsigned char temp1,temp2,key; P0=0xf0; if(P0!=0xf0) { delay(10); if(P0!=0xf0) { temp1=P0; P0=0x0f; _nop_();_nop_();_nop_(); temp2=P0; key=temp1|temp2; while(P0!=0x0f); return key; } } return NO_KEY_PRESS; } unsigned char key_inquiry()//对键盘扫描值译码并显示 { unsigned char i,key; key=keyscan(); if(key!=NO_KEY_PRESS) { if(flag)//按等于号若再次计算则将之前的数值清零 { WriteInstruction(0x01); delay(5); flag=0; } switch(key) { case 0x7e:WriteData('+');return '+'; case 0x7d:WriteData('-');return '-'; case 0x7b:WriteData('*');return '*'; case 0x77:WriteData(0xfd);return '/'; case 0xd7:WriteAddress(0x40);WriteData('=');return '='; case 0xe7:WriteInstruction(0x01);num1=0;num2=0;break;//CE default:break; } for(i=0;i<10;i++) { if(key==tab) { WriteData(num); return i; } } } return NO_KEY_PRESS; } void count()//对计算进行处理,并显示计算后的结果 { unsigned char key,i=0,a[9]; unsigned long num0; key=key_inquiry(); if((key=='+')||(key=='-')||(key=='*')||(key=='/')) { num2=num1; num1=0; alg=key; } if(key<10) { num1=num1*10+key; } if(key=='=') { WriteAddress(0x41); switch(alg)//对算法进行处理 { case '+':num0=num1+num2; break; case '-': if(num2>num1) num0=(num2-num1); if(num2 WriteData('-'); num0=num1-num2; } break; case '*':num0=(num1*num2);break; case '/': if(num1>0) num0=(num2/num1); else WriteData('e'); break; default:num0=0;break; } //显示计算结果 if(0==num0) { if(0!=alg) WriteData('0'); else num0=num1; } while(num0>0) { i++; a=num0%10; //WriteData(num[num0%10]); num0=num0/10; } for(;i>0;i--) { WriteData(num[a]); } num1=0;num2=0;alg=0; flag=1; } } void main(void) //主函数 { num1=0;num2=0; LcdInitiate(); //调用LCD初始化函数 WriteAddress(0x00); while(1) { count(); } } 调试合适了 以后注意函数的写法 |
|
|
|
|
|
路过学习,谢谢分享。。。。。。。。。。。。
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
4540 浏览 3 评论
5828 浏览 1 评论
6102 浏览 0 评论
Protues中自己封装的芯片元件无Program File、Clock Frequency选项怎么解决,求求大神了!
7838 浏览 1 评论
基于51单片机的车辆倒车雷达报警系统,HC-SR04超声波测距,全套资料
1224 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-24 07:23 , Processed in 0.567522 second(s), Total 81, Slave 63 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号