找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

帖子
查看: 2949|回復: 17
收起左側(cè)

關(guān)于不支持在線仿真的單片機的單線單工通信接收函數(shù)的問題

[復制鏈接]
ID:540927 發(fā)表于 2020-8-26 08:49 | 顯示全部樓層 |閱讀模式
我現(xiàn)在在做一個單線單工通信的程序,但是單片機不支持在線仿真,接收函數(shù)如下:
void Receive()                                 //接收函數(shù),接收5byte數(shù)據(jù),先接收低位再接收高位
{
CHAR Temp;
if((time1 > 40)&&(time1 < 60))               //新的引導碼開始退出接收函數(shù)
{
  Temp = 0;
  beginflag = 0;
}
if((time1 > 0)&&(time1 < 5))                 //數(shù)據(jù)位低電平所在范圍
{
  BitNum++;
  time1 = 0;
  lowflag = 1;                       //低電平信號標志
}
else if((time1 >= 5)&&((time1 <=40)||(time1 >= 60)))
{
  
  time1 = 0;
  Temp = 0;
  beginflag = 0;                                            //數(shù)據(jù)出錯退出接收
}
if(lowflag == 1)                               //每一位的低電平接收成功則接收高電平
{
  if((time2 > 0)&&(time2 < 5))           //數(shù)據(jù)位0信號
  {
   time2 = 0;
   Bit = 0;
  }
  else if((time2 > 8)&&(time2 < 14))           //數(shù)據(jù)位1信號
  {
   time2 = 0;
   Bit = 1;
  }
  else if((time2 >= 5)&&((time2 <= 8)||(time2 >= 14)))
  {
   
   time2 = 0;
   Temp = 0;
   beginflag = 0;                                  //數(shù)據(jù)出錯退出接收
  }
  Temp |= (Bit << (BitNum - 1));                   //把所在位的數(shù)據(jù)存入
  lowflag = 0;
  if(BitNum >= 8)                                   //1byte數(shù)據(jù)接收完之后存入     
    {
   ByteNum++;
   switch(ByteNum)
   {
    case 1: {NewByte1 = Temp; Temp = 0;break;}
    case 2: {NewByte2 = Temp; Temp = 0;break;}
    case 3: {NewByte3 = Temp; Temp = 0;break;}
    case 4: {NewByte4 = Temp; Temp = 0;break;}
    case 5: {NewByte5 = Temp; Temp = 0;break;}
    default : break;
   }
      BitNum = 0;
      
   if(ByteNum >= 5)                             //5byte數(shù)據(jù)接收完進行數(shù)據(jù)處理
      {
   
        ByteNum = 0;
    beginflag = 0;                         //接收完畢標志置0
    dataflag = 1;                         //數(shù)據(jù)處理標志
   }
  }
}
}

在調(diào)試過程中,我不能知道NewByte1,NewByte2,NewByte3,NewByte4,NewByte5的具體值,只能直接燒錄在板子上驗證,但是結(jié)果不成功。我已經(jīng)確認了這個函數(shù)一直能運行到完,只能說明接收到的數(shù)據(jù)不正確。請問有什么辦法可以知道這幾個數(shù)據(jù)的具體值是多少?不支持在線仿真的單片機調(diào)試有技巧嗎?我的這個函數(shù)有什么問題?請大家?guī)蛶臀野桑x謝!
回復

使用道具 舉報

ID:739545 發(fā)表于 2020-8-26 10:33 | 顯示全部樓層
有LCD顯示的話,把你需要看的數(shù)據(jù)實時在LCD上顯示出來,或者有串口的話,把debug的數(shù)據(jù)用串口傳輸看結(jié)果。很多情況下都是沒有在線仿真的。都是在線檢查
回復

使用道具 舉報

ID:654028 發(fā)表于 2020-8-26 11:48 | 顯示全部樓層
串口通信?或者其他方式,比如收到什么數(shù)據(jù)做什么事情,比較容易觀察的
回復

使用道具 舉報

ID:540927 發(fā)表于 2020-8-26 12:27 | 顯示全部樓層
lovezjf234 發(fā)表于 2020-8-26 10:33
有LCD顯示的話,把你需要看的數(shù)據(jù)實時在LCD上顯示出來,或者有串口的話,把debug的數(shù)據(jù)用串口傳輸看結(jié)果。 ...

感謝你的回復,我這個是單線通信的,沒有用到串口板上也沒有LCD,所以比較難辦
回復

使用道具 舉報

ID:540927 發(fā)表于 2020-8-26 12:31 | 顯示全部樓層
心有浮生 發(fā)表于 2020-8-26 11:48
串口通信?或者其他方式,比如收到什么數(shù)據(jù)做什么事情,比較容易觀察的

感謝您的回復,我的這個不是串口通信而是單線通信,就是收到數(shù)據(jù)進行處理可以在板子上驗證,但是就是因為不能成功,我才想知道接收到的具體數(shù)據(jù),或者說我的接收函數(shù)是不是正確的
回復

使用道具 舉報

