久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3047|回復: 9
打印 上一主題 下一主題
收起左側

單片機遙控控制流水燈的開和關,程序出現了死循環沒有跳出

[復制鏈接]
跳轉到指定樓層
樓主
ID:237797 發表于 2019-10-17 16:27 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
自己51單片機寫的用遙控器來控制流水燈開和關,現在遙控可以打開流水燈工作,不能關閉。出現問題的原因是在流水燈程序里出現了死循環沒有跳出來,有啥解決思路?

單片機源程序如下:
  1. #include<reg51.h>
  2. #include<intrins.h>
  3. sbit ADDR0 = P1^0;
  4. sbit ADDR1 = P1^1;
  5. sbit ADDR2 = P1^2;
  6. sbit ADDR3 = P1^3;
  7. sbit ENLED = P1^4;
  8. sbit LED1 = P0^0;



  9. typedef unsigned char uint8;
  10. typedef unsigned int uint16;

  11. uint8 dir = 0;                //移位方向
  12. uint8 shift = 0x01;                //循環變量
  13. uint16 i = 0;

  14. extern bit irflag;
  15. extern unsigned char ircode[4];
  16. extern void InitInfrared();
  17. void LshiftRshift();


  18. void main()
  19. {
  20.         EA = 1;
  21.         ADDR0 = 0;
  22.         ADDR1 = 1;
  23.         ADDR2 = 1;
  24.         ADDR3 = 1;
  25.         ENLED = 0;

  26.         InitInfrared();

  27.         while (1)
  28.         {
  29.                 if (irflag)
  30.                 {
  31.                         irflag = 0;
  32.                         if (ircode[2] == 0x45)          //0X45  遙控器鍵值
  33.                         {
  34.                                 LshiftRshift();
  35.                         }
  36.                         else if (ircode[2] == 0x46)          
  37.                         {
  38.                                 ENLED = 1;
  39.                         }
  40.                        
  41.                 }
  42.         }
  43. }


  44. void LshiftRshift()
  45. {       
  46.         ENLED = 0;
  47.         ADDR3 = 1;

  48.         ADDR0 = 0;
  49.         ADDR1 = 1;                    
  50.         ADDR2 = 1;


  51.         while(1)
  52.         {       
  53.                 P0 = ~shift;
  54.                 for (i=0;i<20000;i++);
  55.                 if (!dir)           //!dir和dir==0 邏輯相同   dir和dir==1 邏輯相同
  56.                 {
  57.                         shift = shift<<1;
  58.                         if (shift == 0x80)
  59.                         {
  60.                                 dir = 1;
  61.                         }
  62.                 }
  63.                 else
  64.                 {
  65.                         shift = shift>>1;
  66.                         if (shift == 0x01)
  67.                         {
  68.                                 dir = 0;
  69.                         }
  70.                 }
  71.         }
  72. }
復制代碼


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:601639 發表于 2019-10-17 17:21 | 只看該作者
設個標志位,工作完成后標志位置0,需要執行時標志位置1
回復

使用道具 舉報

板凳
ID:235200 發表于 2019-10-17 18:30 | 只看該作者
把流水燈LshiftRshift程序中的while(1)改為while(退出條件)就能退出了
回復

使用道具 舉報

地板
ID:237797 發表于 2019-10-18 08:16 | 只看該作者
csmyldl 發表于 2019-10-17 18:30
把流水燈LshiftRshift程序中的while(1)改為while(退出條件)就能退出了

謝謝你的回答,你的方法有效!
回復

使用道具 舉報

5#
ID:237797 發表于 2019-10-18 08:17 | 只看該作者
那個誰和誰 發表于 2019-10-17 17:21
設個標志位,工作完成后標志位置0,需要執行時標志位置1

你說的方法,我試過,不知道是加錯了,不能實現想要的功能
回復

使用道具 舉報

6#
ID:237797 發表于 2019-10-18 17:46 | 只看該作者
本帖最后由 lclbf 于 2019-10-19 10:43 編輯

