找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3325|回復(fù): 14
打印 上一主題 下一主題
收起左側(cè)

51單片機(jī)開發(fā)板串行中斷if語句無法執(zhí)行問題(看起來很簡單,但程序怎么也調(diào)不過去)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:30063 發(fā)表于 2022-12-5 10:59 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
碰到一個看起來很簡單的51單片機(jī)串行通信的問題,但折騰了兩天了,怎么也調(diào)試不過去

1.目的:
使用郭天祥的開發(fā)版,實現(xiàn)串口送入0x01情況下,led燈閃爍的效果


2.代碼如下:
void Usart() interrupt 4
{
unsigned char receiveData;
receiveData=SBUF;//出去接收到的數(shù)據(jù)
RI = 0;//清除接收中斷標(biāo)志位

//ledFlash();//放在外面單片機(jī)能夠指揮外部小燈閃爍
if(receiveData==0x01)
{
ledFlash();
}

SBUF=receiveData;//將接收到的數(shù)據(jù)放入到發(fā)送寄存器
while(!TI); //等待發(fā)送數(shù)據(jù)完成
TI=0; //清除發(fā)送完成標(biāo)志位
}


3.問題:
1)將實現(xiàn)led閃爍的函數(shù) ledFlash()放在if語句之外直接執(zhí)行,可以實現(xiàn)當(dāng)字節(jié)到達(dá)時,直接閃爍的效果
2)但是,當(dāng)將ledFlash()移到if 語句中,不知為什么,下載到單片機(jī)就無法實現(xiàn)小燈閃爍效果了,但是后面發(fā)送到stc-isp的緩沖區(qū)的程序仍然正常。如下圖

4.嘗試:
使用keil串口仿真調(diào)試,則當(dāng)發(fā)送0x01時,能夠進(jìn)入 if 語句,正常執(zhí)行l(wèi)edFlash(),如圖


請教大家,這個到底是怎么回事的,問題該如何解決啊

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

使用道具 舉報

沙發(fā)
ID:781832 發(fā)表于 2022-12-5 12:00 | 只看該作者
連續(xù)發(fā) 0x01 看看是否能閃爍
回復(fù)

使用道具 舉報

板凳
ID:1055764 發(fā)表于 2022-12-5 14:05 | 只看該作者
和樓上觀點一樣:連續(xù)發(fā) 0x01,看是否閃爍。
回復(fù)

使用道具 舉報

地板
ID:30063 發(fā)表于 2022-12-5 16:27 | 只看該作者
連續(xù)發(fā)了,不閃爍
回復(fù)

使用道具 舉報

5#
ID:30063 發(fā)表于 2022-12-5 19:17 | 只看該作者
northroom 發(fā)表于 2022-12-5 12:00
連續(xù)發(fā) 0x01 看看是否能閃爍

連續(xù)發(fā)了,還是不行
回復(fù)

使用道具 舉報

6#
ID:301191 發(fā)表于 2022-12-6 05:48 | 只看該作者
頂一下
回復(fù)

使用道具 舉報

7#
ID:213173 發(fā)表于 2022-12-6 07:27 | 只看該作者
問題當(dāng)然在出在ledFlash()函數(shù)。放在串口中斷里,每發(fā)生一次中斷,if判斷真后 ledFlash()函數(shù)只執(zhí)行一次。放在主循環(huán)中就不同了,if判斷真后只要receiveData沒有變化, ledFlash()函數(shù)永久重復(fù)執(zhí)行。
回復(fù)

使用道具 舉報

8#
ID:308903 發(fā)表于 2022-12-6 08:37 | 只看該作者
if(receiveData==0x01)
{
ledFlash();
}
放到 while(!TI); //等待發(fā)送數(shù)據(jù)完成里面呢?
回復(fù)

使用道具 舉報

9#
ID:384109 發(fā)表于 2022-12-6 08:42 | 只看該作者
代碼不全,這類處理最好是放在主程序處理,而不是在中斷里處理
回復(fù)

使用道具 舉報

10#
ID:77589 發(fā)表于 2022-12-6 09:22 | 只看該作者
我嚴(yán)重懷疑,你是串口調(diào)試助手使用問題,可能選擇了ASCII發(fā)送(這種情況下,單片機(jī)永遠(yuǎn)收不到0x01)。
應(yīng)該切換到十六進(jìn)制發(fā)送。
回復(fù)

