完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
本帖最后由 夏末的感伤 于 2015-12-20 14:06 编辑
前几天利用手中的1602做一个计算器,感觉程序也不是太难,但是做起来却问题一大包(眼高手低了) ,程序不是这有问题,就是那有问题,调试了几天无果,直接感到崩溃!!(实在是找不到那又有问题了),所以来到论坛求助 问题: 1:按下等于键没有反应(显示0) 下面是程序,1602的部分没有问题 #include #include #define uchar unsigned char; #define uint unsigned int ; typedef unsigned char BYTE; //用BYTE代替unsigned char typedef bit BOOL; // 用BOOL代替bit uchar table [ ]={0x7e,0xee,0xed,0xeb,0xde,0xdd,0xdb,0xbe,0xbd,0xbb};//键盘真值表,扫描查值; uchar result[16];//运算结果显示存储 uchar keyvalue;//存放键盘的值 uchar f=0,c=0; uint num1=0,num2=0,num0;//输入数字的缓冲 ***it LCD_RS = P2^7; //复位端 ***it LCD_RW = P2^6; //写数据端 ***it LCD_EP = P2^5; //使能端 /****************延时函数************************/ delay(int ms) { //延时子程序 int i; while(ms--) { for(i = 0; i< 250; i++) { _nop_(); //空执行 _nop_(); _nop_(); _nop_(); } } } /****************侧忙函数************************/ BOOL lcd_bz() { BOOL result; LCD_RS = 0; LCD_RW = 1; LCD_EP = 1; _nop_(); _nop_(); _nop_(); _nop_(); result = (BOOL)(P0 & 0x80); //检测P0最高位是否为1 LCD_EP = 0; return result;//返回侧忙结果 } /****************写命令函数************************/ lcd_wcmd(BYTE cmd) { // 写入指令数据到LCD while(lcd_bz()); LCD_RS = 0; LCD_RW = 0; LCD_EP = 0; _nop_(); _nop_(); P0 = cmd; //将8位指令通过P0口传给1602 _nop_(); _nop_(); //用于产生一个脉冲宽度 _nop_(); _nop_(); LCD_EP = 1; _nop_(); _nop_(); _nop_(); _nop_(); LCD_EP = 0; } lcd_pos(BYTE pos) { //设定显示位置 lcd_wcmd(pos | 0x80); } /****************写数据函数************************/ lcd_wdat(BYTE dat) { //写入字符显示数据到LCD while(lcd_bz()); LCD_RS = 1; LCD_RW = 0; LCD_EP = 0; P0 = dat; //将8位数据通过P0口传给1602 _nop_(); _nop_(); //用于产生一个脉冲宽度 _nop_(); _nop_(); LCD_EP = 1; _nop_(); _nop_(); _nop_(); _nop_(); LCD_EP = 0; } lcd_init() { //LCD初始化设定 lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据 delay(1); lcd_wcmd(0x0c); //显示开,关光标 delay(1); lcd_wcmd(0x06); //移动光标 delay(1); lcd_wcmd(0x01); //清除LCD的显示内容 delay(1); } ************************************************************************************************************ !!!!!!!!!!!!!!!!!!!!!有问题地方的在这里往下!!!!!!!!!!!!!!!!!!! /**********************************************/ void display()//运算结果处理以方便显示 { char i=0; if(num0==0)//如果等于0,则显示0 lcd_wdat(0x30); while(num0>0) { i++; result=num0%10; num0=num0/10; } for(i;i>0;i--) { lcd_wdat(result[ i ]+0x30); delay(1); } } void count() { switch(c)//根据c的值进行不同的操作 { case 1:num0=num1+num2;break; case 2:num0=num1-num2;break; case 3:num0=num1*num2;break; case 4:num0=num1/num2;break; } display();//1602显示处理 num1=0;//初始化值,否则影响下一次的计算 num2=0; c=0; } uchar scanf() { unsigned char key,temp1,temp2,a; P1=0xf0; if(P1!=0xf0) { delay(10); if(P1!=0xf0) { temp1=P1; P1=0x0f; temp2=P1; key=temp1|temp2; while(P1!=0x0f); //松手检测 switch(key) { case 0xe7:lcd_wdat('+');c=1;break; case 0xd7:lcd_wdat('-');c=2;break; case 0xb7:lcd_wdat('*');c=3;break; case 0x77:lcd_wdat('/');c=4;break; case 0x7b:lcd_wdat('=');return'='; case 0x7d:lcd_wdat('.');break; } for(a=0;a<10;a++) { if(key==table[a]) { f=1;//表示有键被按下 return a;//返回键盘值 } } } } } jreturn()// { char i; i=scanf(); if(c!=0)//有运算操作符被按下 { num1=num2; num2=0; } if(f==1&&i<10)//f=1表示有键被按下&&i值是数字 i { num2=num2*10+i; lcd_wdat(i+0x30);//1602显示 f=0;//重新赋值,直到键再被按下f=1; } if(i=='=')//i等于=,进入计算程序 count(); } /****************主函数************************/ main() { lcd_init();// 初始化LCD delay(10); while(1) { lcd_wcmd(0x06);//向右移动光标 lcd_pos(0);//设置显示位置为第一行的第1个字符 while(1) jreturn(); } } |
|
相关推荐
9个回答
|
|
本帖最后由 夏末的感伤 于 2016-4-4 15:21 编辑
此程序为正确的 /******************************************* 经验:此程序写完感觉逻辑没有问题,但是老是出现莫名其妙的结果, 后来才知道是“全局变量”没有正确的赋值导致的,现在才感到要谨慎 使用全局变量的重要性 各个函数之间要有“强内聚,低耦合”这个真的很重要,只有各个函数之间 没有太多的联系,调试工作才会进行得更加顺利 *******************************************/ #include #include #include #define uchar unsigned char; #define uint unsigned int ; extern void ds18b20(); typedef unsigned char BYTE; //用BYTE代替unsigned char typedef bit BOOL; // 用BOOL代替bit uchar table [ ]={0x7e,0xee,0xed,0xeb,0xde,0xdd,0xdb,0xbe,0xbd,0xbb};//键盘真值表,扫描查值; uchar result[16];//运算结果显示存储 extern uchar test[4]; bit minus;//负号标志位 uchar keyvalue;//存放键盘的值 uchar rnumber=0;//最终值的位数 uchar f=0,c=0,t; unsigned long int num1=0,num2=0,num0;//输入数字的缓冲 ***it LCD_RS = P2^7; //复位端 ***it LCD_RW = P2^6; //写数据端 ***it LCD_EP = P2^5; //使能端 /****************延时函数************************/ delay(int ms) { //延时子程序 int i; while(ms--) { for(i = 0; i< 250; i++) { _nop_(); //空执行 _nop_(); _nop_(); _nop_(); } } } /****************侧忙函数************************/ BOOL lcd_bz() { BOOL result; LCD_RS = 0; LCD_RW = 1; LCD_EP = 1; _nop_(); _nop_(); _nop_(); _nop_(); result = (BOOL)(P0 & 0x80); //检测P0最高位是否为1 LCD_EP = 0; return result;//返回侧忙结果 } /****************写命令函数************************/ lcd_wcmd(BYTE cmd) { // 写入指令数据到LCD while(lcd_bz()); LCD_RS = 0; LCD_RW = 0; LCD_EP = 0; _nop_(); _nop_(); P0 = cmd; //将8位指令通过P0口传给1602 _nop_(); _nop_(); //用于产生一个脉冲宽度 _nop_(); _nop_(); LCD_EP = 1; _nop_(); _nop_(); _nop_(); _nop_(); LCD_EP = 0; } lcd_pos(BYTE pos) { //设定显示位置 lcd_wcmd(pos | 0x80); } /****************写数据函数************************/ lcd_wdat(BYTE dat) { //写入字符显示数据到LCD while(lcd_bz()); LCD_RS = 1; LCD_RW = 0; LCD_EP = 0; P0 = dat; //将8位数据通过P0口传给1602 _nop_(); _nop_(); //用于产生一个脉冲宽度 _nop_(); _nop_(); LCD_EP = 1; _nop_(); _nop_(); _nop_(); _nop_(); LCD_EP = 0; } lcd_init() { //LCD初始化设定 lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据 delay(1); lcd_wcmd(0x0c); //显示开,关光标 delay(1); lcd_wcmd(0x06); //移动光标 delay(1); lcd_wcmd(0x01); //清除LCD的显示内容 delay(1); } /**********************************************/ void display()//显示函数 { char g; lcd_wcmd(0x04);//向左移动光标 delay(1); lcd_pos(0x4F); //设置显示位置为第二行的第16个字符 delay(1); for(g=0;g lcd_wdat(result[ g ]+0x30); delay(1); } rnumber=0;//位数符0 if(minus==1)//结果是负数 { lcd_wdat('-'); minus=0; } } void count() { switch(t)//根据c的值进行不同的操作 { case 1:num0=num1+num2;break; case 2:if(num1>num2) num0=num1-num2; if(num1 num0=num2-num1; minus=1; }break; case 3:num0=num1*num2;break; case 4:num0=num1/num2;break; } if(num0==0)//如果等于0,则显示0 { result[0]=0; rnumber++; } if(t==0)//按下第一个键后,直接按了等于键 num0=num1; while(num0>0)//显示处理 把数字存储到result数组中 { result[rnumber] = num0%10; num0=num0 / 10; rnumber++; } display();//1602显示处理 num1=0;//初始化值,否则影响下一次的计算 num2=0; t=0; } uchar scanf() { unsigned char key,temp1,temp2,a; P1=0xf0; if(P1!=0xf0) { delay(10); if(P1!=0xf0) { temp1=P1; P1=0x0f; temp2=P1; key=temp1|temp2; while(P1!=0x0f); //松手检测 switch(key) { case 0xe7:lcd_wdat('+');c=1;break; case 0xd7:lcd_wdat('-');c=2;break; case 0xb7:lcd_wdat('*');c=3;break; case 0x77:lcd_wdat('/');c=4;break; case 0x7b:lcd_wdat('=');return'='; case 0x7d:lcd_wdat('.');break;; } for(a=0;a<10;a++) { if(key==table[a]) { f=1;//表示有键被按下 return a;//返回键盘值 } } } } } jreturn()// { char i; i=scanf(); if(c!=0)//有运算操作符被按下 { num1=num2; num2=0; t=c; c=0; } if(f==1&&i<10)//f=1表示有键被按下&&i值是数字 { num2=num2*10+i; lcd_wdat(i+0x30);//1602显示 f=0;//重新赋值,直到键再被按下f=1; } if(i=='=')//i等于=,进入计算程序 count(); } /****************主函数************************/ main() { lcd_init();// 初始化LCD delay(10); /* while(1) { ds18b20(); if(g>0) lcd_wdat(1+0x30); if(g==0) lcd_wdat(2+0x30); if(g<0) lcd_wdat(3+0x30); }*/ while(1) { lcd_wcmd(0x06);//向右移动光标 lcd_pos(0);//设置显示位置为第一行的第1个字符 while(1) jreturn(); } } |
|
|
|
void display()//运算结果处理以方便显示
{ char i=0; if(num0==0)//如果等于0,则显示0 lcd_wdat(0x30); while(num0>0) { i++; result=num0%10; // result是数组,这句能编译通过? num0=num0/10; } ... } 首先你先注释其它代码,看你按下一个键,能不能把键值正确显示出来,以此确认你的按键扫描程序没问题。其次你的jreturn();调用一次最多只能处理一个按键。而你的c是全局变量,一旦不为0,每次进jreturn()都会发生, if(c!=0)//有运算操作符被按下 { num1=num2; num2=0; } 只有等到你按下=键才会在count()中把c清0,这样会造成什么问题你自己想
最佳答案
|
|
|
|
|
|
|
|
谢谢你的回答,数组晕本的代码是没有问题的,只是复制错了。原因就是全局变量c的原因。非常感激你的帮助, |
|
|
|
你好,看了你的程序,全局变量c的原因是啥,不太懂,你能发次正确的代码我看看嘛?我也是学习52板,好奇你的这个计算器
|
|
|
|
本帖最后由 夏末的感伤 于 2015-12-22 12:10 编辑
*******************************************/ #include #include #define uchar unsigned char; #define uint unsigned int ; typedef unsigned char BYTE; //用BYTE代替unsigned char typedef bit BOOL; // 用BOOL代替bit uchar table [ ]={0x7e,0xee,0xed,0xeb,0xde,0xdd,0xdb,0xbe,0xbd,0xbb};//键盘真值表,扫描查值; uchar result[16];//运算结果显示存储 uchar keyvalue;//存放键盘的值 uchar f=0,c=0,t; unsigned long int num1=0,num2=0,num0;//输入数字的缓冲 ***it LCD_RS = P2^7; //复位端 ***it LCD_RW = P2^6; //写数据端 ***it LCD_EP = P2^5; //使能端 /****************延时函数************************/ delay(int ms) { //延时子程序 int i; while(ms--) { for(i = 0; i< 250; i++) { _nop_(); //空执行 _nop_(); _nop_(); _nop_(); } } } /****************侧忙函数************************/ BOOL lcd_bz() { BOOL result; LCD_RS = 0; LCD_RW = 1; LCD_EP = 1; _nop_(); _nop_(); _nop_(); _nop_(); result = (BOOL)(P0 & 0x80); //检测P0最高位是否为1 LCD_EP = 0; return result;//返回侧忙结果 } /****************写命令函数************************/ lcd_wcmd(BYTE cmd) { // 写入指令数据到LCD while(lcd_bz()); LCD_RS = 0; LCD_RW = 0; LCD_EP = 0; _nop_(); _nop_(); P0 = cmd; //将8位指令通过P0口传给1602 _nop_(); _nop_(); //用于产生一个脉冲宽度 _nop_(); _nop_(); LCD_EP = 1; _nop_(); _nop_(); _nop_(); _nop_(); LCD_EP = 0; } lcd_pos(BYTE pos) { //设定显示位置 lcd_wcmd(pos | 0x80); } /****************写数据函数************************/ lcd_wdat(BYTE dat) { //写入字符显示数据到LCD while(lcd_bz()); LCD_RS = 1; LCD_RW = 0; LCD_EP = 0; P0 = dat; //将8位数据通过P0口传给1602 _nop_(); _nop_(); //用于产生一个脉冲宽度 _nop_(); _nop_(); LCD_EP = 1; _nop_(); _nop_(); _nop_(); _nop_(); LCD_EP = 0; } lcd_init() { //LCD初始化设定 lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据 delay(1); lcd_wcmd(0x0c); //显示开,关光标 delay(1); lcd_wcmd(0x06); //移动光标 delay(1); lcd_wcmd(0x01); //清除LCD的显示内容 delay(1); } /**********************************************/ void display()//运算结果处理以方便显示 { char i=0,g; if(num0==0)//如果等于0,则显示0 lcd_wdat(0x30); while(num0>0) { result=num0%10; num0=num0/10; i++; } lcd_wcmd(0x04);//向左移动光标 delay(1); lcd_pos(0x4F); //设置显示位置为第二行的第16个字符 delay(1); for(g=0;g { lcd_wdat(result[ g ]+0x30); delay(1); } } void count() { switch(t)//根据t的值进行不同的操作 { case 1:num0=num1+num2;break; case 2:num0=num1-num2;break; case 3:num0=num1*num2;break; case 4:num0=num1/num2;break; } display();//1602显示处理 num1=0;//初始化值,否则影响下一次的计算 num2=0; t=0; } uchar scanf() { unsigned char key,temp1,temp2,a; P1=0xf0; if(P1!=0xf0) { delay(10); if(P1!=0xf0) { temp1=P1; P1=0x0f; temp2=P1; key=temp1|temp2; while(P1!=0x0f); //松手检测 switch(key) { case 0xe7:lcd_wdat('+');c=1;break; case 0xd7:lcd_wdat('-');c=2;break; case 0xb7:lcd_wdat('*');c=3;break; case 0x77:lcd_wdat('/');c=4;break; case 0x7b:lcd_wdat('=');return'='; case 0x7d:lcd_wdat('.');break;; } for(a=0;a<10;a++) { if(key==table[a]) { f=1;//表示有键被按下 return a;//返回键盘值 } } } } } jreturn()// { char i; i=scanf(); if(c!=0)//有运算操作符被按下 { num1=num2; num2=0; t=c;//把c的值赋给t c=0;//c值初始化,不然会一直执行,导致错误 } if(f==1&&i<10)//f=1表示有键被按下&&i值是数字 { num2=num2*10+i; lcd_wdat(i+0x30);//1602显示 f=0;//重新赋值,直到键再被按下f=1; } if(i=='=')//i等于=,进入计算程序 count(); } /****************主函数************************/ main() { lcd_init();// 初始化LCD delay(10); while(1) { lcd_wcmd(0x06);//向右移动光标 lcd_pos(0);//设置显示位置为第一行的第1个字符 while(1) jreturn(); } } |
|
|
|
不对啊 result=num0%10;这句话怎么说编译错误 新手小白 麻烦大神解释下 |
|
|
|
如果还没有解决请说一下具体的错误信息 |
|
|
|
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-LCD显示图片编程示例之介绍mmap
551 浏览 0 评论
《DNESP32S3使用指南-IDF版_V1.6》第二章 常用的C语言知识点
910 浏览 0 评论
【RA-Eco-RA2E1-48PIN-V1.0开发板试用】(第三篇)ADC采集+PWM输出
575 浏览 0 评论
《DNK210使用指南 -CanMV版 V1.0》第四十五章 人脸识别实验
572 浏览 0 评论
1221 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
11769 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-23 18:35 , Processed in 0.789734 second(s), Total 92, Slave 73 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号