# Topic-8 SPI (NOR flash)
## SPI (Serial Peripheral Interface)
SPI(Serial Peripheral Interface)是一種常見的串列通訊協議,用於在MCU和外部設備之間進行高速數據傳輸。SPI通訊通常用於連接MCU與各種外部設備,如感測器、螢幕、儲存裝置、無線模組等。
### 基本原理
#### SPI通訊是一種同步通訊協議,它基於主從(Master-Slave)架構。以下是SPI通訊的基本原理:
**主機(Master)**:MCU當主機,生成時鐘訊號並控制數據傳輸。
**從機(Slave)**:外部設備(如感測器或儲存裝置)當從機,按照主機的時鐘訊號進行數據傳輸。
#### SPI通訊使用四條訊號線進行通訊
SCLK(Serial Clock):主機生成的時鐘訊號,用於同步數據傳輸。
MISO(Master In Slave Out):從機到主機的數據傳輸線,用於將數據從從機傳輸到主機。
MOSI(Master Out Slave In):主機到從機的數據傳輸線,用於將數據從主機傳輸到從機。
CS/SS(Chip Select/Slave Select):選擇要與主機通訊的從機的信號線。當CS/SS訊號為低電位時,表示該從機被選擇。


#### SPI(Serial Peripheral Interface)為主從式同步串列通訊,可分為單工/全雙工
單工:線路上的訊號只能做單向傳送
半雙工:線路上的訊號可以雙向傳送 , 但是不能同時傳送
全雙工:線路上的訊號可以同時雙向傳送
同步:傳送端和接收端共用同一個CLOCK
所有的傳輸都會根據一個共同的頻率訊號 , 此頻率訊號產生自”主控裝置(Master端)”, 從屬裝置(Slave端)會用此頻率訊號來對收到的位串流進行同步
如果有多個周邊晶片被連到同一個SPI介面 , 主控裝置能透過SS pin腳的電位高低來選擇接收資料的周邊裝置

SPI_CR1 中有兩個 bits 時鐘極性CPOL 和 時鐘相位CPHA 控制取值的時間關係,總共有4種組合。
CPOL(clock polarity) 決定閒置時 clock 的電位。
CPOL = 0 表閒置時為低電位。
CPOL = 1 表閒置時為高電位。
CPHA(clock phase) 決定在 clock 的哪個 edge 取值。
CPHA = 0 表示在第一個 edge (Rising,when CPOL=0.Falling,when CPOL=1.)取值。
CPHA = 1 表示在第二個 edge (Falling,when CPOL=1.Rising,when CPOL=0.)取值。

## W25Q32FV - Serial NOR Flash
快閃記憶體(NOR Flash)是一種非揮發性記憶體技術,廣泛應用於嵌入式系統和儲存設備中。
### 基本特性
非揮發性:即使在沒有電力的情況下,存儲在 NOR Flash 中的數據也不會丟失。
可擦寫性:數據可以寫入、讀取和擦除,但在操作上一般需要擦除整個扇區或區塊,而不是單個字節。
Nor Flash主要應用在程式碼的儲存,容量較小、寫入速度慢,但因隨機讀取速度快,不適合朝大容量發展,主要用在手機上,目前以16Mb、32Mb為主。


### W25Q32 記憶體結構:
W25Q32 共有 64 個block,因此總容量為 4MB。
區塊 (block):
每個block的大小為 64KB。 1 block = 16 sector。
扇區 (sector):
每個sector的大小為 4KB。1 sector = 16 page。
頁 (page):
1 page = 256byte。
字節 (byte):
1 byte = 8 bit。每個byte有唯一的address。
位 (bit):
最小的單位是bit,每個bit的值是 1 或 0。每 8 bit 構成 1 個byte。
### W25Q32 常用指令集(非所有指令)

## 實作
## Demo
{%youtube _nCUfQEKNps %}
## STM32CubeIDE設定
### PIN 設定

---
### GPIO設定

---
### RCC設定

---
### SYS設定

---
### SPI1啟用


---
### UART設定

---
### Clock設定

---
### 外設檔案分開+生成

#### 生成程式碼

---
### 建立 W25Q32.c及W25Q32.h


---
### Nucleo_Pinou

---
### 電路圖

---
## SPI + NOR flash(W25Q32) 實作
### 程式碼
####
:::spoiler usart.c
{%gist /shiaw87/09dec84840d9a0b98cf144d9f2969985 %}
:::
####
:::spoiler main.c
{%gist /shiaw87/b172cbb82083f4db644f06ee211c9e0f %}
:::
####
:::spoiler W25Q32.c
{%gist /shiaw87/3d47ed11c466c0f53215366897a76ec3 %}
:::
####
:::spoiler W25Q32.h
{%gist /shiaw87/5a889b19d7637e58fdc874d0cc99ef37 %}
:::
## TFT ILI9341實作
## Demo
{%youtube _0Ot_U6uRhs %}
## STM32CubeIDE設定
### PIN 設定

---
### GPIO設定

---
### RCC設定

---
### SYS設定

---
### TIM設定

---
### SPI設定
選



---
### NVIC 設定

---
### CRC設定

___
### touchGFX設定


___
### Clock設定

---
### 外設檔案分開+生成

#### 生成程式碼

---
### Nucleo_Pinou

---
### 電路圖

---
## ILI9341實作
[下載touchGFX](https://www.st.com/en/development-tools/touchgfxdesigner.html)
---
### 程式碼
#### main.c
:::spoiler
{%gist /shiaw87/0dd6c5c81c47d50fdc3edbd5700aa713 %}
:::
{%gist /shiaw87/0dd6c5c81c47d50fdc3edbd5700aa713 %}
#### z_displ_ILI9XXX.h
:::spoiler
{%gist /shiaw87/c222e228084efeaa4c7390281a45a624 %}
:::
#### z_displ_ILI9XXX.c
:::spoiler
{%gist /shiaw87/85c629b6727ed8f86417e8e40731e0eb %}
:::
### z_touch_XPT2046.h
:::spoiler
{%gist /shiaw87/20cb8f64c8fdcf0e66f641228f63564e %}
:::
### z_touch_XPT2046.c
:::spoiler
{%gist /shiaw87/cbf270d4f1dcb77e41a1c4680b26f07f %}
:::
### STM32TouchController.cpp
:::spoiler
{%gist /shiaw87/8ba7a2dc1d99c53064082cc37f9d6713 %}
:::
### touchGFX設定
點擊



調整UI介面

添加背景

把原本的背景刪除

可以模擬看看成效

完成後就可以生成程式碼了

##
[📖參考資料](https://www.youtube.com/watch?v=g1siKaPox88)