打印

实现让8个二极管依次以200ms的间隔连续闪烁5次

[复制链接]
1110|22
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
langgq|  楼主 | 2018-10-20 20:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
但是实际运行时发现有问题
#include"reg51.h"
#define uchar unsigned char
#define uint unsigned int
sbit led1=P1^0;
sbit led2=P1^1;
sbit led3=P1^2;
sbit led4=P1^3;
sbit led5=P1^4;
sbit led6=P1^5;
sbit led7=P1^6;
sbit led8=P1^7;
uchar num1;
void main()
{
        TMOD=0x01;
        TH0=(65536-45872)/256;
        TL0=(65536-45872)%256;
        EA=1;
        ET0=1;
        TR0=1;
        led1=1;
        led2=1;
        led3=1;
        led4=1;
        led5=1;
        led6=1;
        led7=1;
        led8=1;
        while(1)
        {
                if((num1==4)||(num1==8)||(num1==12)||(num1==16)||(num1==20))
                {
                        led1=~led1;
                }
                if((num1==24)||(num1==28)||(num1==32)||(num1==36)||(num1==40))
                {        led1=1;
                        led2=~led2;
                }
                if((num1==44)||(num1==48)||(num1==52)||(num1==56)||(num1==60))
                {        led2=1;
                        led3=~led3;
                }
                if((num1==64)||(num1==68)||(num1==72)||(num1==76)||(num1==80))
                {        led3=1;
                        led4=~led4;
                }
                if((num1==84)||(num1==88)||(num1==92)||(num1==96)||(num1==100))
                {        led4=1;
                        led5=~led5;
                }
                if((num1==104)||(num1==108)||(num1==112)||(num1==116)||(num1==120))
                {        led5=1;
                        led6=~led6;
                }
                if((num1==124)||(num1==128)||(num1==132)||(num1==136)||(num1==140))
                {        led6=1;
                        led7=~led7;
                }
                if((num1==144)||(num1==148)||(num1==152)||(num1==156))
                {        led7=1;
                        led8=~led8;
                }                 
                if(num1==160)
                {        
                        led8=~led8;
                        led8=1;
                        num1=0;
                }        
        }        
        }
void T0_time()interrupt 1
        {
                TH0=(65536-45872)/256;
                TL0=(65536-45872)%256;
                num1++;        
        }
沙发
wangzsa| | 2018-10-20 20:28 | 只看该作者

有什么问题?

使用特权

评论回复
板凳
wangzsa| | 2018-10-20 20:31 | 只看该作者
你这个错误关键在num1的处理上,这个变量在不停的被中断累加,在主循环的一次循环处理中可能值会发生变化,导致错误

使用特权

评论回复
地板
zhuww| | 2018-10-20 20:38 | 只看该作者

你这个程序还有明显不合理的地方,加个else合理些,会大大提高效率

使用特权

评论回复
5
langgq|  楼主 | 2018-10-20 20:40 | 只看该作者
哦,哪儿

使用特权

评论回复
6
zhanglli| | 2018-10-20 20:43 | 只看该作者

if((num1==4)||(num1==8)||(num1==12)||(num1==16)||(num1==20))
{
     led1=~led1;
}else
但仍然会有问题


typedef unsigned char U8;

#define BIT0        (1<<0)
#define BIT1        (1<<1)

#define LED0_7        P1

sbit LED0 = P1^0;

bit flag_200ms;

#define ms        /50

void main(void)
{
        U8 stage = 0;

        init()

        while(1)
        {
                if(flag_200ms){
                        flag_200ms = 0;
                        stage++;
                        if(stage >= 8){
                                stage = 0;
                        }

                        switch(stage){
                        default:
                        case 0:
                                LED0 = (LED0_7 & BIT0) ^ BIT0;
                                break;

                        case 1:
                                LED1 = (LED0_7 & BIT1) ^ BIT1;
                                break;

                        case 2:
                        case 3:
                        case 4:
                        case 5:
                        case 6:
                        case 7:
                                ......
                                break
                        }
                }
        }

}


void T0_time()interrupt 1
{
        TH0=(65536-45872)/256;
        TL0=(65536-45872)%256;
        num1++;

        {
                static U8 c = 0;

                if(++c >= 200ms){
                        c = 0;
                        flag_200ms = 1;
                }
        }
}

使用特权

评论回复
7
langgq|  楼主 | 2018-10-20 20:46 | 只看该作者
所有的灯都会闪

使用特权

