[STM32] 18-SPI

Morgan Ting
閱益如美
Published in
12 min readNov 12, 2022
Photo by Tim Käbel on Unsplash

Serial Peripheral Interface, SPI ,是一種同步串列傳輸介面。SPI 介面簡單傳輸可靠被使用在諸多裝置的介面上,例如EEPROM、SD Card…等。本文章介紹 STM32 的 SPI 功能並利用移位暫存器 74595 來進行實作,開發環境為 STM32CubeIDE 以及搭配 Hardware Abstraction Layer, HAL 函式庫。

文章內容

  1. SPI 通訊簡介
  2. STM32 的 SPI
  3. 74595 移位暫存器
  4. 實作
  5. 成果展示

工具與材料

  1. STM32CubeIDE
  2. Blue Pill ( STM32F103C8T6 ) 開發板
  3. ST-LINK v2
  4. 共陽極七段顯示器 * 1
  5. 220 Ω 電阻 * 7
  6. 麵包板與單芯線

SPI 通訊簡介

Serial Peripheral Interface Bus, SPI ,是一種全雙工高速同步式傳輸介面,由 Motorora 公司於 1980 年代中期發表,隨後被廣為應用在記憶體相關產品上。

SPI 以主-從式 ( Master / Slave ) 方式進行通訊,可單一主機搭配單部或多部從機。

SPI 硬體接線主要有 4 條線,分別說明如下:

  • MOSI ( Master Output Slave Input ) 於主機模式作為輸出,從機模式作為輸入。
  • MISO ( Master Input Slave Output ) 於主機模式作為輸入,從機模式作為輸出。
  • SCLK ( Serial Clock ) 串列時脈,由主機發出。
  • SS ( Slave Select ) 從機選定,選定特定從機進行通訊。依裝置應用需求,可不使用。

STM32 的 SPI

STM32 的 SPI 介面有以下特點:

  • 3 線全雙工同步傳輸。
  • 8 或 16 位元資料傳輸長度。
  • 主 — 從 ( Master — Slave ) 式操作,也支援多主機模式。
  • 可選擇數據傳輸順序,MSB 或 LSB 位元優先傳輸。
  • 傳輸與接收完成可觸發中斷。
  • 可設定時鐘極性 ( CPOL ) 與相位 ( CPHA )。
  • 提供CRC 偵錯。
  • 提供 DMA 1 Byte 傳送與接收緩衝器發起傳送與接收請求。

STM32 的 SPI 系統方塊圖

Ref : datasheet

由系統方塊圖可以明顯看到 4 個硬體腳位組成通訊界面,其中 NSS 即從機選擇線一般是低電位致能,MOSI / MISO 組成全雙工通訊而SCK 則由主機發出作為同步訊號。由於 SPI 是串列傳輸因此可見移位暫存器 ( Shift Register ) 存放資料。

SPI 有 4 種通訊模式是由時鐘極性 ( CPOL ) 與時鐘相位 ( CPHA ) 組合而成。

SPI Mode

那麼,時鐘極性 ( CPOL ) 與時鐘相位 ( CPHA ) 又是什麼呢 ?

時鐘極性 ( CPOL ) 用來表示空閒時的電位狀態。

  • CPOL = 0 :表示當 SCLK 為低電位時處於空閒狀態,因此SCLK 為高電位時才會工作。
  • CPOL = 1 :表示當 SCLK 為高電位時處於空閒狀態,因此SCLK 為低電位時才會工作。

時鐘相位 ( CPHA ) 用來表示何時栓鎖 / 取樣資料。

  • CPHA = 0 :在 SCLK 時脈的第一個邊緣對資料取樣。
  • CPHA = 1 :在 SCLK 時脈的第二個邊緣對資料取樣。
Ref : datasheet

常見 SPI 連接結構

STM32F103C8T6 的 SPI 腳位

Pin mapping

74595 移位暫存器

74595 是一款串列輸入並列輸出的移位暫存器,以本文章所使用由德州儀器出品的 74HC595 而言具有以下特性:

  • 8 位元串列輸入,並列輸出。
  • 工作電壓範圍 2 ~ 6 v。
  • 低輸入電流,約 1uA。

74595 腳位

Ref : datasheet

由系統方塊圖可進一步了解功能

Ref : datasheet