ID:540927 發(fā)表于 2020-8-26 13:10 | 顯示全部樓層
lovezjf234 發(fā)表于 2020-8-26 10:33
有LCD顯示的話,把你需要看的數(shù)據(jù)實時在LCD上顯示出來,或者有串口的話,把debug的數(shù)據(jù)用串口傳輸看結(jié)果。 ...

謝謝您,確實可以自己做串口通信到電腦看結(jié)果,這個對不能在線仿真的單片機來說確實是個好辦法
回復

使用道具 舉報

ID:804115 發(fā)表于 2020-8-26 13:58 | 顯示全部樓層
你這個是底層信號接收,對時序要求比較嚴格,用串口debug和lcd顯示都不行,因為都比較耗時。
你可以用一個沒有用的io來調(diào)試,因為IO翻轉(zhuǎn)耗費的時間比較少。你可以將此io接到一個燈上用于指示。
另外,你可以通過示波器或者邏輯分析儀抓取發(fā)送端的發(fā)送時序,看看發(fā)送端是否符合要求,再分析你的接收端是否匹配。
回復

使用道具 舉報

ID:540927 發(fā)表于 2020-8-26 15:19 | 顯示全部樓層
1692483014 發(fā)表于 2020-8-26 13:58
你這個是底層信號接收,對時序要求比較嚴格,用串口debug和lcd顯示都不行,因為都比較耗時。
你可以用一個 ...

感謝您的回復,我調(diào)試的時候也是把一個引腳置1輸出,然后一步一步看程序可以執(zhí)行到哪,但是在使用數(shù)據(jù)處理的時候出了問題,所以我需要了解接收的數(shù)據(jù)怎么了
回復

使用道具 舉報

ID:230118 發(fā)表于 2020-8-26 15:24 | 顯示全部樓層
邏輯分析儀或示波器最簡單直觀,沒有的話,可以嘗試按比例把通訊時隙按比例放大若干倍(以保證肉眼能觀察到led變化),接收端用指示燈來指示接收數(shù)據(jù)位的變化
回復

使用道具 舉報