评论回复
8
langgq|  楼主 | 2018-10-20 20:49 | 只看该作者
虽然现在我还没有发现问题出在什么地方,但是我认为应该不是出在num1上,下面我这程序也是用的num++,运行就很正确
#include"reg51.h"
#define uchar unsigned char
#define uint unsigned int
sbit led1=P1^0;
sbit led2=P1^1;
sbit led3=P1^2;
sbit led4=P1^3;
sbit led5=P1^4;
sbit led6=P1^5;
sbit led7=P1^6;
sbit led8=P1^7;
uchar num1,num2;
void main()
{
        TMOD=0x01;
        TH0=(65536-45872)/256;
        TL0=(65536-45872)%256;
        EA=1;
        ET0=1;
        TR0=1;
        while(1)
        {
        switch(num1)
        {
                case 0:
                while(num1<=20)
                {
                        if(num2==4)
                        {
                                num2=0;
                                led1=~led1;
                        }        
                }
                case 20:
                        while(num1<=40)
                {
                        if(num2==4)
                        {        led1=1;
                                num2=0;
                                led2=~led2;
                        }        
                }
                case 40:
                        while(num1<=60)
                {
                        if(num2==4)
                        {        led2=1;
                                num2=0;
                                led3=~led3;
                        }        
                }
                case 60:
                        while(num1<=80)
                {
                        if(num2==4)
                        {        led3=1;
                                num2=0;
                                led4=~led4;
                        }        
                }
                case 80:
                        while(num1<=100)
                {
                        if(num2==4)
                        {        led4=1;
                                num2=0;
                                led5=~led5;
                        }        
                }
                case 100:
                        while(num1<=120)
                {
                        if(num2==4)
                        {        led5=1;
                                num2=0;
                                led6=~led6;
                        }        
                }
                case 120:
                        while(num1<=140)
                {
                        if(num2==4)
                        {        led6=1;
                                num2=0;
                                led7=~led7;
                        }        
                }
                case 160:
                        while(num1<=180)
                {
                        if(num2==4)
                        {        led7=1;
                                num2=0;
                                led8=~led8;
                        }        
                }led8=1;num1=0;break;
        }
  }
}
void T0_time()interrupt 1
{
                TH0=(65536-45872)/256;
                TL0=(65536-45872)%256;
                num1++;
                num2++;        
}

使用特权

评论回复
9
lium| | 2018-10-20 20:53 | 只看该作者

既然这么认为,我也就不说什么了,

此没有问题只能说明这个没有问题,也只能说明没有看到问题。。。

使用特权

评论回复
10
langgq|  楼主 | 2018-10-20 20:55 | 只看该作者

恩,我是不会放弃治疗的

使用特权

评论回复
11
guoyt| | 2018-10-20 20:58 | 只看该作者

if(num2==4)
{
    num2=0;
    led1=~led1;
  delay(50ms); // 加延时函数就能看出问题
}   

使用特权

评论回复
12
yufe| | 2018-10-20 21:01 | 只看该作者

简单的修改最先的代码

        while(1)
        {
                        uchar t;
                        t = num1;
                        while(t == num1);
                        
                if((num1==4)||(num1==8)||(num1==12)||(num1==16)||(num1==20))
                {
                        led1=~led1;
                }

使用特权

评论回复
13
yufe| | 2018-10-23 17:59 | 只看该作者
定时200ms准不准?
还是先把程序简化。
if((num1==4)||(num1==8)||(num1==12)||(num1==16)||(num1==20))
                {
                        led1=~led1;
                }
先试第一个灯,看对不对。对了,再加第二个灯。。。

使用特权

评论回复
14
llia| | 2018-10-23 18:03 | 只看该作者
~是字节按位取反.  准确的应该是: led1=!led1;

使用特权

评论回复
15
zhanglli| | 2018-10-23 18:06 | 只看该作者
有些编译器不会出问题.  但不能保证所有的编译都正确

使用特权

评论回复
16
wangpe| | 2018-10-23 18:09 | 只看该作者
本逻辑有问题
我前面的说法有些不正确的

本应每中断一次才进行一次主循环处理,这样就逻辑合理了,但LZ的程序是在不停的处理,而CPU相对很快,所以不停的符合条件,不停的闪烁


LZ对num1这个变量的访问还是有些问题,这个变量类似计数器的飞读概念,

建议先赋值给局部变量,再使用局部变量进行判断,这样要可靠多了

使用特权

评论回复
17
wangzsa| | 2018-10-23 18:11 | 只看该作者
楼上说到本质了。 应该在中断里再加一个标志,主程序每处理一次中断溢出、就将改标志清掉。

使用特权

评论回复
18
zhuww| | 2018-10-23 18:15 | 只看该作者
嗯,另外,应该在主程序中加一个变量,移位控制。主循环没理由那么大、那么繁琐。

使用特权

评论回复
19
zhanglli| | 2018-10-23 18:19 | 只看该作者

问题在于num1 == 4 之类的条件成立可持续50ms,而主程序循环跑得很快,在50ms里灯的状态会不停的快速变换
uchar  last_num;
if(last_num == num1)
    continue;
else
    last_num = num1;
后面的处理怎么方便怎么做就好了

使用特权

评论回复
20
zhuww| | 2018-10-23 18:22 | 只看该作者

void  T0_timer()   interrupt 1
{
       num1++;
       if  (num1==4)
       {
                num1=0;
                Bflash=1;
       }
}


uchar  sta=0x01, counter=0;

while(1)
{
          if  (Bflash)
          {
                 Bflash=0;
                 sta=~sta;
                 counter++;

                  if (counter==6)
                  {
                          counter=0;
                          sta=sta<<1;         if (!sta)   sta=0x01;
                  }
                 
                  P1=sta;
          }

使用特权

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

本版积分规则

932

主题

8762

帖子

1

粉丝