在CW32生態社區以極高的性價比入手了這塊CW32L012開發評估板,開發板以底板、核心板、1.77寸TFT顯示屏構成,所有的IO口都引出了排針,這點好評,使用杜邦線可以非常方便的連接其他模塊。引腳、接口模塊的布局都非常合理,并且整板子都使用了黑色,顏值也杠杠在線的,非常方便我用來學習這顆芯片。這里邊還有一個非常小的細節,這個細小的設計很貼中我的使用習慣,核心板中的功能按鍵和復位按鍵進行了區分,白色的按鍵是功能按鍵,紅色的按鍵才是復位按鍵,讓我這種分不清左邊是復位按鍵還是右邊是復位按鍵的人一下就能按中復位按鍵了;
開發板介紹

這款開發評估板的設計非常巧妙,首先是電源部分,給出了一個12V的DC直流電源插口,有自恢復保險絲和保證電流單項導通的二極管,7805線性穩壓器將電壓從15V的電壓穩壓到5V,需要用到5V電壓的模塊此時接到這里完成5V供電,同時我們的芯片也從這里獲得5V的供電,這款芯片是寬電壓的芯片,用5V是完全沒有問題的;AMS1117-3.3是一款非常經典的5V穩壓到3.3V的線性穩壓器,此時需要用到3.3V的模塊在這里供電,在開發板的右側區域預留了大量的+5V、+3V3、GND的排針,方便外接模塊供電,這就是電源部分。

接著是顯示屏幕區域,這塊開發板做足的對屏幕的兼容,對0.91OLED,0.96OLED,1.77TFT屏幕都兼容,接口方面是4線SPI,2線的I2C,官方默認給配置的是一個8針的1.77TFT屏幕,在這篇文章我將著重介紹4線SPI,通過軟件模擬來實現SPI通訊協議,并測量其通訊速率。

板載的模塊設計了一個有源蜂鳴器,通過MCU的PB3引腳來控制SS8050三極管來開關斷蜂鳴器,可以完成蜂鳴器相關的實驗,三個按鍵分別是KEY1,KEY2,KEY3,三個LED燈分別是LED1,LED2,LED3,對應MCU的PB13,PB14,PB15,PA7,PA8,PC13,LED燈是低電平點亮,可以完成流水燈以及按鍵電燈實驗,一個電位器,可以調節電阻的大小,對應MCU的PB0口,通過調節電位器,來完成adc采集模擬電壓的實驗。
在核心板區域提供了TYPE-C單獨供電,留出了4針的SWO程序調式口,有一個復位按鍵和一個功能按鍵,預留了一個外部高速晶振和一個低速晶振,高速晶振支持4-32MHz,低速晶振是32.768KHz的,這款芯片沒有PLL倍頻器,內部時鐘頻率連接到外部高速晶振時,外部高速晶振最高是多少,那么內部時鐘頻率最高就是多少,但是這款芯片內部的RC振蕩器是96MHz的,這個頻率可以滿足大部分使用場景,還可以節省使用外部晶振的成本,那么使用這款芯片的時候大概率就是使用內部RC振蕩器了,官方也沒有配置外部晶振,只是設計了這個位置,估計也是和我有類似的考量吧。
最后這塊板子還提供了大量的外部模塊接口,可以拓展更多的模塊,增添了可玩性,由于這塊開發板已經極具性價比了,出于對成本的考量,官方是沒有配備拓展模塊,預留出來的模塊接口有8Pin的mpu6050,我們外接了這個模塊可以做一些與運動檢測相關的實驗,因為這個模塊是測量橫滾角、俯仰角、偏航角的,4Pin的電子秤模塊接口,可以做電子秤的實驗,2*4Pin的WIFI模塊,可以插ESP8266做物聯網相關的實驗,6Pin的藍牙模塊,可以做和手機通訊的實驗,9針的矩陣鍵盤接口,3Pin的溫濕度,插上dht11模塊可以測量溫度和濕度,以及預留了2個4針的串口,可以做串口通訊的實驗。
原理圖
原理圖來源于CW32生態社區,官方開源了硬件原理圖;