遙控部分程序如下:#include<reg51.h>

sbit IR_INPUT = P3^3;

bit irflag = 0;
unsigned char ircode[4];

void InitInfrared()
{
        IR_INPUT = 1;
        TMOD &= 0X0F;
        TMOD |= 0X10;
        TR1 = 0;
        ET1 = 0;
        IT1 = 1;
        EX1 = 1;
}

unsigned int GetHighTime()
{
        TH1 = 0;
        TL1 = 0;
        TR1 = 1;
        while (IR_INPUT)
        {
                if (TH1 >= 0X40)
                {
                        break;
                }
        }
        TR1 = 0;
        return (TH1*256 + TL1);
}

unsigned int GetLowTime()
{
        TH1 = 0;
        TL1 = 0;
        TR1 = 1;
        while (!IR_INPUT)
        {
                if (TH1 >= 0X40)
                {
                        break;
                }
        }
        TR1 = 0;
        return (TH1*256 + TL1);
}

void EXINT1_ISR() interrupt 2
{
        unsigned char i,j;
        unsigned char byt;
        unsigned int time;

        time = GetLowTime();
        if ((time<7833)||(time>8755))
        {
                IE1 = 0;
                return;
        }
        time = GetHighTime();
        if ((time<3686)||(time>4608))
        {
                IE1 = 0;
                return;
        }
        for (i=0;i<4;i++)
        {
                for (j=0;j<8;j++)
                {
                        time = GetLowTime();
                        if ((time<313)||(time>718))
                        {
                                IE1 = 0;
                                return;
                        }
                        time = GetHighTime();
                        if ((time>313)&&(time<718))
                        {
                                byt >>= 1;
                        }
                        else if ((time>1345)&&(time<1751))
                        {
                                byt >>= 1;
                                byt |= 0x80;
                        }
                        else
                        {
                                IE1 = 0;
                                return;
                        }
                }
                ircode = byt;
        }
        irflag = 1;
        IE1 = 0;
}

回復

使用道具 舉報

7#
ID:237797 發表于 2019-10-18 17:48 | 只看該作者
lclbf 發表于 2019-10-18 08:16
謝謝你的回答,你的方法有效!

這是按照你說的方法,修改的程序:


#include<reg51.h>

sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;

typedef unsigned char uint8;
typedef unsigned int uint16;


uint16 i = 0;
uint8 dir = 0;                //移位方向
uint8 shift = 0x01;                //循環變量
uint8 LRshiftflag = 0;

extern bit irflag;
extern unsigned char ircode[4];
extern void InitInfrared();
void LshiftRshift();

void main()
{
        EA = 1;

        InitInfrared();

        while (1)
        {
                if (irflag)
                {
                        irflag = 0;
                        if (ircode[2] == 0x45)          //0X45  遙控器鍵值
                        {       
                                LshiftRshift();
                        }
                        else if (ircode[2] == 0x46)          
                        {       
                                ENLED = 1;
                        }
                       
                }
        }
}


void LshiftRshift()
{       
        ENLED = 0;
        ADDR3 = 1;

        ADDR0 = 0;
        ADDR1 = 1;                    
        ADDR2 = 1;


        while(ircode[2] == 0x45) //while(ircode[2] == 0x45)  while(ircode[2] != 0x46)        不能用while(1),會死在里面,跳不出來,不能關
        {       
               
                        P0 = ~shift;
                        for (i=0;i<20000;i++);
                        if (!dir)           //!dir和dir==0 邏輯相同   dir和dir==1 邏輯相同
                        {
                                shift = shift<<1;
                                if (shift == 0x80)
                                {
                                        dir = 1;
                                }
                        }
                        else
                        {
                                shift = shift>>1;
                                if (shift == 0x01)
                                {
                                        dir = 0;
                                }
                        }
        }
}

回復

使用道具 舉報