資料由 SER 進入,主機端的同步時脈送入 SRCLK 而圖中的暫存器是負緣觸發且 SRCLK 進入後又經過一個反閘 ( Not Gate ) ,因此推斷 SRCLK 處於上升緣時會驅動暫存器。資料依序傳入後須透過 RCLK 時脈驅動第二級暫存器,其原理同 SRCLK 因此 RCLK 在上升緣時會將資料送到第二級,最後由 OE 控制資料是否輸出,當輸出端的三態閘被 OE 驅動就像打開水龍頭一樣資料就會輸出到硬體腳位 QA ~ QH 。

實作

此次實驗利用移位暫存器 74HC595 與 STM32 的 SPI 介面進行通訊,屬於單向單工的應用。選用 SPI_1 介面用到 MOSI 、SCK 與 NSS 腳位做資料推送,此外 74HC595 尚須控制線對RCLK 進行控制。74HC595 輸出端接一個共陽極七段顯示器來顯示數字,程式內會依序送出數字 0 至 9 的編碼。

電路圖

硬體接線

七段顯示器的腳位

一、開啟 STM32CubeIDE 開發環境,建立一個新的專案。

start a project

二、選擇微處理器型號,輸入F103C8 可以快速找到,選擇該型號後按下 「Finish」鍵。

target selection

三、輸入專案名稱後按下「Finish」鍵。

project name

四、設定 SYS ,這邊的 Debug 選項選擇 「Serial Wire」。

SYS

五、RCC 時脈源,HSE 選擇 「Crystal / Ceramic Resonator」,其中 HSE 是連接開發板上的 8 MHz 震盪器提供系統使用。

RCC

六、 Clock Configuration 設定系統時脈為 72 MHz 。

Clock Configuration

七、點開 「Connectivity 」可以看到各項通訊界面,選擇 SPI1。

Mode 選擇 「Transmit Only Master 」。

Hardware NSS Signal 選擇 「Disable」不啟用這項功能。

SPI 1 Configuration

參數設定

  • Data Size : 8 Bit ,一次送 8 位元資料。
  • First Bit : MSB First ,從最高位元開始送資料。
  • Prescaler : 分頻,選擇 16 後底下會顯示鮑率。依傳輸對象的工作頻率做設定,參考74HC595 在 2 v 工作電壓時其時脈頻率可以到 5 MHz 。
  • Clock Polarity ( CPOL ) 時鐘極性 : Low 。
  • Clock Phase ( CPHA ) 時鐘相位 : 1 Edge 。

這樣的時鐘極性與時鐘相位的組合其實就是 SPI 模式 0 。選擇何種模式須依傳輸對象做設定,翻閱74HC595 手冊得知在此模式下運作。

八、將 PA4 腳位設定成輸出模式,並賦予別名 RCLK ,表示此腳位連接到 74HC595 的 RCLK 腳,該腳位控制資料送到第二級。 PA4 原本是 SPI 的 NSS 腳,但我們未啟用 NSS 功能因此將其當作一般 I / O 腳即可。

九、project manager 原則上不需要設定,看一下是否有異即可。

十、產生程式碼,可以按存檔鍵或是點擊上方 「Project 」=> 「Generate Code 」產生程式碼。

Generate Code

十一、在程式碼中找到 / * USER CODE BEGIN PFP * / 區段,宣告一個函數用來傳輸一個 Byte 資料。

void send_byte(uint8_t * Data, uint16_t Size);

在 / * USER CODE BEGIN 0 * / 區段,宣告一個陣列變數存放數字編碼,這是共陽極使用的編碼。

uint8_t num[] = { 
0xC0, // 0
0xF9, // 1
0xA4, // 2
0xB0, // 3
0x99, // 4
0x92, // 5
0x82, // 6
0xF8, // 7
0x80, // 8
0x90, // 9
0xFF, // clear 7-segment, show nothing
};
code for common anode

在 /* USER CODE BEGIN 2 */ 區段實作傳送 1 Byte 資料函數,其步驟為:

  • 送出低電位給 74HC595 的 RCLK 腳位,準備接收資料。
  • 使用 HAL 函式庫的 SPI 傳輸函式傳送 1 Byte 資料。
  • 送出高電位給 74HC595 的 RCLK 腳位,栓鎖資料 ( 送到 74HC595 第二級 )。

以上 3 步驟即完成 1 Byte 資料傳輸,很簡易。

