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

来源:https://www.cnblogs.com/benjiah/archive/2019/08/20/11381108.html
-Advertisement-
Play Games

SPI協議簡述 SPI,是英語Serial Peripheral interface的縮寫,顧名思義就是串列外圍設備介面。由Motorola首創。SPI介面主要應用在 EEPROM,FLASH,實時時鐘,AD轉換器,還有數字信號處理器和數字信號解碼器之間。SPI,是一種高速的,全雙工,同步的通信匯流排 ...


SPI協議簡述

  SPI,是英語Serial Peripheral interface的縮寫,顧名思義就是串列外圍設備介面。由Motorola首創。SPI介面主要應用在 EEPROM,FLASH,實時時鐘,AD轉換器,還有數字信號處理器和數字信號解碼器之間。SPI,是一種高速的,全雙工,同步的通信匯流排。

優缺點:

  • 協議簡單,相對數據速率高。
  • 占用的Pin口較多
  • 沒有指定的流控制,沒有應答機制確認是否接收到數據。

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為主機接受,從機發送。

參考網站:http://dlnware.com/theory/SPI-Bus

SPI的四種模式

 

這四種模式分別為:
模式  CPOL CPHA
MODE0 0 0
MODE1 0 1
MODE2 1 0
MODE3 1 1

 

參考網站:http://dlnware.com/theory/SPI-Transfer-Modes

 

在這四種模式中,我們常用MODE0和MODE2。因為它便於操作。我便是使用的MODE2模式。這四種模式的區別在參考網站中有詳細的描述,這裡便不再贅述。
  
在MODE2模式下。時鐘在空閑時始終置1,每產生一次下降沿便會發送1 bit 數據。大家可能已經想到,SPI協議可以在八位沒有發出送完的情況下停止發送。
  
這裡我跑了下示波器。
  
  從圖中清晰可見8個下降沿,時鐘在空閑時始終置1。
  
  其餘的三個模式以此類推。

軟體模擬

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

代碼

# include <reg52.h>//頭文件
# include <intrins.h>//頭文件

# define uchar unsigned char
# define uint unsigned int

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

/*-----函數聲明-----*/
void delay5us();
void SpiSend(uchar dat1);
uchar SpiReceive();
void UARTInit();

/*-----主函數-----*/
void main()
{    
    UARTInit();
     while(1)
    {
        SBUF = SpiReceive();// 迴圈接收數據
    }
    ;//空語句    
}
 
/*-----5微秒延時函數-----*/
void delay5us()
{
    _nop_();
}

/*-----CPHA=0;CPOL=1 模式2-----*/
/*-----SPI發送函數-----*/
/*-----上升沿發送-----*/
void SpiSend(uchar dat1)
{
    uchar i;
    for (i=0; i<8; ++i)//8bit,一位一位寫
    {
        SCK = 0;
        if (dat1 & 0x80)//判斷當前最高位為1還是0
        {
            SDO = 1;        
        }
        else
        {
            SDO = 0;
        }
        SCK = 1;//上升沿發送數據
        dat1 <<= 1;
        delay5us();        
    }
}

/*-----SPI接收函數-----*/
/*-----下降沿接收-----*/
uchar SpiReceive()
{
    uchar i, dat0;
    dat0 = 0x00;//dat0初始化 
    for (i=0; i<8; ++i)//8bit,一位一位讀
    {
        dat0 <<= 1;
        while(SCK == 1);    
        while(SCK == 0);//等待下降沿,下降沿讀取數據       
        dat0 |= SDI;         
    }
    return (dat0);//收到數據(返回值)dat0
}

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

/*-----串口中斷服務函數-----*/
void UART() interrupt 4
{
    if (RI)//判斷是否接收完成
    {
        RI = 0;//軟體清零
        SpiSend(SBUF);     // 轉發接收到的數據
    }
    if (TI)//判斷是否發送完成
    {
        TI = 0;//軟體清零
    }        
}

 

PS:SDI和SDO需交叉連接。

總結

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

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 背景 By 魯迅 By 高爾基 說明: 1. Kernel版本:4.14 2. ARM64處理器 3. 使用工具:Source Insight 3.5, Visio 1. 介紹 子系統負責在運行時對CPU頻率和電壓的動態調整,以達到性能和功耗的平衡,它也叫 。 原理:CMOS電路中功耗與電壓的平方成 ...
  • 最近由於業務系統新需求的需要,我們平臺需要將供應商G提供一類數據轉換格式後提供給客戶K。比較頭疼是供應商G提供的數據都是在Windows下使用Excel存儲的,而客戶K先前與我們相關對接人員商定的數據類型必須使用utf-8的txt文件,並且由於客戶K程式處理的需要,並附帶生成一個與該數據文件匹配的校 ...
  • Windows下的Linux子系統安裝,WSL 2下配置docker 安裝WSL 2需要Windows 10版本是Build 18917或更高,首先先確認系統版本已升級。 在“啟用或關閉Windows功能”中啟用以下兩個選項:Windows虛擬機平臺、適用於Linux的Windows子系統。 啟用這 ...
  • windows系統: 部署了一個Tomcat8.5.15,bin目錄下startup.bat執行,結果提示Neither the JAVA_HOME nor the JRE_HOME environment variable is defined At least one of these envi ...
  • 查看zabbix_agentd.log時出現下列錯誤 [root@4gronghe_110 ~]# tail /var/log/zabbix/zabbix_agentd.log 1266:20140523:063554.157 no active checks on server [127.0.0. ...
  • 什麼是虛擬機? 虛擬化是在Host操作系統之上導入Guest操作系統的技術。這種技術最初是一個啟示,因為它允許開發人員在同一主機上運行的不同虛擬機中運行多個操作系統。這消除了對額外硬體資源的需求。 虛擬機或虛擬化的優點是: 多個操作系統可以在同一臺機器上運行 在出現故障的情況下,維護和恢復很容易 由 ...
  • 總結: 遇到的問題:No support for locale: zh_CN.utf8 可能的解決方法:1.sudo dpkg-reconfigure locale (重新配置?) 2.上一步失敗,提示locale 未安裝,於是安裝之: sudo dpkg-reconfigure locale 3. ...
  • (一) 軟體介紹由俄羅斯人lgor Sysove開發,為開源軟體。支持高併發:支持幾萬併發連接(特別是靜態小文件業務環境) 資源消耗少:在3萬併發連接下開啟10個Nginx線程消耗記憶體不到200M 支持非同步網路I/O事件模型epoll(Linux2.6+) apache(select)功能介紹 1. ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...