对于下面的程序存在两个疑问,求解答。
感谢您抽出时间来帮我解决这个问题。因完整程序太长,并且我个人认为这两个问题与其他部分没有关联,因此没有附出完整程序。
步入正题。在下是想,来简单的模拟一个界面显示。定义一个引脚,用一根杜邦线,引脚接地时,显示需要模拟的那个界面,不接地时,是正常状态的界面。用的是12864来显示。
问题一、
程序如下:
void main()//固定界面显示
{
TH0=(65536-46080)/256;
TL0=(65536-46080)%256;
TL0=0x00; //50ms中断定时
ET0=1;
EA=1;
lcd_busy(); //LCD忙状态检测
delay1ms(10);
lcd_init(); //LCD初始化
lcd_pos(0,0);//智能控制
i=0;
while(dis0!='\0')
{ // LCD显示,下面三个均是
write_dat(dis0);
i++;
}
lcd_pos(1,0);//当前水温
i=0;
while(dis2!='\0')
{
write_dat(dis2);
i++;
}
lcd_pos(2,0);//当前水位比
i=0;
while(dis3!='\0')
{
write_dat(dis3);
i++;
}
lcd_pos(3,0);//当前功能显示区
i=0;
while(dis1!='\0')
{
write_dat(dis1);
i++;
}
if(Low==0)//触发模拟自动上水,其中Low是定义的IP脚
{
write_cmd(0x01);
delay1ms(5);
delay(20);
lcd_pos(0,0);
i=0;
while(dis0!='\0')
{
write_dat(dis0);
i++;
}
delay(20);
lcd_pos(1,0);
i=0;
while(dis6!='\0')
{
write_dat(dis6);
i++;
}
delay(20);
lcd_pos(2,0);
i=0;
while(dis12!='\0')
{
write_dat(dis12);
i++;
}
lcd_pos(2,6);
write_sfm1(6,water);
write_cmd(0x90);
delay(20);
lcd_pos(3,0);
i=0;
while(dis7!='\0')
{
write_dat(dis7);
i++;
}
P1=0x00; // 接地,显示一个界面
}
else if(Low==1)//未触发
{
write_cmd(0x01);
delay1ms(5);
delay(20);
lcd_pos(0,0);
i=0;
while(dis0!='\0')
{
write_dat(dis0);
i++;
}
delay(20);
lcd_pos(1,0);
i=0;
while(dis2!='\0')
{
write_dat(dis2);
i++;
}
delay(20);
lcd_pos(2,0);
i=0;
while(dis3!='\0')
{
write_dat(dis3);
i++;
}
delay(20);
lcd_pos(3,0);
i=0;
while(dis1!='\0')
{
write_dat(dis1);
i++;
}
P1=0xff; //正常状态,未接地,显示原界面
}
delay1ms(10);
while(1)
{
keyscan(); // 显示函数
}
}
问题描述:
不知以上程序是否存在问题,个人认为无,但程序结果却有错误,无编译问题,未报错。具体表现如下:
1.当在下烧写完程序后,用杜邦线接Low引脚时,接地和接Vcc都没有正常显示。
2.当在下先用杜邦线接Low引脚再烧写程序时,如果接的是地,它会显示应该显示的界面,如果接的是Vcc,同样都会显示应该显示的界面。但是,当接地或者Vcc时,再把地换成Vcc或者把Vcc换成地,都不显示任何界面,只显示上一次地或Vcc显示的界面。
3.当不用杜邦线接Low引脚时,如果if里面是Low==0时,会一闪而过Low==1应当显示的界面,一闪而过后,显示初始状态界面(初始状态界面就是什么都不做时,也会显示的界面,如同手机桌面),相反的,不再赘述。
综上所述,想请教一下您们,怎么解决这个问题,怎么才能让它正常,接地显示一个,不接地显示一个。还有,接地为0,接Vcc时为1,如果什么都不接,默认为0吗?希望能得到您的帮助!
问题二、
程序如下(同问题一只增加了红色标出的语句):
void main()//固定界面显示
{
TH0=(65536-46080)/256;
TL0=(65536-46080)%256;
TL0=0x00; //50ms定时
ET0=1;
EA=1;
lcd_busy();
delay1ms(10);
lcd_init();
lcd_pos(0,0);//智能控制
i=0;
while(dis0!='\0')
{
write_dat(dis0);
i++;
}
lcd_pos(1,0);//当前水温
i=0;
while(dis2!='\0')
{
write_dat(dis2);
i++;
}
lcd_pos(2,0);//当前水位比
i=0;
while(dis3!='\0')
{
write_dat(dis3);
i++;
}
lcd_pos(3,0);//当前功能显示区
i=0;
while(dis1!='\0')
{
write_dat(dis1);
i++;
}
if(Low==0)//触发模拟自动上水
{
write_cmd(0x01);
delay1ms(5);
delay(20);
lcd_pos(0,0);
i=0;
while(dis0!='\0')
{
write_dat(dis0);
i++;
}
delay(20);
lcd_pos(1,0);
i=0;
while(dis6!='\0')
{
write_dat(dis6);
i++;
}
delay(20);
lcd_pos(2,0);
i=0;
while(dis12!='\0')
{
write_dat(dis12);
i++;
}
lcd_pos(2,6);
write_sfm1(6,water);
write_cmd(0x90);
delay(20);
lcd_pos(3,0);
i=0;
while(dis7!='\0')
{
write_dat(dis7);
i++;
}
P1=0x00;
break;
}
else if(Low==1)//未触发
{
write_cmd(0x01);
delay1ms(5);
delay(20);
lcd_pos(0,0);
i=0;
while(dis0!='\0')
{
write_dat(dis0);
i++;
}
delay(20);
lcd_pos(1,0);
i=0;
while(dis2!='\0')
{
write_dat(dis2);
i++;
}
delay(20);
lcd_pos(2,0);
i=0;
while(dis3!='\0')
{
write_dat(dis3);
i++;
}
delay(20);
lcd_pos(3,0);
i=0;
while(dis1!='\0')
{
write_dat(dis1);
i++;
}
P1=0xff;
break;
}
delay1ms(10);
while(1)
{
keyscan();
}
}
具体如下:
编译报错,如图。不解,求答,谢谢您!
文字版:
Build target 'Target 1'
compiling test1.c...
TEST1.C(136): error C171: 'break': missing enclosing loop
TEST1.C(179): error C171: 'break': missing enclosing loop
Target not created
再次向您表达感谢!
程序一估计是因为芯片本身输出功率问题,如果用锁频或是增加功率的辅助用芯片应该能解决问题。
如果我回答的不对,请谅解!
小编,
首先如果是我的话,我会先定义一个表示Low的变量,比如LOW,一直检测Low引脚,当是高时LOW=1;当是低时LOW=0;其他时候LOW=2;这样就需要一直检测LOW这个变量就好了。不过程序简单的话,检测引脚也没什么不好的是吧
好吧废话少说
第一个问题:应当把检测Low的if语句( if(Low==0)... else if(Low==1)...)放在while(1)里面,这样就能刷新Low状态和12864显示了,这是常识问题
问题二:break;含义是:退出当前循环
小编用在这是想干些什么呢?好像没什么用吧!
小编可以试试我的办法解决一下,如果不行的话,请留言
说的有道理,预设LOW=2会有好处。
问题1:从主程序初始化看没有发现逻辑错误,只感觉if(Low==0)之前的显示语句多余,if(Low==0)之后才对开机显示内容做选择,你遇到的问题比较奇怪。由于你使用杜邦线接控制脚,可能会引入噪波干扰,软件里设置消噪语句试试。
问题2:break使用于跳出当前循环或switch结构,你用在非循环体内,语法错误。
好,谢谢您,条件允许的情况下,在下会试一下的,谢谢您的帮助,感激!
怎么我就看到一个break呢
首先谢谢您的帮助,只是在下愚笨,没太懂您的意思。
按照您的意思,我没设置LOW变量时,直接把原程序放到大循环里,12864屏就会一直闪一直闪,闪一会屏幕什么都不显示了。不知是什么原因。
呃,至于break,当时在下误把if看成了for语句。惭愧。
按照您的意思在下修改了一下程序,但是烧写完后,我的按键都不能用了呢。可能是在下修改错了吧,望您指点一二!
#include<reg52.h>
#include <stdlib.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define LCD_data P0
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
sbit col1=P1^7; //列端口定义
sbit col2=P1^6;
sbit col3=P2^0;
sbit col4=P2^1;
sbit LCD_EN=P3^4;
sbit LCD_RS=P3^5;
sbit LCD_RW=P3^6;
sbit LCD_PSB=P3^7;
sbit _Speak=P3^2 ; //讯响器控制脚
sbit Low=P3^0; //模拟最低水位触发脚
uchar code dis0[]={"****智能控制****"};
uchar code dis1[]={"当前功能显示区"};
uchar code dis2[]={"当前水温: "};
uchar code dis3[]={"当前水位比: 60"};
uchar code dis4[]={"按S19 开始上水"};
uchar code dis5[]={"目标水位比: "};
uchar code dis6[]={"按 S7 停止上水"};
uchar code dis7[]={"上水中..."};
uchar code dis8[]={"按S20 开始加热"};
uchar code dis9[]={"目标水温:"};
uchar code dis10[]={"按 S8 停止加热"};
uchar code dis11[]={"加热中..."};
uchar code dis12[]={"目标水位比: 00"};
uchar code dis13[]={"当前水位比: "};
void delay1ms(uint);
void delay(uchar);
void keyscan();
void write_cmd(uchar cmd);
void write_dat(uchar dat);
void lcd_pos(uchar X,uchar Y);
void write_sfm1(uchar add,uchar date);
void write_sfm2(uchar add,uchar date);
void lcd_init();
bit lcd_busy();
uint num=0,i=0;
uint counter=0,a=0,counter1=0,b=0;
uint water0=0,water1=0,temp=0;
uint m;
uint LOW;
void main()//固定界面显示
{
TH0=(65536-46080)/256;
TL0=(65536-46080)%256; //50ms定时
ET0=1;
EA=1;
lcd_busy();
delay1ms(10);
lcd_init();
lcd_pos(0,0);//智能控制
i=0;
while(dis0!='\0')
{
write_dat(dis0);
i++;
}
lcd_pos(1,0);//当前水温
i=0;
while(dis2!='\0')
{
write_dat(dis2);
i++;
}
lcd_pos(2,0);//当前水位比
i=0;
while(dis3!='\0')
{
write_dat(dis3);
i++;
}
lcd_pos(3,0);//当前功能显示区
i=0;
while(dis1!='\0')
{
write_dat(dis1);
i++;
}
delay1ms(10);
while(1)
{
if(Low==1)
{
LOW=1;
}
else if(Low==0)
{
LOW=0;
}
else
{
LOW=2;
}
if(LOW==1)//触发模拟自动上水
{
TR0=1;//开中断
write_cmd(0x01);
delay1ms(5);
delay(20);
lcd_pos(0,0);
i=0;
while(dis0!='\0')
{
write_dat(dis0);
i++;
}
delay(20);
lcd_pos(1,0);
i=0;
while(dis6!='\0')
{
write_dat(dis6);
i++;
}
delay(20);
lcd_pos(2,0);
i=0;
while(dis13!='\0')
{
write_dat(dis13);
i++;
}
if(water1<=water0)//判断是否上水完毕
{
lcd_pos(2,6);
write_sfm1(6,water1);
write_cmd(0x90);
m=0xfe;
P1=m;
delay1ms(500); //延时
m=_crol_(m,1);
}
else if(water1>water0)
{
TR0=0;//关中断
write_cmd(0x01);
delay1ms(5);
delay(20);
lcd_pos(0,0);
i=0;
while(dis0!='\0')
{
write_dat(dis0);
i++;
}
delay(20);
lcd_pos(1,0);
i=0;
while(dis4!='\0')
{
write_dat(dis4);
i++;
}
delay(20);
lcd_pos(2,0);
i=0;
while(dis13!='\0')
{
write_dat(dis13);
i++;
}
lcd_pos(2,6);
write_sfm1(6,water0);
write_cmd(0x90);
delay(20);
lcd_pos(3,0);
i=0;
while(dis1!='\0')
{
write_dat(dis1);
i++;
}
}
delay(20);
lcd_pos(3,0);
i=0;
while(dis7!='\0')
{
write_dat(dis7);
i++;
}
}
else if(LOW==0)//未触发
{
write_cmd(0x01);
delay1ms(5);
delay(20);
lcd_pos(0,0);
i=0;
while(dis0!='\0')
{
write_dat(dis0);
i++;
}
delay(20);
lcd_pos(1,0);
i=0;
while(dis2!='\0')
{
write_dat(dis2);
i++;
}
delay(20);
lcd_pos(2,0);
i=0;
while(dis13!='\0')
{
write_dat(dis13);
i++;
}
lcd_pos(2,6);
write_sfm1(6,water0);
write_cmd(0x90);
delay(20);
lcd_pos(3,0);
i=0;
while(dis1!='\0')
{
write_dat(dis1);
i++;
}
}
keyscan();
}
}
如果您想看一下我的程序,在下的帖子里提问过,和帖子里面的程序虽然变化稍大,但想实现和表达的基本相同。
再次谢过您了!
首先感谢您的帮助。
可能是在下没把程序全部贴上来,您可能不太理解在下的程序。呃,程序1k行左右,不美,贴上来,几乎很少有人愿意看下去。
噪波干扰,在下第一次听说这个词,我去问下百度,没有查到消噪语句的相关资料,可能是在下没找到吧。方便的话,您愿意为在下讲解一下吗?感激不尽!
至于,break,呃,在下误把if当成for了,这种错误不会再犯了。
不可能啊,您仔细看一下,在下的两个break都用红字标注出来了。
仔细看了下程序,每一个显示都是这样的
- lcd_pos(1,0);//当前水温
- i=0;
- while(dis2!='\0')
- {
- write_dat(dis2);
- i++;
- }
为什么呢
i=0;...i++;你在循环里并没有用到 i
这是我以前写的
- LCD12864_SetWindow(1,1);
- while(Init0[i]!='\0')
- {
- LCD12864_WriteData(Init0[i]); //初始化中
- i++;
- }
是不是应该这样,
你的是怎么显示的,没明白
根据你的描述,用杜邦线连接Low与地模拟按键,通常按键自身会产生噪波,需要软件消噪,虽然用杜邦线固定连接不会自身会产生噪波,但引线过长就会接收环境辐射引入噪波,可能会对判断Low高低电平产生影响。所谓消噪语句就是软件滤波。
不知为何我复制的时候,i 没有复制过来,我也是醉了。
应该都有 i 的,类似下面的:
lcd_pos(1,0);
i=0;
while(dis0!='\0')
{
write_dat(dis0);
i++;
}
问题1,你需要考虑好LCD的显示状态有几种,定义好,直接在while循环中根据条件刷新显示相应的界面就完了,同时注意在进入while大循环前最好复位相应管脚的状态。然后在实际人为改变管脚电平状态时可在IDE里实时仿真看下自己的逻辑对不对,很容易找到毛病。
问题2,你的程序缩减一下大体为:
void main()
{
if(conditions)
{
break;
}
else if(conditions)
{
break;
}
}
你在这里写break有点画蛇添足了,不需要写。
嗯,谢谢您,刚才百度了一下软件滤波的知识,在下会努力尝试一下在程序里面加入的。谢谢您!
谢谢您的回答。可能是没把全部的程序贴上来的原因,其实在下是想通过按键来显示的,按不同的键会有不同的显示。程序自认为没问题,但烧写完后,就会出现一些小问题,最近一直在想办法解决这些小问题,只是在下愚笨,实在找不到,只好求助。
复位管脚的问题在下明白了。
IDE刚才百度了一下,请问是集成开发环境吗,在下第一次听说。您简单说一下怎么使用吗,实时仿真功能。在下不太懂这个呢,若您能指点一二,在下感激不尽。另外,下面的链接推荐的IDE和您说的一样吗?
http://www.oschina.net/news/16563/15-free-ides-for-developers
当时在下写break的时候,是发现12864显示屏没有正常显示,心想是不是程序死在里面了,就写了个break,然后报错了,因为误把if看成for,当成循环结构了,当时没反应过来,就问了问。
再次向您表示感谢!
http://bbs.elecfans.com/jishu_1137593_1_1.html
望您能指点迷津,在下感激不尽!
顶一个 !
我看着还是没有 i 呢
- lcd_pos(1,0);
- i=0;
- while(dis0[i]!='\0')
- {
- write_dat(dis0[i]);
- i++;
- }
不应该是这样吗,数组里的字符挨个显示
我的就是这样的,不知道为什么我手打了一遍,还是没显示。