void send_byte(uint8_t * Data, uint16_t Size)
{
HAL_GPIO_WritePin(RCLK_GPIO_Port, RCLK_Pin, GPIO_PIN_RESET); // 送低電位給 74HC595 的 RCLK 腳位
HAL_SPI_Transmit(&hspi1, Data, Size, 100); // 送出 1 Byte 資料,逾時時間為 100 毫秒
HAL_GPIO_WritePin(RCLK_GPIO_Port, RCLK_Pin, GPIO_PIN_SET); // 送高電位給 74HC595 的 RCLK 腳位
}

在 While 循環區段中寫一段程式重複傳送 0 ~ 9 數字編碼,先傳送清除編碼 0xFF 讓七段顯示器關閉之後再傳送數字編碼,這樣做可以讓七段顯示器不致於產生殘影。每隔 500 毫秒傳送一次編碼,0 ~ 9 傳送完畢後稍停 1 秒鐘再重複以上程序。

for(int index = 0; index < 10 ; index++)
{
send_byte(&num[10], 1);
send_byte(&num[index], 1);
HAL_Delay(500);
}
HAL_Delay(1000);

十一、完成程式碼撰寫後進行編譯程序,按下綠色箭頭按鈕。

十二、在 Debugger 項目將 「ST-LINK S/N 」打勾並點擊右方 「SCAN」按鈕。

此時會顯示 ST-Link v2 編號,沒問題後按下 「OK 」按鈕即開始編譯並上傳程式到開發板。

成果展示

程式開始運行後可以觀查到七段顯示器顯示數字 0 至 數字 9 ,之後重複循環。依手冊說明 74HC595 可工作於 2 v 至 6 v ,於 2 v 供電時可運作傳輸頻率最高為 5 MHz。在電路接線中將 74HC595 電源接至 3.3 v ,傳輸頻率由 STM32CubeIDE 設定為 4.5 MHz ,時鐘極性 ( CPOL ) 與時鐘相位 ( CPHA ) 構成 SPI 傳輸模式 0 ,以上條件運行無礙。

Result

總結

本次 STM32 的 SPI 實作利用 74HC595 移位暫存器作為傳輸對象,傳送資料給 74HC595 並推動一個共陽極七段顯示器。

本文章總結如下:

  • SPI 為串列傳輸。
  • 主 — 從式架構 ( Master — Slave ) 。
  • 傳輸資料長度可設定為 8 位元或 16 位元。
  • SPI 工作時脈頻率可選擇分頻降低匯流排提供的時脈頻率。
  • 可全雙工傳輸。
  • 提供中斷與 DMA 請求。
  • 提供 8位元與 16 位元 CRC 偵錯。
  • 時鐘極性 CPOL 與時鐘相位 CPHA 構成 4 種工作模式。

參考資料

  1. STM32F103 手冊 [ 連結 ]
  2. STM32F1 HAL and Low-layer drivers [ 連結 ]
  3. STM32F103 電器特性 [ 連結 ]
  4. TI 74HC595 手冊 [ 連結 ]

感謝讀者

若文章有幫助到您可以拍手給我鼓勵,免費支持我。

相關文章

  • [STM32] 00-Install STM32CubeIDE [連結]
  • [STM32] 01-ST-LINK [連結]
  • [STM32] 02-STM32F103C8T6 [連結]
  • [STM32] 03-GPIO-Output [連結]
  • [STM32] 04-GPIO-Input [連結]
  • [STM32] 05-Ext-Interrupt [連結]
  • [STM32] 06-Timer-Basic [連結]
  • [STM32] 07-Timer-Interrupt [連結]
  • [STM32] 08-Timer-Output_Compare [連結]
  • [STM32] 09-Timer-PWM [連結]
  • [STM32] 10-Timer-Input_Capture [連結]
  • [STM32] 11-RTC-Second-Interrupt [連結]
  • [STM32] 12-RTC-Alarm_Interrupt [連結]
  • [STM32] 13-Independent_Watch_Dog [連結]
  • [STM32] 14-Windows_Watch_Dog [連結]
  • [STM32] 15-ADC_Conversion [連結]
  • [STM32] 16-ADC_Conversion_Temperature_Sensor [連結]
  • [STM32] 17-ADC_Convversion_DMA [連結]
  • [STM32] 18-SPI [連結]
  • [STM32] 19-UART [連結]
  • [STM32] 20-I2C [連結]

--

--

Morgan Ting
閱益如美

用好奇心探索世界。喜愛學習樂於分享。