欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

單片機紅外遙控控制繼電器 為什么led()子程序無法跳出

[復制鏈接]
跳轉到指定樓層
樓主
這是一個紅外遙控控制繼電器RELAY,并在液晶上顯示遙控編碼,在if(Y0==0x10){RELAY=1;P2=0xff;} else {RELAY=0;led();}中,我設定當遙控按下關閉鍵時關閉繼電器,同時P2全部LED燈關閉,但程序卻無法返回P2=0xff;,我自己大概分析原因應該是led();子函數正常運行,while(1)無法跳出。我用過do while也不行。請問各大神應該怎么修改呢?
  1. #include <intrins.h>
  2. #define  NOP()   _nop_()   /* 定義空指令 */

  3. #define uchar unsigned char
  4. #define uint  unsigned int
  5. #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};

  6. void delay(uchar x);  //x*0.14MS
  7. void delay1(int ms);
  8. void beep(void);
  9. void led();

  10. sbit IRIN = P3^2;         //紅外接收器數據線
  11. sbit RELAY= P1^4;         //繼電器驅動線
  12. sbit BEEP = P1^5;         //蜂鳴器驅動線

  13. uchar IRCOM[7];

  14. uchar cdis1[] = {" REMOTE CONTROL "};
  15. uchar cdis2[] = {"  IR-CODE: --H"};

  16. //LCD IO
  17. sbit LCD_RW = P2^5;
  18. sbit LCD_RS = P2^6;            
  19. sbit LCD_EN = P2^7;


  20. unsigned char Y0;

  21. /*******************************************************************/
  22. /*                                                                 */
  23. /*檢查LCD忙狀態                                                    */
  24. /*lcd_busy為1時,忙,等待。lcd-busy為0時,閑,可寫指令與數據。      */
  25. /*                                                                 */
  26. /*******************************************************************/

  27. bit lcd_busy()
  28. {                          
  29.     bit result;
  30.     LCD_RS = 0;
  31.     LCD_RW = 1;
  32.     LCD_EN = 1;
  33.     delayNOP();
  34.     result = (bit)(P0&0x80);
  35.     LCD_EN = 0;
  36.     return(result);
  37. }

  38. /*******************************************************************/
  39. /*                                                                 */
  40. /*寫指令數據到LCD                                                  */
  41. /*RS=L,RW=L,E=高脈沖,D0-D7=指令碼。                             */
  42. /*                                                                 */
  43. /*******************************************************************/

  44. void lcd_wcmd(uchar cmd)

  45. {                          
  46.    while(lcd_busy());
  47.     LCD_RS = 0;
  48.     LCD_RW = 0;
  49.     LCD_EN = 0;
  50.     _nop_();
  51.     _nop_();
  52.     P0 = cmd;
  53.     delayNOP();
  54.     LCD_EN = 1;
  55.     delayNOP();
  56.     LCD_EN = 0;  
  57. }

  58. /*******************************************************************/
  59. /*                                                                 */
  60. /*寫顯示數據到LCD                                                  */
  61. /*RS=H,RW=L,E=高脈沖,D0-D7=數據。                               */
  62. /*                                                                 */
  63. /*******************************************************************/

  64. void lcd_wdat(uchar dat)
  65. {                          
  66.    while(lcd_busy());
  67.     LCD_RS = 1;
  68.     LCD_RW = 0;
  69.     LCD_EN = 0;
  70.     P0 = dat;
  71.     delayNOP();
  72.     LCD_EN = 1;
  73.     delayNOP();
  74.     LCD_EN = 0;
  75. }

  76. /*******************************************************************/
  77. /*                                                                 */
  78. /*  LCD初始化設定                                                  */
  79. /*                                                                 */
  80. /*******************************************************************/

  81. void lcd_init()
  82. {
  83.     delay1(15);                  
  84.     lcd_wcmd(0x38);      //16*2顯示,5*7點陣,8位數據
  85.     delay1(5);
  86.     lcd_wcmd(0x38);         
  87.     delay1(5);
  88.     lcd_wcmd(0x38);         
  89.     delay1(5);

  90.     lcd_wcmd(0x0c);      //顯示開,關光標
  91.     delay1(5);
  92.     lcd_wcmd(0x06);      //移動光標
  93.     delay1(5);
  94.     lcd_wcmd(0x01);      //清除LCD的顯示內容
  95.     delay1(5);
  96. }

  97. /*******************************************************************/
  98. /*                                                                 */
  99. /*  設定顯示位置                                                   */
  100. /*                                                                 */
  101. /*******************************************************************/

  102. void lcd_pos(uchar pos)
  103. {                          
  104.   lcd_wcmd(pos | 0x80);  //數據指針=80+地址變量
  105. }

  106. /*******************************************************************/
  107. main()
  108. {
  109.         uchar m;
  110.     IE = 0x81;                 //允許總中斷中斷,使能 INT0 外部中斷
  111.     TCON = 0x01;               //觸發方式為脈沖負邊沿觸發

  112.     IRIN=1;                    //I/O口初始化
  113.     BEEP=1;
  114.     RELAY=1;
  115.         
  116.     delay1(10);                 //延時
  117.     lcd_init();                //初始化LCD            

  118.     lcd_pos(0);                //設置顯示位置為第一行的第1個字符
  119.      m = 0;
  120.     while(cdis1[m] != '\0')
  121.      {                         //顯示字符
  122.        lcd_wdat(cdis1[m]);
  123.        m++;
  124.      }

  125.     lcd_pos(0x40);             //設置顯示位置為第二行第1個字符
  126.      m = 0;
  127.     while(cdis2[m] != '\0')
  128.      {
  129.        lcd_wdat(cdis2[m]);      //顯示字符
  130.        m++;
  131.      }

  132.    while(1);

  133. } //end main
  134. /**********************************************************/
  135. void IR_IN(void) interrupt 0          //外部中斷服務程序
  136. {
  137.   unsigned char j,k,N=0;
  138.      EX0 = 0;   
  139.          delay(15);
  140.          if (IRIN==1)
  141.      { EX0 =1;
  142.            return;
  143.           }
  144.                            //確認IR信號出現
  145.   while (!IRIN)            //等IR變為高電平,跳過9ms的前導低電平信號。
  146.     {delay(1);}

  147. for (j=0;j<4;j++)         //收集四組數據
  148. {
  149.   for (k=0;k<8;k++)        //每組數據有8位
  150.   {
  151.    while (IRIN)            //等 IR 變為低電平,跳過4.5ms的前導高電平信號。
  152.      {delay(1);}
  153.     while (!IRIN)          //等 IR 變為高電平
  154.      {delay(1);}
  155.      while (IRIN)           //計算IR高電平時長
  156.       {
  157.     delay(1);
  158.     N++;           
  159.     if (N>=30)
  160.          { EX0=1;
  161.          return;}                  //0.14ms計數過長自動離開。
  162.       }                        //高電平計數完畢               
  163.      IRCOM[j]=IRCOM[j] >> 1;                  //數據最高位補“0”
  164.      if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80;}  //數據最高位補“1”
  165.      N=0;
  166.   }//end for k
  167. }//end for j

  168.    if (IRCOM[2]!=~IRCOM[3])
  169.    { EX0=1;
  170.      return; }

  171.    IRCOM[5]=IRCOM[2] & 0x0F;     //取鍵碼的低四位
  172.    IRCOM[6]=IRCOM[2] >> 4;       //右移4次,高四位變為低四位

  173.    if(IRCOM[5]>9)
  174.     { IRCOM[5]=IRCOM[5]+0x37;}
  175.    else
  176.           IRCOM[5]=IRCOM[5]+0x30;

  177.    if(IRCOM[6]>9)
  178.     { IRCOM[6]=IRCOM[6]+0x37;}
  179.    else
  180.           IRCOM[6]=IRCOM[6]+0x30;

  181.      lcd_pos(0x4b);            
  182.      lcd_wdat(IRCOM[6]);        //第一位數顯示
  183.      lcd_pos(0x4c);            
  184.      lcd_wdat(IRCOM[5]);        //第二位數顯示

  185.          Y0=0;
  186.          switch(IRCOM[2])
  187.          {
  188.            case 0x09: Y0=0x01; break;
  189.            case 0x1D: Y0=0x02; break;
  190.            case 0x1F: Y0=0x03; break;
  191.            case 0x0D: Y0=0x04; break;
  192.            case 0x19: Y0=0x05; break;
  193.            case 0x1B: Y0=0x06; break;
  194.            case 0x11: Y0=0x07; break;
  195.            case 0x15: Y0=0x08; break;
  196.            case 0x17: Y0=0x09; break;
  197.            case 0x45: Y0=0x10; break;

  198.           case 0x13: RELAY=1; break;
  199.           case 0x14: RELAY=1; break;
  200.           case 0x51: RELAY=0; break;
  201.          }

  202.         if(Y0==0x10){RELAY=1;P2=0xff;} //關閉繼電器
  203.         else {RELAY=0;led();}       //打開繼電器

  204.     beep();
  205.     EX0 = 1;
  206. }

  207. /**********************************************************/
  208. void beep(void)
  209. {
  210.   unsigned char i;
  211.   for (i=0;i<100;i++)
  212.    {
  213.    delay(4);
  214.    BEEP=!BEEP;                 //BEEP取反
  215.    }
  216.   BEEP=1;                      //關閉蜂鳴器
  217. }
  218. void led()
  219. {
  220.     int i=0;
  221.         uchar a;
  222.     unsigned char ledd[8]={0x7e,0xbd,0xdb,0xe7,0xdb,0xbd,0x7e,0xff};
  223.     //其實就是定義了一個亮燈狀態表
  224.    while(1)
  225.         {
  226.         for(i=0;i<8;i++)
  227.             {
  228.                         P2=ledd[i];
  229.                         delay1(50);
  230.                         }
  231.         //中間往兩邊移動
  232.                 a=0xff;
  233.                 for(i=0;i<=8;i++)
  234.                 {
  235.                         P2=a;
  236.                         delay1(50);
  237.                         a=a>>1;
  238.                         //if(a==0x00)        break;
  239.                 }
  240.          //右移+1
  241.                 a=0xff;
  242.                 for(i=0;i<8;i++)
  243.                 {
  244.                         P2=a;
  245.                         delay1(50);
  246.                         a=a<<1;
  247.                         //if(a==0x00)        break;
  248.                 }
  249.          //左移+1
  250.                 a=0x7f;
  251.                 for (i = 0 ;i < 8 ; i++)
  252.           {
  253.                 P2=a;
  254.                 delay1(50);
  255.                 a=_cror_(a,1);
  256.             if (a == 0xfe)         break;
  257.            }
  258.                    for (i = 0 ;i < 8 ; i++)
  259.           {
  260.                 P2=a;
  261.                 delay1(50);
  262.                 a=_crol_(a,1);
  263.             if (a == 0xff)         break;
  264.            }
  265.         //循環左右移
  266.         }
  267. }
  268. /**********************************************************/
  269. void delay(unsigned char x)    //x*0.14MS
  270. {
  271. unsigned char i;
  272.   while(x--)
  273. {
  274.   for (i = 0; i<13; i++) {}
  275. }
  276. }

  277. /**********************************************************/
  278. void delay1(int ms)
  279. {
  280. unsigned char y;
  281.   while(ms--)
  282. {
  283.   for(y = 0; y<250; y++)
  284.   {
  285.    _nop_();
  286.    _nop_();
  287.    _nop_();
  288.    _nop_();
  289.   }
  290. }
  291. }