ID:540927 發(fā)表于 2020-8-26 17:19 | 顯示全部樓層
bro0310 發(fā)表于 2020-8-26 15:24
邏輯分析儀或示波器最簡單直觀,沒有的話,可以嘗試按比例把通訊時隙按比例放大若干倍(以保證肉眼能觀察到l ...

感謝您的回復,接收端我可以用示波器測到波形的,關(guān)鍵是單片機中的程序處理不知道是不是錯了
回復

使用道具 舉報

ID:230118 發(fā)表于 2020-8-26 19:54 | 顯示全部樓層
你這個通訊方式和NEC紅外協(xié)議很類似,既然是單線單工,你的引導碼和數(shù)據(jù)應(yīng)該是讀的同一個引腳,那么time1,time2是同一個引腳的電平持續(xù)時間,對嗎?要找到問題,我的思路是這樣的,僅供參考:
1  根據(jù)你的晶振精度,以及系統(tǒng)中有無其它優(yōu)先級更高的中斷影響通訊時序,合理設(shè)計0、1bit的時序特征,提高容錯性,比方說3~10us低電平后接10~20us高電平代表0; 10~18us低電平厚街3~10us高電平代碼1;
2  由于時序要求比較高,發(fā)送端的延時最好用定時器來做
3  示波器測量輸出端時序,比方說你發(fā)送數(shù)據(jù)0x55,確認發(fā)送端的輸出時序和你的協(xié)議設(shè)計相符
4  接收端用定時器的輸入捕獲功能來測量電平時間
中斷服務(wù)程序
void Capture_ISR (void)
{
    // 讀取timer寄存器時間time
    if (!receive_flag)
    {
        receive(time);
    }
}


void receive(uint16_t Capture_Time )
{
    if(IR_State == 0)
    {
        IR_LDC_Ready = 0;           // Clear LeaDer Code Ready
        IR_State=1;
    }
    // Leader or Repeater code
    else if(IR_State == 1)
    {
        // Leader code
        if((Capture_Time >= IR_LDC_MIN) && (Capture_Time <= IR_LDC_MAX))
        {
            IR_LDC_Ready = 1;       // Set LeaDer Code Ready
            IR_State++;
        }
        else
        {
            IR_State = 1;
            IR_LDC_Ready = 0;           // Clear LeaDer Code Ready
        }
    }
      // Data
    else if((IR_State >= 2 && IR_State < 10) && (IR_LDC_Ready == 1))
    {
        IR_State++;
        NewByte1 = NewByte1 >> 1;
        if((Capture_Time >= IR_BIT_0_MIN) && (Capture_Time <= IR_BIT_0_MAX))
            NewByte1 &= 0x7f;
        else if((Capture_Time >= IR_BIT_1_MIN) && (Capture_Time <= IR_BIT_1_MAX))
            NewByte1 |= 0x80;
        else
            IR_State = 0;
    }
    else if((IR_State >= 10 && IR_State < 18) && (IR_LDC_Ready == 1))
    {
        IR_State++;
        NewByte2 = NewByte2 >> 1;
        if((Capture_Time >= IR_BIT_0_MIN) && (Capture_Time <= IR_BIT_0_MAX))
            NewByte2 &= 0x7f;
        else if((Capture_Time >= IR_BIT_1_MIN) && (Capture_Time <= IR_BIT_1_MAX))
            NewByte2 |= 0x80;
        else
            IR_State = 0;
    }
    else if((IR_State >= 18 && IR_State < 26) && (IR_LDC_Ready == 1))
    {
        IR_State++;
        NewByte3= NewByte3>> 1;
        if((Capture_Time >= IR_BIT_0_MIN) && (Capture_Time <= IR_BIT_0_MAX))
            NewByte3&= 0x7f;
        else if((Capture_Time >= IR_BIT_1_MIN) && (Capture_Time <= IR_BIT_1_MAX))
            NewByte3|= 0x80;
        else
            IR_State = 0;
    }
    else if((IR_State >= 26 && IR_State < 34) && (IR_LDC_Ready == 1))
    {
        IR_State++;
        NewByte4= NewByte4>> 1;
        if((Capture_Time >= IR_BIT_0_MIN) && (Capture_Time <= IR_BIT_0_MAX))
            NewByte4&= 0x7f;
        else if((Capture_Time >= IR_BIT_1_MIN) && (Capture_Time <= IR_BIT_1_MAX))
            NewByte4|= 0x80;
        else
            IR_State = 0;
    }
    else if((IR_State >= 34 && IR_State < 42) && (IR_LDC_Ready == 1))
    {
        IR_State++;
        NewByte5= NewByte5>> 1;
        if((Capture_Time >= IR_BIT_0_MIN) && (Capture_Time <= IR_BIT_0_MAX))
            NewByte5&= 0x7f;
        else if((Capture_Time >= IR_BIT_1_MIN) && (Capture_Time <= IR_BIT_1_MAX))
            NewByte5|= 0x80;
        else
            IR_State = 0;
    }

        if(IR_State == 42)
        {
            IR_LDC_Ready = 0;   // Clear LeaDer Code Ready
            received_flag= 1;
            IR_State = 0;
        }
}

評分

參與人數(shù) 1黑幣 +60 收起 理由
admin + 60 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:213173 發(fā)表于 2020-8-26 20:06 | 顯示全部樓層
其實可以參照ds18b20溫度傳感器的單總線通訊方式完成異步串行通訊,如果只是單向傳輸就更簡單了。
回復

使用道具 舉報

ID:540927 發(fā)表于 2020-8-27 08:13 | 顯示全部樓層
bro0310 發(fā)表于 2020-8-26 19:54
你這個通訊方式和NEC紅外協(xié)議很類似,既然是單線單工,你的引導碼和數(shù)據(jù)應(yīng)該是讀的同一個引腳,那么time1,t ...

感謝您詳細的回復,我會參考您提供的辦法試圖解決問題的,不過由于接收端的單片機功能比較少,沒有輸入捕獲功能,很遺憾呢
回復

使用道具 舉報

ID:540927 發(fā)表于 2020-8-27 08:15 | 顯示全部樓層
wulin 發(fā)表于 2020-8-26 20:06
其實可以參照ds18b20溫度傳感器的單總線通訊方式完成異步串行通訊,如果只是單向傳輸就更簡單了。

感謝您的回復,我也參考了這個,同時還參考了紅外解調(diào),后來我想要自己的方法編程,可惜不盡如意
回復

使用道具 舉報

ID:176854 發(fā)表于 2020-8-27 16:29 | 顯示全部樓層
TB買一個串行數(shù)碼管,用數(shù)碼管顯示接收值。
飛線也就4、5根。
回復

使用道具 舉報

ID:540927 發(fā)表于 2020-8-28 09:45 | 顯示全部樓層
jjjjjjir 發(fā)表于 2020-8-27 16:29
TB買一個串行數(shù)碼管,用數(shù)碼管顯示接收值。
飛線也就4、5根。

好主意呢,不錯,謝謝啦
回復

使用道具 舉報

ID:540927 發(fā)表于 2020-8-28 11:08 | 顯示全部樓層
lovezjf234 發(fā)表于 2020-8-26 10:33
有LCD顯示的話,把你需要看的數(shù)據(jù)實時在LCD上顯示出來,或者有串口的話,把debug的數(shù)據(jù)用串口傳輸看結(jié)果。 ...

不好意思了,前天嘗試了用串口通信到電腦上看數(shù)據(jù),結(jié)果昨天一整天單片機引腳檢測不到電平信號,我換了好多器件都沒解決,今天我才發(fā)現(xiàn),我的串口就是輸入信號的接口,再做串口通信就沖突了
回復

使用道具 舉報

ID:540927 發(fā)表于 2020-8-28 11:50 | 顯示全部樓層
jjjjjjir 發(fā)表于 2020-8-27 16:29
TB買一個串行數(shù)碼管,用數(shù)碼管顯示接收值。
飛線也就4、5根。

感謝您的建言,果然是個好方法的,我會參考的,謝謝
回復

使用道具 舉報

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

本版積分規(guī)則

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

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

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