久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

利用C51單片機模擬SPI進行雙機通信

  [復制鏈接]
跳轉到指定樓層
樓主
1.1SPI協議簡述
      SPI,是英語Serial Peripheral interface的縮寫,顧名思義就是串行外圍設備接口。由Motorola首創。SPI接口主要應用在 EEPROM,FLASH,實時時鐘,AD轉換器,還有數字信號處理器和數字信號解碼器之間。SPI,是一種高速的,全雙工,同步的通信總線。
  優缺點:
  • 1.協議簡單,相對數據速率高。
  • 2.占用的Pin口較多
  • 3.沒有指定的流控制,沒有應答機制確認是否接收到數據。


      SPI的通信原理很簡單,它以主從方式工作,這種模式通常有一個主設備和一個或多個從設備,需要至少4根線,事實上3根也可以(單向傳輸時)。也是所有基于SPI的設備共有的,它們是SDI,SDO,SCK,CS。

  • SDO – 主設備數據輸出,從設備數據輸入
  • SDI – 主設備數據輸入,從設備數據輸出
  • SCK – 時鐘信號,由主設備產生
  • CS – 從設備使能信號,由主設備控制


CS: 其中CS是控制芯片是否被選中的,也就是說只有片選信號為預先規定的使能信號時(高電位或低電位),對此芯片的操作才有效,這就允許在同一總線上連接多個SPI設備成為可能。

SCK:SCK為時鐘信號線,主要控制時序。相當于整個SPI協議是以SCK為準進行的。因此SCK的控制在每次發送中只能在主機的控制下進行,從機不可控制。

SDI/SDO: 通訊是通過數據交換完成的,這里先要知道SPI是串行通訊協議,也就是說數據是一位一位的傳輸的。SDO為主機發送,從機接收;SDI為主機接受,從機發送。

參考網站(請自行替換.):dlnwarecom/theory/SPI-Bus

1.2SPI的四種模式

     這四種模式分別為:

模式                   CPOL&CPHA
MODE0          CPOL=0;CPHA=0
MODE1          CPOL=0;CPHA=1
MODE2          CPOL=1;CPHA=0
MODE3          CPOL=1;CPHA=1

參考網站(請自行替換.)dlnwarecom/theory/SPI-Transfer-Modes

       在這四種模式中,我們常用MODE0和MODE2。因為它便于操作。我便是使用的MODE2模式。這四種模式的區別在參考網站中有詳細的描述,這里便不再贅述。

  在MODE2模式下。時鐘在空閑時始終置1,每產生一次下降沿便會發送1 bit 數據。大家可能已經想到,SPI協議可以在八位沒有發出送完的情況下停止發送。


  這里我跑了下示波器。



        從圖中清晰可見8個下降沿,時鐘在空閑時始終置1。
  
  其余的三個模式以此類推。

2.1軟件模擬       我使用的單片機為STC89C52,內部沒有SPI的資源,因此需要自己進行軟件模擬。
  利用串口中斷,首先利用電腦A得串口助手發送的數據存入SBUF,再將SBUF的值通過SPI的SDO發送給從機的SDI接收,并存入從機的SBUF,顯示在電腦B的串口助手上。
  目的:電腦A發送數據,如:AB,電腦B可接收到AB。

  如圖:


     PS:在此項目中CS(片選)可以不用。