SPI通訊簡介
SPI,全稱為 串行外設接口,是一種高速、全雙工、同步的串行通信總線。它由摩托羅拉公司開發,因其簡單和高效的特點,被廣泛應用于微控制器、傳感器、存儲器、SD卡、觸摸屏等設備之間的短距離通信。
一、核心特點
全雙工通信:數據可以同時在兩個方向上傳輸(主機發送數據的同時,也能接收從機返回的數據)。
同步通信:所有數據傳輸都由主機產生的時鐘信號同步,通信雙方無需預先配置波特率。
高速:相比I2C、UART等協議,SPI可以達到很高的通信速率(通常可達幾十MHz甚至更高)。
簡單:協議本身非常簡單,沒有復雜的地址幀和應答機制,硬件實現也相對容易。
二、硬件連接(4線制)
一個標準的SPI總線需要至少4根信號線:
td {white-space:nowrap;border:0.5pt solid #dee0e3;font-size:10pt;font-style:normal;font-weight:normal;vertical-align:middle;word-break:normal;word-wrap:normal;}
| 信號線名稱 | 全稱 | 方向(以主機視角) | 功能描述 |
| SCLK | 串行時鐘 | 輸出 | 由主機產生,用于同步數據位傳輸的時鐘信號。 |
| MOSI | 主設備輸出,從設備輸入 | 輸出 | 主機向從機發送數據的線路。 |
| MISO | 主設備輸入,從設備輸出 | 輸入 | 主機從從機接收數據的線路。 |
| CS/SS | 片選 / 從設備選擇 | 輸出 | 由主機控制,用于選中要進行通信的特定從機。此信號通常低電平有效。 |
連接方式:
一主一從:連接最為簡單,四根線直接相連即可。
一主多從(標準模式):這是最常用的方式。主機為每個從機提供獨立的片選信號。同一時刻,只有一個片選信號有效,從而選中一個從機進行通信。
一主多從(菊花鏈模式):所有從機共用一根片選線,數據像鏈條一樣從一個從機傳遞到下一個。這種方式節省主機的I/O口,但軟件控制更復雜,且并非所有從設備都支持。
三、通信過程與工作原理
初始化:主機配置好時鐘極性(CPOL)和時鐘相位(CPHA),這決定了時鐘的空閑狀態和數據的采樣邊沿。
選擇從機:主機將目標從機的CS引腳拉至低電平。
數據傳輸:
主機在SCLK時鐘線上產生時鐘脈沖。
在每個時鐘周期內,主機通過MOSI線發送一位數據,同時通過MISO線讀取一位數據。
這意味著每次移位操作實際上是一次主從設備的數據交換。主機發送一個字節的同時,也會收到從機返回的一個字節。
取消選擇:通信完成后,主機將CS引腳拉回高電平。
一個生動的比喻:
可以把SPI通信想象成兩個面對面的的人(主機和從機)在進行一場同步的“說聽”練習。SCLK是節拍器,確保節奏一致。MOSI是主機說話的通道,MISO是主機聽音的通道。CS就像是主機決定是否要與對面的人對話的開關。當開關打開(CS拉低),隨著節拍器的每個節拍,主機說一個字的同時,也能聽到對方回一個字。
四、時鐘極性與相位
這是SPI配置中的一個關鍵概念,決定了時鐘空閑時的電平和數據采樣的時刻。通過組合CPOL和CPHA,主要有四種模式:
td {white-space:nowrap;border:0.5pt solid #dee0e3;font-size:10pt;font-style:normal;font-weight:normal;vertical-align:middle;word-break:normal;word-wrap:normal;}
| 模式 | CPOL (時鐘極性) | CPHA (時鐘相位) | 時鐘空閑狀態 | 數據采樣時刻 |
| 0 | 0 | 0 | 低電平 | 時鐘的第一個邊沿(上升沿) |
| 1 | 0 | 1 | 低電平 | 時鐘的第二個邊沿(下降沿) |
| 2 | 1 | 0 | 高電平 | 時鐘的第一個邊沿(下降沿) |
| 3 | 1 | 1 | 高電平 | 時鐘的第二個邊沿(上升沿) |
要點:主設備和從設備必須工作在相同的模式下才能正常通信。
軟件模擬SPI通訊
總之,SPI是一種在嵌入式領域極其重要且實用的通訊協議,它在高速數據交換的設備中扮演著關鍵角色。
SPI可以通過軟件模擬和硬件外設資源實現,軟件模擬SPI是指在不用硬件電路SPI控制器的情況下,通過通用輸入輸出引腳(GPIO)和程序代碼來模擬SPI通信時序的方法。我將通過這種方式來點亮官方配置的這一塊1.77寸TFT屏幕,讓屏幕顯示出圖片。
實現思路
使用普通的GPIO引腳分別模擬SCLK、MOSI、MISO、CS功能
通過程序控制引腳電平變化來生成SPI時序
用延時函數或精確計時控制通信時序
代碼實現
#if !defined(__SPI_H__) #define __SPI_H__ #include "cw32l012_sysctrl.h" #include "cw32l012_gpio.h" #include "cw32l012_spi.h" #include "cw32l012_systick.h" void SPI1_Init(void); uint8_t SPI_SwapByte(uint8_t byte); #define SPI_W_CS(x) GPIO_WritePin(CW_GPIOB, GPIO_PIN_5, (GPIO_PinState)x) #define SPI_W_CLK(x) GPIO_WritePin(CW_GPIOB, GPIO_PIN_6, (GPIO_PinState)x) #define SPI_W_MOSI(x) GPIO_WritePin(CW_GPIOB, GPIO_PIN_7, (GPIO_PinState)x) #define SPI_R_MISO() GPIO_ReadPin(CW_GPIOA, GPIO_PIN_6) #define SPI_W_RTS(x) GPIO_WritePin(CW_GPIOA,GPIO_PIN_15, (GPIO_PinState)x) #define SPI_W_DC(x) GPIO_WritePin(CW_GPIOB,GPIO_PIN_4, (GPIO_PinState)x) #endif // __SPI_H__
#include "SPI.h"
void SPI1_Init(void)
{
SYSCTRL_AHBPeriphClk_Enable(SYSCTRL_AHB_PERIPH_GPIOA|SYSCTRL_AHB_PERIPH_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.IT = GPIO_IT_NONE;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Pins = GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
GPIO_Init(CW_GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.IT = GPIO_IT_NONE;
GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
GPIO_InitStructure.Pins = GPIO_PIN_6;
GPIO_Init(CW_GPIOA, &GPIO_InitStructure);
GPIO_WritePin(CW_GPIOB, GPIO_PIN_6, GPIO_Pin_RESET);
GPIO_WritePin(CW_GPIOB, GPIO_PIN_5, GPIO_Pin_SET);
GPIO_InitStructure.IT = GPIO_IT_NONE;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Pins = GPIO_PIN_15;
GPIO_Init(CW_GPIOA, &GPIO_InitStructure);
}
uint8_t SPI_SwapByte(uint8_t byte)
{
uint8_t read_byte = 0x00;
for (uint8_t i = 0; i < 8; i++)
{
if (byte & 0x80)
{
SPI_W_MOSI(1);
}
else
{
SPI_W_MOSI(0);
}
byte <= 1;
SPI_W_CLK(1);
read_byte <= 1;
if ((uint8_t)SPI_R_MISO())
{
read_byte |= 0x01;
}
SPI_W_CLK(0);
}
return read_byte;
}
這就是軟件模擬SPI的底層驅動,由于屏幕顯示圖片的代碼數量太長了,這里就沒有分享出來了;
軟件模擬SPI的優缺點
優點
靈活性高:可以在任何有GPIO的設備上實現
引腳可配置:可以任意選擇可用的GPIO引腳
多設備支持:可以輕松創建多個SPI總線實例
調試方便:可以添加調試信息和時序監控
成本低:不需要專門的硬件SPI控制器
缺點
速度較慢:受限于CPU速度和軟件延時精度
CPU占用高:通信期間CPU需要持續處理時序
時序精度差:受中斷和其他任務影響,時序可能不穩定
實時性差:不適合高速或實時性要求高的應用
實現復雜:需要仔細處理各種SPI模式和時序
實現效果

傳輸速度測試
這次對于SPI的實驗做到這里其實基本算已經完成了,但是每次寫通訊協議的代碼的時候,我都希望把每種通訊協議的性能拉滿,然后看看具體能達到多少速度,這次正好寫了SPI通訊的文章,出于對軟件模擬SPI通訊協議速度的好奇,那么我就想在這里測一測我這個實驗的通訊協議的速度;
這顆芯片的官方手冊說明了內部集成 3個串行外設接口(SPI), 主機模式下 SCK 頻率高達 24MHz,理論上最大的傳輸速度是24Mbit/s,實際的傳輸速度是遠遠低于這個傳輸速度的,因為成功發送一個字節數據有協議開銷,處理器和軟件開銷。這是硬件SPI支持的最大數據傳輸速度,大家可以從我的底層代碼可以看到,MCU內核對于代碼的執行我是沒有添加任何的延時阻塞的,我在main.c中把時鐘的也配置到了這顆芯片最大的時鐘頻率96MHz,那么這顆芯片處理SPI底層代碼,也就是發送一個字節的數據是按照最大速度執行的,然后我找來了示波器。
我們來看看示波器測試的結果:

黃色的線是SCLK的波形,藍色是MOSI信號線的波形

通過示波器的光標我們可以看到發送一個字節需要的時間是18.6us,發送一位需要的時間就是18.6us/8=2.325us,那么1s發送的位數為:1s/2.325us=430107.5268,約等于430.107Kbit/s。即使去掉MCU內核去處理其他代碼的時間,黃色的線間距較寬的地方就是內核去處理其他代碼的時候,那么發送8個bit位用時14us,發送一位需要的時間就是14us/8=1.75us,1s發送的數據位是1s/1.75us=571428.5714,約等于571.428Kbit/s;
審核編輯 黃宇
-
開發評估板
+關注
關注
0文章
2瀏覽量
703
發布評論請先 登錄
CW32L012與STM32G431的CORDIC三角函數運算性能對比
CW32L012與STM32F103的三角運算性能對比
基于武漢芯源CW32F030C8T6直流無刷電機評估開發板的設計方案
CW32L012小型機器人控制評估板活動 四足機器人+智能小車 開箱評測
CW32L012小機器人的電機控制
使用芯源CW32的CW32L012開發評估板做了spi屏幕驅動
評論