打印

程序简单问题很纠结!貌似相同的程序,出现不同的效果

[复制链接]
2969|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
沙发
funfactory|  楼主 | 2011-3-13 13:41 | 只看该作者
本帖最后由 funfactory 于 2011-4-9 19:39 编辑

使用特权

评论回复
板凳
funfactory|  楼主 | 2011-3-13 13:42 | 只看该作者
#include<reg51.h>
sbit k1=P1^0;sbit swx=P3^0;sbit gwx=P3^1;
int     disp[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void delay(int z)
        {        int x,y;
         for(x=z;x>0;x--)
                 for(y=120;y>0;y--);
        }
void main()
{        int ge,sh,sbuff;
        while(1)
        {   P0=0x00;
                if(k1==0)
                {delay(5);
                        while(k1==0);
                        sbuff++;       
                }
                sh=sbuff/10%10;
                ge=sbuff%10;
                swx=0;gwx=1;
                P0=disp[sh];
                delay(50);
                gwx=0;swx=1;
                P0=disp[ge];
                delay(50);   }}




        #include<reg51.h>
sbit k1=P1^0;
sbit swx=P3^0;
sbit gwx=P3^1;
int display[]={0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F};
delay(int k){
      int i,j;
          for(i=k;i>0;i--)
          for(j=120;j>0;j--);}
main()
{ int a;
  int sw,gw;
while(1){ P0=0x00;
    if(k1==0){
        delay(5);
        while(k1==0);
        a++;
        }
        sw=a/10%10;
        gw=a%10;
        swx=0;gwx=1;
        P0=display[sw];
        delay(5);
        swx=1;gwx=0;
        P0=display[gw];
        delay(5);  }}

使用特权

评论回复
地板
funfactory|  楼主 | 2011-3-13 13:49 | 只看该作者
下面那个程序数字显示正常,上面那个十位一直在闪,个位显示正常(平静)。
当上面那个程序数码管延时由50改为100时,个位十位都一直在闪。改为5时,十位干脆部显示了。
这两个程序好像差不多啊,上面那程序问题出在哪里,什么原因。?

使用特权

评论回复
5
funfactory|  楼主 | 2011-4-2 19:19 | 只看该作者

使用特权

评论回复
6
sysdriver| | 2011-4-2 22:09 | 只看该作者
如果你知道什么是静态显示和动态扫描显示,就大概知道什么原因了,我描述得详细点吧。

(1)单个数码管的静态显示:
gwx = 0;
P0 = disp[gw];
while(1);
//因为数码管亮之后就不管它了,所以它会一直静态的亮下去。

(2)单个数码管的动态显示:
while(1)
{
         gwx = 0;
         P0 = disp[gw];
         daley_100ms();
         gwx = 1;
         daley_100ms();
}
//让数码管亮一段时间灭一段时间的交替循环,时间的比例就叫占空比,这里是1:1。
//人眼的反应时间大约在100ms左右,如果你延时长了,肯定看到数码管是一闪一闪的。
//如果你延时短了,数码管就不太亮,如果特短,甚至不亮(因为亮的时间短,人眼来不及反应)。
//就这例子来说说,10~20ms就可以了。人眼来不及反应就会认为数码管是一直“静态”着亮。

(3)2个数码管的静态显示:
gwx = 0;
P0 = disp[gw];
swx = 0;
P0 = disp[sw];
while(1);
//最终的结果是2个数码管亮的都是十位数,因为它们共用同一个数据口。
//如果你想让它们亮的是不同的数据,要么用不同的数据口要么就动态扫描显示,你用的是后者。

(4)2个数码管的动态扫描显示:
while(1)
{
         gwx = 0;
         swx = 1;
         P0 = disp[gw];
         daley_10ms();
         gwx = 1;
         swx = 0;
         P0 = disp[sw];
         daley_10ms();
}
//这个时候就是:数码管1亮10ms,2灭10ms;1灭10ms,2亮10ms;.......不停的循环下去。
//根据上面说到的,宏观上它们是同时亮的,微观上是交替着亮,只是我们没反应过来而已。

//50改为100后都在闪,这个好理解吧。但是,50时,十位闪,个位不闪?看不出来。
//改为5时,十位又不亮了?你不是说下面的程序是对的吗?怎么又不亮了?

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
funfactory + 1
7
funfactory|  楼主 | 2011-4-9 19:34 | 只看该作者
正当以为此贴已经浸没在无底沼泽中,今天惊奇的发现有人回帖,更加信息诺狂的是,还是教科书般的讲解。非常感谢您的回帖。应该也花了你不少时间。

使用特权

评论回复
8
funfactory|  楼主 | 2011-4-9 19:35 | 只看该作者
问题基本解决,我把
                swx = 0; gwx = 1;
                P0 = disp[sh];
                delay(5);                        ------------------->从仿真上看,该程序的位选电平一直在跳动(正常),但是段选始终保持在P0 = disp[ge];还是无法理解原因。
            gwx = 0; swx = 1;               
                P0 = disp[ge];
                delay(5);

改为
                swx = 0; gwx = 1;
                P0 = disp[sh];
                delay(5);

            swx = 1; gwx = 0;         
                P0 = disp[ge];
                delay(5);   
第二次位选位置交换一下就一切正常。

使用特权

评论回复
9
funfactory|  楼主 | 2011-4-9 19:36 | 只看该作者
第一个程序有问题的是我自己写的,第二个是同学写的。上课时老师讲解了一遍思路然后自己编写,所以看上去差不多。问题出现后就请教了老师,只是说了问题出在延时上,所以对延时时间一直在修改!所以就出现了一系列现象,如下
(1)
                swx = 0; gwx = 1;
                P0 = disp[sh];
                delay(5);

            gwx = 0; swx = 1;        
                P0 = disp[ge];
                delay(5)
延时5毫秒时,十位没有显示,个位正常,通过protues上看,位选电平一直在跳动(正常),但是段选始终保持在P0 = disp[ge];  。在想!是不是十位延时太短?所以延长十位时间如下
(2)
                swx = 0; gwx = 1;
                P0 = disp[sh];
                delay(50);

            gwx = 0; swx = 1;        
                P0 = disp[ge];
                delay(5);
该程序的现象是个位正常,十位一直在跳动。通过protues上看,位选正常,时间比为5:1,但是段选始终保持在P0 = disp[ge]; 数字0到60显示正常。当延时都为50时,个位正常,十位闪烁跳动的更加厉害!
(3)
                swx = 0; gwx = 1;
                P0 = disp[sh];
                delay(100);

            gwx = 0; swx = 1;        
                P0 = disp[ge];
                delay(100);
个位十位都在闪烁,貌似这个可以理解。



(1)(2)两个程序都只需要把第二次位选改成  swx = 1; gwx = 0;  即可,但是还是不能理解原因,他是怎么执行程序的?

使用特权

评论回复
10
sysdriver| | 2011-4-9 21:39 | 只看该作者
遇到问题就思考,是个非常好的习惯。
为什么换个位置就行?我也看不出来,从理论上来说,是没有道理的,可以尝试往其他方面去想一想。
针对你写的程序,提几点建议。

要养成程序格式规范的习惯,一行写一句程序。你可以参考华为程序规范或者去看看一些开源项目的格式规范。
你提到的是protues?我就不知道你是否在实物上实践过?你可以99%相信protus,但是有人被protus害惨过。
可以的话,系统复习一下C51,动不动来一个int也许会产生错误的。

使用特权

评论回复
11
funfactory|  楼主 | 2011-4-9 22:16 | 只看该作者

使用特权

评论回复
12
xiaoyuan_ly| | 2011-4-10 19:42 | 只看该作者
晕死了,你自己再看看数据和位选的对应情况,我根据你的命名: 应该是 gwx位个位选通线,swx为十位选通线,看看你自己编的。。。   说句实在话,你这叫基本解决-- 太太那个。。。。 按照你的思路,你再加点程序功能模块上去看看。--- 都会让你觉得调好的显示程序,怎么会有变化。

使用特权

评论回复
13
funfactory|  楼主 | 2011-4-11 22:34 | 只看该作者
12# xiaoyuan_ly


问题确实还存在。通过我这几天的实践证明,数码管的显示存在很严重的问题!但是对于一个初学不久的菜鸟来说,实在看不出什么问题,能不能详细的讲讲原因。下礼拜还要做实物,问题解决不了,这几天睡觉都不踏实啊。
最后弱弱的问一句,什么是“程序功能模块”,做什么用!!
求理解!

使用特权

评论回复
14
xiaoyuan_ly| | 2011-4-12 10:36 | 只看该作者
对于“程序功能模块”,我可能没说透点,就是加入其他的功能了,总不会你就这点显示东西就是整个了吧?!比如按键模块,数据控制模块等等。
我的做法是: 1、模块应该尽可能的和其他模块不耦合,如果没办法有些耦合,那你自己注意这些耦合的关键点就可以,在之后的整个程序加入中合理安排就行。2、对于你这个动态显示,你应该在任意一个时刻都知道数码管的显示状态,你做到了吗?? -这样做的好处-(你对数码管的亮度控制的很精确,别说什么闪烁之类的低级问题了) 我相信你没有,否则你就不会这样处理。我的做法一般是:1、中断置显示标记,有且只有执行一次,然后在程序中扫描执行。2、有消显控制。3、控制住整个程序的响应总时间。看看满足显示要求否??!!   ---其实的核心做法:用硬件的显示方法软件程序化来做。

使用特权

评论回复
15
funfactory|  楼主 | 2011-4-12 17:40 | 只看该作者
本帖最后由 funfactory 于 2011-4-12 17:48 编辑

14# xiaoyuan_ly 对于你的解决方案与做法,能不能举个例子(基于原先的程序上)描述一下。这样还是看不怎么明白啊!?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

68

帖子

1

粉丝