復制代碼


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

使用道具 舉報

沙發
ID:7485 發表于 2018-1-29 08:26 | 只看該作者
沒看到你打開外部中斷呢?(EX0=1;)

   “ TCON = 0x01;               //觸發方式為脈沖負邊沿觸發”


是上升沿觸發吧。
回復

使用道具 舉報

板凳
ID:7485 發表于 2018-1-29 08:27 | 只看該作者
沒有詳細看其他地方。
回復

使用道具 舉報

地板
ID:62355 發表于 2018-1-29 09:08 | 只看該作者
main()
{
        uchar m;
    IE = 0x81;                 //允許總中斷中斷,使能 INT0 外部中斷
    TCON = 0x01;               //觸發方式為脈沖負邊沿觸發

    IRIN=1;                    //I/O口初始化
    BEEP=1;
    RELAY=1;
        
    delay1(10);                 //延時
    lcd_init();                //初始化LCD            

    lcd_pos(0);                //設置顯示位置為第一行的第1個字符
     m = 0;
    while(cdis1[m] != '\0')
     {                         //顯示字符
       lcd_wdat(cdis1[m]);
       m++;
     }

    lcd_pos(0x40);             //設置顯示位置為第二行第1個字符
     m = 0;
    while(cdis2[m] != '\0')
     {
       lcd_wdat(cdis2[m]);      //顯示字符
       m++;
     }

   while(1)
{
//你要的循環
}

} //end main
回復