8#
ID:237797 發表于 2019-10-20 11:14 | 只看該作者
那個誰和誰 發表于 2019-10-17 17:21
設個標志位,工作完成后標志位置0,需要執行時標志位置1

用你說的標志位的方法實現的控制,程序如下:
#include<reg51.h>

sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;

bit sysOn = 0;


typedef unsigned char uint8;
typedef unsigned int uint16;


uint16 i = 0;
uint8 dir = 0;                //移位方向
uint8 shift = 0x01;                //循環變量
uint8 LRshiftflag = 0;

extern bit irflag;
extern unsigned char ircode[4];
extern void InitInfrared();
void LshiftRshift();

void main()
{
        EA = 1;

        InitInfrared();

                while (1)
                {
                        if (irflag)
                        {
                                irflag = 0;
                       
                                if (ircode[2] == 0x45)          //0X45  遙控器鍵值
                                {       
                                        sysOn = 1;
                                }
                                else if (ircode[2] == 0x46)          
                                {       
                                        sysOn = 0;
                                }                               
                        }
                        LshiftRshift();
        }

}


void LshiftRshift()
{       
//        ENLED = 0;                  //注消這部分不能放這個位置,會出現不能關燈
//        ADDR3 = 1;
//
//        ADDR0 = 0;
//        ADDR1 = 1;                    
//        ADDR2 = 1;

                if (sysOn)
                {       
                        ENLED = 0;
                        ADDR3 = 1;
               
                        ADDR0 = 0;
                        ADDR1 = 1;                    
                        ADDR2 = 1;

                        P0 = ~shift;
                        for (i=0;i<20000;i++);
                        if (!dir)           //!dir和dir==0 邏輯相同   dir和dir==1 邏輯相同
                        {
                                shift = shift<<1;
                                if (shift == 0x80)
                                {
                                        dir = 1;
                                }
                        }
                        else  
                        {
                                shift = shift>>1;
                                if (shift == 0x01)
                                {
                                        dir = 0;
                                }
                        }
                }
                else
                {
                ENLED = 1;        //關燈程序
                }

}

回復

使用道具 舉報

9#
ID:237797 發表于 2019-10-20 11:18 | 只看該作者
現在還有個問題,就是關的時候燈在哪里滅,下次開燈接著哪里亮,有沒有辦法每次開燈在同一個地方亮?想到在關燈的時候賦初值,還是不行,會出現下次開燈就是初值的燈亮,不流動了。
回復

使用道具 舉報

10#
ID:542032 發表于 2019-10-20 13:18 | 只看該作者
你這需要把數據存到51的eeprom里,用的時候調用
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日韩一区二区在线看 | 日韩一级精品视频在线观看 | 日韩精品久久久久久 | 欧美日韩亚洲在线 | 国产一区二区在线91 | 成人欧美一区二区三区色青冈 | 亚洲视频在线免费观看 | 欧美一区二区三区视频在线观看 | 99久久精品免费看国产免费软件 | 欧美一区二区三区在线观看 | www.亚洲.com| 夜夜爽99久久国产综合精品女不卡 | 久草热线| 国产在线一区二区三区 | www.天天干.com | 91pron在线 | 亚洲国产精品一区二区久久 | 国产精品一区二区三区久久久 | 国产日韩欧美二区 | 人妖videosex高潮另类 | 天堂久久网 | 黄色一级电影免费观看 | 91久久久久久久久久久 | 国产99精品 | 久久不卡| a视频在线 | 黄色一级大片在线免费看产 | 久久久久久久久99精品 | 美女视频网站久久 | 久久久久久久久久久久久久av | 国产99在线 | 欧美 | 亚洲网站在线观看 | 久久一起草 | 欧美精品网站 | 日韩视频一区在线观看 | 精品视频在线观看 | 国产99久久久国产精品 | 欧美一区二区三区的 | 日本久久网 | 久在线| 国产一区二区三区免费观看视频 |