2.2代碼
  1. # include <reg52.h>//頭文件
  2. # include <intrins.h>//頭文件

  3. # define uchar unsigned char
  4. # define uint unsigned int

  5. sbit SCK = P1^0;//位定義時鐘
  6. //sbit CS = P1^1;//位定義片選(使能)  此項目可以不使用
  7. sbit SDI = P1^2;//位定義Input
  8. sbit SDO = P1^3;//位定義Output

  9. /*-----函數聲明-----*/
  10. void delay5us();
  11. void SpiSend(uchar dat1);
  12. uchar SpiReceive();
  13. void UARTInit();

  14. /*-----主函數-----*/
  15. void main()
  16. {        
  17.         UARTInit();
  18.          while(1)
  19.     {
  20.                 SBUF = SpiReceive();// 循環接收數據
  21.     }
  22.         ;//空語句        
  23. }

  24. /*-----5微秒延時函數-----*/
  25. void delay5us()
  26. {
  27.         _nop_();
  28. }

  29. /*-----CPHA=0;CPOL=1 模式2-----*/
  30. /*-----SPI發送函數-----*/
  31. /*-----上升沿發送-----*/
  32. void SpiSend(uchar dat1)
  33. {
  34.         uchar i;
  35.         for (i=0; i<8; ++i)//8bit,一位一位寫
  36.         {
  37.                 SCK = 0;
  38.                 if (dat1 & 0x80)//判斷當前最高位為1還是0
  39.                 {
  40.                         SDO = 1;               
  41.                 }
  42.                 else
  43.                 {
  44.                         SDO = 0;
  45.                 }
  46.                 SCK = 1;//上升沿發送數據
  47.                 dat1 <<= 1;
  48.                 delay5us();               
  49.         }
  50. }

  51. /*-----SPI接收函數-----*/
  52. /*-----下降沿接收-----*/
  53. uchar SpiReceive()
  54. {
  55.         uchar i, dat0;
  56.         dat0 = 0x00;//dat0初始化
  57.         for (i=0; i<8; ++i)//8bit,一位一位讀
  58.         {
  59.                 dat0<<=1;
  60.         while(SCK == 1);   
  61.         while(SCK == 0);//下降沿讀取數據      
  62.         dat0 |= SDI;         
  63.         }
  64.         return (dat0);//收到數據(返回值)dat0
  65. }

  66. /*-----串口(中斷)初始化-----*/
  67. void UARTInit()
  68. {
  69.         EA = 1;//開啟總中斷
  70.         ES = 1;//打開串口中斷
  71.         SM0 = 0;SM1 = 1;//串口工作方式1,8位UART波特率可變
  72.         REN = 1;//串口允許接收
  73.         TR1 = 1;//啟動定時器1
  74.         TMOD |= 0X20;//定時器1,工作模式2 8位自動重裝
  75.         TH1 =0XFD;
  76.         TL1 =0XFD;//設置波特率9600
  77. }

  78. /*-----串口中斷服務函數-----*/
  79. void UART() interrupt 4
  80. {
  81.         if (RI)//判斷是否接收完成
  82.         {
  83.                 RI = 0;//軟件清零
  84.                 SpiSend(SBUF);// 轉發接收到的數據
  85.         }
  86.         if (TI)//判斷是否發送完成
  87.         {
  88.                 TI = 0;//軟件清零
  89.         }               
  90. }
復制代碼

      PS:SDI和SDO需交叉連接。

3.總結
  • 在發送數據時,時鐘僅由發送端(主機)控制;
  • SPI四種模式,只需將主從機同步一種模式即可;
  • SCK,SDI,SDO,CS四個引腳由自己定義即可。

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

來自 2#
ID:67274 發表于 2020-7-21 01:28 | 只看該作者
stc89c52做模擬SPI接收,STC15F104做模擬SPI發射,按照樓主源碼是收不到的,STC15F104必須增加到8us才可以成功。

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

板凳
ID:620021 發表于 2019-11-26 22:51 | 只看該作者
看看~~~~~~~
回復

使用道具 舉報

地板
ID:648072 發表于 2019-12-3 10:59 | 只看該作者
不錯不錯
回復

使用道具 舉報

5#
ID:67274 發表于 2020-7-18 03:33 | 只看該作者
這里有個問題,如果2種單片機速度不一樣,那樣模擬的結果無法通信。
回復

使用道具 舉報

6#
ID:1010785 發表于 2022-3-16 11:37 | 只看該作者
a461624201 發表于 2020-7-18 03:33
這里有個問題,如果2種單片機速度不一樣,那樣模擬的結果無法通信。

請問有解決辦法嗎
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产成人精品一区二区三区在线 | 亚洲一级av毛片 | 在线免费观看黄色 | 日韩免费视频一区二区 | 久草网站| 色性av| 中文字幕在线视频免费观看 | 精品一区二区三区在线视频 | 亚洲一区有码 | 韩国理论电影在线 | eeuss国产一区二区三区四区 | 日韩欧美国产一区二区 | 欧美一级片免费看 | 国产视频久久 | 毛片毛片毛片毛片毛片 | 亚洲精品视频在线看 | 欧美a级成人淫片免费看 | 精品国产欧美一区二区 | 97av在线| 国产精品久久久久久妇女 | 色婷婷综合久久久中字幕精品久久 | 亚洲成人一级片 | 亚洲网一区 | 亚洲v区 | 成人亚洲精品久久久久软件 | 国产精品欧美一区二区三区不卡 | 九色一区 | 久久99网| 亚洲国产一 | 久久亚洲国产精品 | 亚洲午夜三级 | 91在线看 | 欧美日韩亚洲视频 | 亚洲国产成人在线 | 免费黄色av网站 | 91免费在线播放 | 国产精品免费在线 | 91视频精选 | 日日操操操 | 蜜桃av一区二区三区 | 欧美日韩精品一区二区天天拍 |