使用道具 舉報

5#
ID:213173 發表于 2018-1-29 09:50 | 只看該作者
你在led()里使用死循環while(1),又沒有設置強制跳出的條件,程序當然死在這里。
回復

使用道具 舉報

6#
ID:258566 發表于 2018-1-29 10:53 | 只看該作者

回復

使用道具 舉報

7#
ID:7485 發表于 2018-1-29 17:04 | 只看該作者
沒仔細看,好像是靠中斷跳出循環的。
你仿真時的中斷正常嗎?
回復

使用道具 舉報

8#
ID:269211 發表于 2018-1-30 22:49 | 只看該作者
流逝記憶 發表于 2018-1-29 09:08
main()
{
        uchar m;

已試過你的方法,不行,不過還是謝謝你
回復

使用道具 舉報

9#
ID:269211 發表于 2018-1-30 22:49 | 只看該作者

已試過你的方法,不行,不過還是謝謝你
回復

使用道具 舉報

10#
ID:280512 發表于 2018-1-31 09:59 | 只看該作者
中斷控制可靠嗎?
回復

使用道具 舉報

11#
ID:269211 發表于 2018-1-31 12:12 來自觸屏版 | 只看該作者
青桑葉 發表于 2018-1-31 09:59
中斷控制可靠嗎?

中斷可以
回復

使用道具 舉報

12#
ID:267330 發表于 2018-1-31 12:23 | 只看該作者
沒看到你打開外部中斷呢?(EX0=1;) “ TCON = 0x01;               //觸發方式為脈沖負邊沿觸發”是上升沿觸發吧
回復

使用道具 舉報

13#
ID:281168 發表于 2018-1-31 15:16 | 只看該作者
你在led()的子函數里面,用了while(1),這樣程序只會在這里面跑,當然不會跳出。不建議在子函數用while(1),應該用while(條件判斷),這樣會合理一點
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表