找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

用兩個(gè)C51單片機(jī)模擬SPI全雙工通信,請教各位大神,指導(dǎo),這錯(cuò)在哪里

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:166571 發(fā)表于 2021-7-19 21:54 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
用兩個(gè)C51單片機(jī)模擬SPI全雙工通信,
//SPI主機(jī)代碼
void SPI_PRO_INIT()
{
      SET_SFR_PAGE1;
          
     _SPI_NSS_OUTPUT;
         _SPI_NSS_PULLUPON;//上拉,關(guān)片選,
         
         _SPI_SCK_OUTPUT;
         _SPI_SCK_PULLDOWNON;//下拉        ,關(guān)時(shí)鐘

         _SPI_MOSI_OUTPUT;
         _SPI_MOSI_PULLDOWNON;//下拉        ,關(guān)數(shù)據(jù)輸出
         
         _SPI_MISO_INPUT;
         _SPI_MISO_PULLDOWNON;//下拉開啟,拉低輸入
         
         R_data=0;
         W_data=0;

         SET_SFR_PAGE0;


}
uint8 SPI_Read_Byte()
        {
                uint8 i;
                uint8 SPI1_dat=0;
       
                _SPI_NSS_ON;//片選
               
          for(i=0;i<8;i++)
                {
                _SPI_SCK_OFF;
                Delay_3us();
                SPI1_dat<<=1;//SPI1_dat=(SPI1_dat<<1),第一個(gè)上升沿讀取數(shù)據(jù)

                if(_SPI_MISO )//從機(jī)發(fā)來的信號(hào),如果是高電平
                        {
                        SPI1_dat|=0x01;//0000 0001,左移后,補(bǔ)1;與(SPI_dat&0x80)//1000 0000相互呼應(yīng)
                        }
                // else
                         //{
                         //SPI1_dat&=0xfe;//1111 1110,左移后,補(bǔ)0;
                         //}
        _SPI_SCK_ON;
                 Delay_3us();
                }
          
         // _SPI_SCK_OFF;
          _SPI_NSS_OFF; //關(guān)片選

          return SPI1_dat;
        }

uint8 SPI_Write_Byte(uint8 SPI_dat)
{
        uint8 i;

        _SPI_NSS_ON;//片選
  for(i=0;i<8;i++)
          {
          _SPI_SCK_OFF;
         Delay_3us();
        if(SPI_dat&0x80)//1000 0000,要發(fā)送的數(shù)據(jù)的第8位是1
                {
                _SPI_MOSI_ON;
                }
        else
                {
               
                _SPI_MOSI_OFF;
               
                }
        SPI_dat=(SPI_dat<<1);//左移,移動(dòng)數(shù)據(jù)傳送
        _SPI_SCK_ON;
        Delay_3us();
          }
// _SPI_SCK_OFF;
  _SPI_NSS_OFF; //關(guān)片選

}



   void SPI_PRO()
   {
        W_data = SPI_Write_Byte(0x55 );//
        R_data = SPI_Read_Byte();
          if(R_data==0xAA)
           {
           _LED1_OFF;
           }
       
  }

//從機(jī)代碼
        void SPI_PRO_INIT()
         {
                   SET_SFR_PAGE1;
                  
                  _SPI_NSS_INPUT;
                  _SPI_NSS_PULLUPON;
                  
                  _SPI_SCK_INPUT;
                  _SPI_SCK_PULLDOWNON;
                  
                  _SPI_MOSI_INPUT;
                  _SPI_MOSI_PULLDOWNON;
                  
                  _SPI_MISO_OUTPUT;
                  _SPI_MISO_PULLDOWNON;
         
                  SET_SFR_PAGE0;
                 
                 W_data=0;
                 R_data=0;
       
                  
         }

                /******************************************************************************
                * Function         :        Slave_SPI_Read_Byte
                * Description:        從SPI讀出一個(gè)8位字節(jié)
                * Input          :        SPI1_dat:要發(fā)送的數(shù)據(jù)
               
                *******************************************************************************/
        uint8 SPI_Read_Byte()
                {
                  uint8 i;
                  uint8 SPI1_dat=0;
                  uint8 SPI1_flag=0;
                               
                 if(!(_SPI_NSS ))//片選后,執(zhí)行if(!(_SPI_NSS ))里面的函數(shù)
                        {
                         for(i=0;i<8;i++)
                                {
                                SPI1_flag=1;
                                while(!( _SPI_SCK ));//等待時(shí)鐘拉低,開始讀數(shù)據(jù)
                                SPI1_dat<<=1;//SPI1_dat=(SPI1_dat<<1)開始
                                if(_SPI_MOSI )
                                        {
                                        SPI1_dat|=0x01;//讀取后,第一位補(bǔ)1;//與SPI_dat&0x80相呼應(yīng)
                                       
                                        }
                                while(_SPI_SCK );//等待讀取結(jié)束
                               
                                }
                         while(!(_SPI_NSS ));//等待關(guān)片選
                        }
                  if(SPI1_flag==1)
                        {
                        return SPI1_dat;
                        }
                  else
                        {
                        return 0;
                        }
                }
       
       
        /******************************************************************************
        * Function         :        Slave_SPI_Write
        * Description:        向SPI寫入一個(gè)8位字節(jié)
        * Input          :        SPI_dat:要發(fā)送的數(shù)據(jù)
       
        *******************************************************************************/
        uint8 SPI_Write_Byte(uint8 SPI_dat)
        {
                uint8 i;
        if(!(_SPI_NSS ))//片選后,執(zhí)行if(!(_SPI_NSS ))里面的函數(shù)
                {
                  for(i=0;i<8;i++)
                          {
                          while(_SPI_SCK);//_SPI_SCK低時(shí),執(zhí)行后面的函數(shù)
                        if(SPI_dat&0x80)//1000 0000 是高電平,有數(shù)據(jù)
                                {
                                _SPI_MISO_ON;
                                }
                        else
                                {
                                _SPI_MISO_OFF;
                                }
                        while(!(_SPI_SCK));//等待讀取完成
                           SPI_dat<<=1;//向SPI寫數(shù)據(jù)
                       
                          }
                 while(!(_SPI_NSS ));//等待關(guān)片選
                }
       
        }
       



  void SPI_PRO()
  {

         W_data= SPI_Write_Byte(0xAA );//
         R_data= SPI_Read_Byte();
         if(R_data==0x55)
          {
          _LED2_OFF;
          }

  }


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