使用道具 舉報

11#
ID:30063 發(fā)表于 2022-12-7 10:05 | 只看該作者
wulin 發(fā)表于 2022-12-6 07:27
問題當(dāng)然在出在ledFlash()函數(shù)。放在串口中斷里,每發(fā)生一次中斷,if判斷真后 ledFlash()函數(shù)只執(zhí)行一次。 ...

你好,抱歉,沒大看明白,能否解釋一下呢

另外,說一下項目的情況,我是想實現(xiàn)雙機(jī)通信,另外一個設(shè)備通過串口發(fā)送信息,這臺設(shè)備通過出口得到信息后進(jìn)行動作(現(xiàn)在使用的ledFlash()就是這個簡單效果,這個函數(shù)在主函數(shù)跑以及在沒有if判斷的這個串行接收中斷函數(shù)中跑,都正常使得外部led閃爍,但是放到if語句就不執(zhí)行了,感覺 if 語句中的布爾邏輯是TRUE,不知為什么)
回復(fù)

使用道具 舉報

12#
ID:30063 發(fā)表于 2022-12-7 10:31 | 只看該作者
  1. #include "reg52.h"                         //此文件中定義了單片機(jī)的一些特殊功能寄存器

  2. typedef unsigned int u16;          //對數(shù)據(jù)類型進(jìn)行聲明定義
  3. typedef unsigned char u8;



  4. sbit led=P1^0;                 //將單片機(jī)的P2.0端口定義為led


  5. sbit beep=P2^3;         //蜂鳴器引腳


  6. /*******************************************************************************
  7. * 函 數(shù) 名         : delay
  8. * 函數(shù)功能                   : 延時函數(shù),i=1時,大約延時10us
  9. *******************************************************************************/
  10. void delay(u16 i)
  11. {
  12.         while(i--);       
  13. }

  14. void ledFlash()
  15. {
  16.         int i=3;
  17.         while(i--)
  18.         {
  19.                 led=0;
  20.                 delay(50000); //大約延時450ms
  21.                 led=1;
  22.                 delay(50000); //大約延時450ms       
  23.         }               
  24. }


  25. void UsartInit()
  26. {
  27.         SCON=0X50;                        //設(shè)置為工作方式1
  28.         TMOD=0X20;                        //設(shè)置計數(shù)器工作方式2
  29.         PCON=0X80;                        //波特率加倍
  30.         TH1=0XF3;                                //計數(shù)器初始值設(shè)置,注意波特率是4800的
  31.         TL1=0XF3;
  32.         ES=1;                                                //打開接收中斷
  33.         EA=1;                                                //打開總中斷
  34.         TR1=1;                                        //打開計數(shù)器
  35. }


  36. void main()
  37. {       
  38.         UsartInit();  //        串口初始化
  39.         while(1);               
  40. }


  41. void Usart() interrupt 4
  42. {
  43.         u8 receiveData;
  44.         if(RI)
  45.         {
  46.          
  47.         receiveData=SBUF;//出去接收到的數(shù)據(jù)       
  48.         {
  49.          ledFlash();//
  50.         }
  51.         while(receiveData==0x01)
  52.        

  53.         RI = 0;//清除接收中斷標(biāo)志位

  54.   }
  55. }
復(fù)制代碼

C:\Users\DELL\Pictures\3.png
這個可以執(zhí)行,不知道為什么?
但是同時出現(xiàn)了2個問題:
1.是ledFlash()函數(shù)只讓led閃爍3次,但是在這個函數(shù)執(zhí)行過程中,小燈卻一直閃爍,退不出來了,這是為什么?
2.是while語句放在前面,{}中的flashLed()又不執(zhí)行了,這個真不懂了
C:\Users\DELL\Pictures\4.png
求教
回復(fù)

使用道具 舉報

