標(biāo)題: 51單片機(jī)開發(fā)板串行中斷if語句無法執(zhí)行問題(看起來很簡(jiǎn)單,但程序怎么也調(diào)不過去) [打印本頁]

作者: goodshot    時(shí)間: 2022-12-5 10:59
標(biāo)題: 51單片機(jī)開發(fā)板串行中斷if語句無法執(zhí)行問題(看起來很簡(jiǎn)單,但程序怎么也調(diào)不過去)
碰到一個(gè)看起來很簡(jiǎn)單的51單片機(jī)串行通信的問題,但折騰了兩天了,怎么也調(diào)試不過去

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

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


請(qǐng)教大家,這個(gè)到底是怎么回事的,問題該如何解決啊


作者: northroom    時(shí)間: 2022-12-5 12:00
連續(xù)發(fā) 0x01 看看是否能閃爍
作者: laosanxu    時(shí)間: 2022-12-5 14:05
和樓上觀點(diǎn)一樣:連續(xù)發(fā) 0x01,看是否閃爍。
作者: goodshot    時(shí)間: 2022-12-5 16:27
連續(xù)發(fā)了,不閃爍
作者: goodshot    時(shí)間: 2022-12-5 19:17
northroom 發(fā)表于 2022-12-5 12:00
連續(xù)發(fā) 0x01 看看是否能閃爍

連續(xù)發(fā)了,還是不行
作者: 人工置頂員    時(shí)間: 2022-12-6 05:48
頂一下
作者: wulin    時(shí)間: 2022-12-6 07:27
問題當(dāng)然在出在ledFlash()函數(shù)。放在串口中斷里,每發(fā)生一次中斷,if判斷真后 ledFlash()函數(shù)只執(zhí)行一次。放在主循環(huán)中就不同了,if判斷真后只要receiveData沒有變化, ledFlash()函數(shù)永久重復(fù)執(zhí)行。
作者: 1261867136qq    時(shí)間: 2022-12-6 08:37
if(receiveData==0x01)
{
ledFlash();
}
放到 while(!TI); //等待發(fā)送數(shù)據(jù)完成里面呢?
作者: 人中狼    時(shí)間: 2022-12-6 08:42
代碼不全,這類處理最好是放在主程序處理,而不是在中斷里處理
作者: Longan.Wang    時(shí)間: 2022-12-6 09:22
我嚴(yán)重懷疑,你是串口調(diào)試助手使用問題,可能選擇了ASCII發(fā)送(這種情況下,單片機(jī)永遠(yuǎn)收不到0x01)。
應(yīng)該切換到十六進(jìn)制發(fā)送。
作者: goodshot    時(shí)間: 2022-12-7 10:05
wulin 發(fā)表于 2022-12-6 07:27
問題當(dāng)然在出在ledFlash()函數(shù)。放在串口中斷里,每發(fā)生一次中斷,if判斷真后 ledFlash()函數(shù)只執(zhí)行一次。 ...

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

另外,說一下項(xiàng)目的情況,我是想實(shí)現(xiàn)雙機(jī)通信,另外一個(gè)設(shè)備通過串口發(fā)送信息,這臺(tái)設(shè)備通過出口得到信息后進(jìn)行動(dòng)作(現(xiàn)在使用的ledFlash()就是這個(gè)簡(jiǎn)單效果,這個(gè)函數(shù)在主函數(shù)跑以及在沒有if判斷的這個(gè)串行接收中斷函數(shù)中跑,都正常使得外部led閃爍,但是放到if語句就不執(zhí)行了,感覺 if 語句中的布爾邏輯是TRUE,不知為什么)
作者: goodshot    時(shí)間: 2022-12-7 10:31
  1. #include "reg52.h"                         //此文件中定義了單片機(jī)的一些特殊功能寄存器

  2. typedef unsigned int u16;          //對(duì)數(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í)函數(shù),i=1時(shí),大約延時(shí)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); //大約延時(shí)450ms
  21.                 led=1;
  22.                 delay(50000); //大約延時(shí)450ms       
  23.         }               
  24. }


  25. void UsartInit()
  26. {
  27.         SCON=0X50;                        //設(shè)置為工作方式1
  28.         TMOD=0X20;                        //設(shè)置計(jì)數(shù)器工作方式2
  29.         PCON=0X80;                        //波特率加倍
  30.         TH1=0XF3;                                //計(jì)數(shù)器初始值設(shè)置,注意波特率是4800的
  31.         TL1=0XF3;
  32.         ES=1;                                                //打開接收中斷
  33.         EA=1;                                                //打開總中斷
  34.         TR1=1;                                        //打開計(jì)數(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
這個(gè)可以執(zhí)行,不知道為什么?
但是同時(shí)出現(xiàn)了2個(gè)問題:
1.是ledFlash()函數(shù)只讓led閃爍3次,但是在這個(gè)函數(shù)執(zhí)行過程中,小燈卻一直閃爍,退不出來了,這是為什么?
2.是while語句放在前面,{}中的flashLed()又不執(zhí)行了,這個(gè)真不懂了
C:\Users\DELL\Pictures\4.png
求教

作者: goodshot    時(shí)間: 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;          //對(duì)數(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í)函數(shù),i=1時(shí),大約延時(shí)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); //大約延時(shí)450ms
  21.                 led=1;
  22.                 delay(50000); //大約延時(shí)450ms       
  23.         }               
  24. }


  25. void UsartInit()
  26. {
  27.         SCON=0X50;                        //設(shè)置為工作方式1
  28.         TMOD=0X20;                        //設(shè)置計(jì)數(shù)器工作方式2
  29.         PCON=0X80;                        //波特率加倍
  30.         TH1=0XF3;                                //計(jì)數(shù)器初始值設(shè)置,注意波特率是4800的
  31.         TL1=0XF3;
  32.         ES=1;                                                //打開接收中斷
  33.         EA=1;                                                //打開總中斷
  34.         TR1=1;                                        //打開計(jì)數(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個(gè)問題:
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ù)制代碼

不知道這是怎么回事

作者: wulin    時(shí)間: 2022-12-7 11:46
goodshot 發(fā)表于 2022-12-7 10:05
你好,抱歉,沒大看明白,能否解釋一下呢

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

不知道你的ledFlash()函數(shù)的具體代碼,但放在串口中斷中運(yùn)行肯定是不當(dāng)?shù),LED閃爍是需要在一定的時(shí)間范圍完成,而串口中斷函數(shù)是不能把占用較長(zhǎng)時(shí)間的LED閃爍函數(shù)放進(jìn)去。串口中斷只能根據(jù)收到的信息經(jīng)判斷輸出一個(gè)標(biāo)志并立即退出函數(shù)。主函數(shù)根據(jù)這個(gè)標(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();
        }

作者: Y_G_G    時(shí)間: 2022-12-7 17:20
在中斷中最好不要使用while
也不要在中斷調(diào)用延時(shí)時(shí)間過長(zhǎng)的函數(shù)




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1