微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 对于下面的程序存在两个疑问,求解答。

对于下面的程序存在两个疑问,求解答。

时间:10-02 整理:3721RD 点击:

感谢您抽出时间来帮我解决这个问题。因完整程序太长,并且我个人认为这两个问题与其他部分没有关联,因此没有附出完整程序。
步入正题。在下是想,来简单的模拟一个界面显示。定义一个引脚,用一根杜邦线,引脚接地时,显示需要模拟的那个界面,不接地时,是正常状态的界面。用的是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都用红字标注出来了。

仔细看了下程序,每一个显示都是这样的

  1. lcd_pos(1,0);//当前水温
  2.         i=0;
  3.         while(dis2!='\0')
  4.         {
  5.                 write_dat(dis2);
  6.                 i++;
  7.         }

复制代码


为什么呢
i=0;...i++;你在循环里并没有用到 i
这是我以前写的

  1. LCD12864_SetWindow(1,1);
  2.         while(Init0[i]!='\0')
  3.         {
  4.                 LCD12864_WriteData(Init0[i]);                //初始化中
  5.                 i++;
  6.         }

复制代码


是不是应该这样,
你的是怎么显示的,没明白

根据你的描述,用杜邦线连接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 呢

  1. lcd_pos(1,0);
  2. i=0;
  3. while(dis0[i]!='\0')
  4. {
  5.     write_dat(dis0[i]);
  6.     i++;
  7. }

复制代码


不应该是这样吗,数组里的字符挨个显示

我的就是这样的,不知道为什么我手打了一遍,还是没显示。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top