13#
ID:30063 發(fā)表于 2022-12-7 10:34 | 只看該作者
1261867136qq 發(fā)表于 2022-12-6 08:37
if(receiveData==0x01)
{
ledFlash();

完整代碼如下:
  1. #include "reg52.h"                         //此文件中定義了單片機(jī)的一些特殊功能寄存器

  2. typedef unsigned int u16;          //對數(shù)據(jù)類型進(jìn)行聲明定義
  3. typedef unsigned char u8;



  4. sbit led=P1^0;                 //將單片機(jī)的P2.0端口定義為led


  5. sbit beep=P2^3;         //蜂鳴器引腳


  6. /*******************************************************************************
  7. * 函 數(shù) 名         : delay
  8. * 函數(shù)功能                   : 延時函數(shù),i=1時,大約延時10us
  9. *******************************************************************************/
  10. void delay(u16 i)
  11. {
  12.         while(i--);       
  13. }

  14. void ledFlash()
  15. {
  16.         int i=3;
  17.         while(i--)
  18.         {
  19.                 led=0;
  20.                 delay(50000); //大約延時450ms
  21.                 led=1;
  22.                 delay(50000); //大約延時450ms       
  23.         }               
  24. }


  25. void UsartInit()
  26. {
  27.         SCON=0X50;                        //設(shè)置為工作方式1
  28.         TMOD=0X20;                        //設(shè)置計數(shù)器工作方式2
  29.         PCON=0X80;                        //波特率加倍
  30.         TH1=0XF3;                                //計數(shù)器初始值設(shè)置,注意波特率是4800的
  31.         TL1=0XF3;
  32.         ES=1;                                                //打開接收中斷
  33.         EA=1;                                                //打開總中斷
  34.         TR1=1;                                        //打開計數(shù)器
  35. }


  36. void main()
  37. {       
  38.         UsartInit();  //        串口初始化
  39.         while(1);               
  40. }


  41. void Usart() interrupt 4
  42. {
  43.         u8 receiveData;
  44.         if(RI)
  45.         {
  46.          
  47.         receiveData=SBUF;//出去接收到的數(shù)據(jù)       

  48.          
  49.         {
  50.          ledFlash();//
  51.         }
  52.         while(receiveData==0x01)

  53.         RI = 0;//清除接收中斷標(biāo)志位

  54.   }
  55. }
復(fù)制代碼

代碼可以執(zhí)行,led閃爍,
但是,出現(xiàn)了2個問題:
1.小燈一直閃爍,停不下來了
2.采用while提前,又不執(zhí)行了
  1. void Usart() interrupt 4
  2. {
  3.         u8 receiveData;
  4.         if(RI)
  5.         {
  6.          
  7.         receiveData=SBUF;//出去接收到的數(shù)據(jù)       

  8.            while(receiveData==0x01)
  9.         {
  10.          ledFlash();//
  11.         }
  12.          

  13.         RI = 0;//清除接收中斷標(biāo)志位

  14.   }
復(fù)制代碼

不知道這是怎么回事
回復(fù)

使用道具 舉報

14#
ID:213173 發(fā)表于 2022-12-7 11:46 | 只看該作者
goodshot 發(fā)表于 2022-12-7 10:05
你好,抱歉,沒大看明白,能否解釋一下呢

另外,說一下項目的情況,我是想實現(xiàn)雙機(jī)通信,另外一個設(shè)備 ...

不知道你的ledFlash()函數(shù)的具體代碼,但放在串口中斷中運行肯定是不當(dāng)?shù),LED閃爍是需要在一定的時間范圍完成,而串口中斷函數(shù)是不能把占用較長時間的LED閃爍函數(shù)放進(jìn)去。串口中斷只能根據(jù)收到的信息經(jīng)判斷輸出一個標(biāo)志并立即退出函數(shù)。主函數(shù)根據(jù)這個標(biāo)志調(diào)用指定的子函數(shù)。
void Usart() interrupt 4
{
        unsigned char receiveData;
        receiveData=SBUF;//獲取接收到的數(shù)據(jù)
        RI = 0;//清除接收中斷標(biāo)志位
        if(receiveData==0x01)//判斷是真
        {
                flag=1;//標(biāo)志置1
        }
        else
        {
                flag=0;//標(biāo)志清0
        }
}
如果主函數(shù)中要持續(xù)執(zhí)行
        if(flag)
        {
                ledFlash();
        }

如果主函數(shù)中只要執(zhí)行1次
        if(flag)
        {
                flag=0;
                ledFlash();
        }
回復(fù)

使用道具 舉報

15#
ID:401564 發(fā)表于 2022-12-7 17:20 | 只看該作者
在中斷中最好不要使用while
也不要在中斷調(diào)用延時時間過長的函數(shù)
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表