使用道具 舉報(bào)

沙發(fā)
ID:166571 發(fā)表于 2021-7-19 21:59 | 只看該作者
菜鳥求大神指教,
回復(fù)

使用道具 舉報(bào)

板凳
ID:123289 發(fā)表于 2021-7-20 09:25 | 只看該作者
先說說錯(cuò)誤的現(xiàn)象長什么樣子?
回復(fù)

使用道具 舉報(bào)

地板
ID:592807 發(fā)表于 2021-7-20 09:37 | 只看該作者
看著太麻煩了,理解也費(fèi)勁。還是解釋一下吧


1  所謂的雙全工值得是通訊雙向,接收數(shù)據(jù)的同時(shí)必須發(fā)等量數(shù)據(jù),就像我給你一桶水你給我一桶水,如果我沒收到一桶水就表示我給你的一桶水中途灑了,我要重新給你一份水,直到我收到你的水,這樣我才能確保你一定收到水。但是你的發(fā)送沒同步接收,不能確保從機(jī)一定受到數(shù)據(jù)。
2主機(jī)已經(jīng)結(jié)束從機(jī)還沒開始。
         W_data= SPI_Write_Byte(0xAA );//
         R_data= SPI_Read_Byte();

你的通訊應(yīng)該是這樣的

主機(jī)片選  ----  主機(jī)發(fā)送“0XAA”-----主機(jī)片選關(guān)閉 ----主機(jī)片選 -----主機(jī)開始接受---主機(jī)接受完畢---主機(jī)關(guān)閉片選
從機(jī)被片選----從機(jī)接受數(shù)據(jù)“0XAA”----從機(jī)處理數(shù)據(jù)----從機(jī)被片選-------從機(jī)發(fā)送數(shù)據(jù)
你這個(gè)主機(jī)接受數(shù)據(jù)和從機(jī)發(fā)送數(shù)據(jù)的時(shí)間沒法保證統(tǒng)一,就像接力賽,時(shí)間一到就開始跑,不管接力棒是否已經(jīng)到你手里了,也不管你接到是不是自家隊(duì)友的接力棒。


回復(fù)

使用道具 舉報(bào)

5#
ID:166571 發(fā)表于 2021-7-20 14:46 | 只看該作者
黃youhui 發(fā)表于 2021-7-20 09:37
看著太麻煩了,理解也費(fèi)勁。還是解釋一下吧

那怎樣保證啊,我也是參考別家的,
回復(fù)

使用道具 舉報(bào)

6#
ID:166571 發(fā)表于 2021-7-20 14:48 | 只看該作者
yzwzfyz 發(fā)表于 2021-7-20 09:25
先說說錯(cuò)誤的現(xiàn)象長什么樣子?

從機(jī)與主機(jī)不能通信
回復(fù)

使用道具 舉報(bào)

7#
ID:592807 發(fā)表于 2021-7-20 15:25 | 只看該作者
qiuluqiang 發(fā)表于 2021-7-20 14:46
那怎樣保證啊,我也是參考別家的,

你主機(jī)發(fā)送完后就while(1)等。
從機(jī)要發(fā)送數(shù)據(jù)前片選CS=0
主機(jī)加收到CS=0信號(hào),就開始接受
回復(fù)

使用道具 舉報(bào)

8#
ID:166571 發(fā)表于 2021-7-21 19:24 | 只看該作者
你要這方面的代碼嗎,能提供參考下嗎
回復(fù)

使用道具 舉報(bào)

9#
ID:166571 發(fā)表于 2021-7-21 19:39 | 只看該作者
接收與發(fā)送是時(shí)鐘控制的啊,
回復(fù)

使用道具 舉報(bào)

10#
ID:166571 發(fā)表于 2021-7-21 19:40 | 只看該作者
你有這方面的代碼嗎,就是用兩個(gè)單片機(jī)模擬SPI的互相通信的,
回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

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

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

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