STM32的SPI通信(軟件讀寫W25Q64)

在了解完I2C通信后,不免會接觸到到SPI通信。而一開始,可能會覺得兩者好似沒什么區別。為什么要學SPI呢,I2C和SPI有什么區別呢。為此我詳細展開說說。

1.什么是 SPI?

SPI,全稱 Serial Peripheral Interface,中文翻譯為串行外設接口,是一種 主從式、同步、全雙工 的串行通信協議。

三個關鍵詞:
主從式:一個主機控制多個從設備(主發起,從響應)

同步式:數據傳輸由時鐘信號(SCK)控制同步

全雙工:可以邊發送邊接收,MOSI/MISO 兩條獨立數據線

2.SPI 的 4 根基本信號線結構

名稱主機作用方向描述
SCK主機 → 從機同步時鐘線,主機輸出時鐘,控制數據采樣節奏
MOSI主機 → 從機主機輸出、從機輸入,主機發數據給從機
MISO從機 → 主機從機輸出、主機輸入,從機回傳數據給主機
CS主機 → 從機片選信號(Chip Select),低電平有效,用來告訴從機“你被選中通信了”

注意:

SCK、MOSI、CS 都是主機控制輸出;

MISO 是主機讀取輸入;

SPI 是一種基于邊沿的協議 —— 數據變化和數據采樣都是“在時鐘跳變沿發生”。

3.SPI 是怎么工作的?(核心機制)

接下來我來對比 SPI 四種模式(Mode 0~3)的行為差異,包括:

CPOL(時鐘空閑電平)

CPHA(數據采樣邊沿)

MOSI 數據什么時候改變

從機什么時候采樣數據

這四種模式是 SPI 協議中最核心也最容易混淆的部分。我現在徹底講明白它們的邏輯區別、時序差異、電平行為和通信節奏。

CPOL 與 CPHA 是什么含義?

CPOL:決定 SCK 在“空閑狀態”的電平(即不傳數據時 SCK 是高還是低)

CPOL = 0 → 空閑時 SCK = 低電平

CPOL = 1 → 空閑時 SCK = 高電平

CPHA:決定 在哪一個邊沿采樣數據

CPHA = 0 → 第一個邊沿采樣

CPHA = 1 → 第二個邊沿采樣

注意:這里是邊沿,不是具體到上升沿還是下降沿,第一個邊沿可能是上升沿也可能是下降沿。

第一個邊沿 = 從空閑態開始的第一個跳變(比如 CPOL=0,SCK 從 0→1 是第一個邊沿)

模式CPOLCPHASCK 空閑狀態采樣邊沿傳輸邊沿(MOSI 改變時刻)
Mode 000低電平上升沿下降沿
Mode 101低電平下降沿上升沿
Mode 210高電平下降沿上升沿
Mode 311高電平上升沿下降沿

我以發送一個字節數據(0xA5 = 10100101)為例,分析 SPI 每一位是如何傳輸的。

Step by Step 時序過程(?SPI Mode 0 )

通信準備階段:
主機將 CS 拉低,激活目標從機(W25Q64)

數據準備完畢,等待時鐘同步

第一位傳輸(發送 bit 7:1)

主機將 MOSI 設置為 1

主機將 SCK 從低拉高(上升沿)

從機在上升沿采樣 MOSI 上的值(記錄 bit7=1)

主機將 SCK 拉低,完成本位傳輸

第二位傳輸(bit6 = 0)

主機將 MOSI=0

SCK 上升沿

從機采樣 0

SCK 下降沿結束

重復 8 次后,完整發送 1 字節

發送完后,主機將 CS 拉高,表示結束通信

若是讀取數據,主機會在每一位 SCK 上升沿讀 MISO 上的電平

SPI Mode 1(CPOL = 0,CPHA = 1)

空閑時 SCK 為低,采樣在下降沿,數據改變在上升沿

通信準備階段:
主機將 CS 拉低,激活目標從機(W25Q64)

SCK 處于空閑低電平(CPOL = 0)

數據準備完畢,等待時鐘同步

第一位傳輸(發送 bit7 = 1)

主機將 SCK 拉高(上升沿)

主機將 MOSI 設置為 1

主機將 SCK 拉低(下降沿)

從機在 下降沿采樣 MOSI 上的值(記錄 bit7 = 1)

第二位傳輸(bit6 = 0)

主機將 SCK 拉高

主機將 MOSI 設置為 0

主機將 SCK 拉低

從機在下降沿采樣 0

重復 8 次后,完整發送 1 字節

主機將 CS 拉高,表示通信結束

若是讀取數據:
主機會在 每一位的 SCK 下降沿 讀取 MISO 上的電平

?SPI Mode 2(CPOL = 1,CPHA = 0)

空閑時 SCK 為高,采樣在下降沿,數據改變在上升沿

通信準備階段:
主機將 CS 拉低,激活目標從機

SCK 初始為高電平(CPOL = 1)

數據準備完畢,等待同步

第一位傳輸(bit7 = 1)

主機將 MOSI 設置為 1

主機將 SCK 從高拉低(下降沿)

從機在 下降沿采樣 MOSI = 1

主機將 SCK 拉高(恢復空閑)

第二位傳輸(bit6 = 0)

主機將 MOSI = 0

主機將 SCK 拉低

從機采樣 0

主機將 SCK 拉高

重復 8 次后,完整發送 1 字節

主機將 CS 拉高,結束通信

若是讀取數據:
主機會在 每一位 SCK 下降沿 讀取 MISO 電平

SPI Mode 3(CPOL = 1,CPHA = 1)

空閑時 SCK 為高,采樣在上升沿**,數據改變在下降沿

通信準備階段:
主機將 CS 拉低,激活從機

SCK 初始為高電平(CPOL = 1)

數據準備完畢,等待同步

第一位傳輸(bit7 = 1)

主機將 SCK 拉低

主機將 MOSI 設置為 1

主機將 SCK 從低拉高(上升沿)

從機在 上升沿采樣 MOSI = 1

第二位傳輸(bit6 = 0)

主機將 SCK 拉低

主機將 MOSI 設置為 0

主機將 SCK 拉高

從機采樣 0

重復 8 次后,完整發送 1 字節

主機將 CS 拉高,結束通信

若是讀取數據:
主機會在 每一位 SCK 上升沿 讀取 MISO 電平

W25Q64 是什么?

W25Q64 是一款 64M-bit(8MB)SPI NOR Flash 存儲芯片,常用于存儲配置文件、圖片、數據日志等。它支持:

SPI Mode 0/3 接口

支持標準讀、頁寫、扇區擦除等

支持寫保護、掉電保護

多種容量(如 Q32、Q64、Q128)

W25Q64 內部結構概覽

參數數值
總容量64Mbit = 8MB
頁大小(Page)256 字節
扇區大小(Sector)4KB(16 頁)
塊大小(Block)64KB
地址范圍0x000000 ~ 0x7FFFFF

寫數據前必須先擦除所在頁或扇區!否則寫入無效。寫數據前必須先擦除所在頁或扇區!否則寫入無效。

W25Q64 使用的 SPI 協議模式

默認使用 SPI Mode 0(CPOL = 0,CPHA = 0)

通信速率支持高達 80MHz(我們軟件模擬約幾十 KHz)

通信格式:主機發送 命令 + 地址 + 數據,從機響應結果或接收寫入

4.舉一個SPI讀寫W25Q64(軟件)例子

從 STM32F103 使用 GPIO 模擬 SPI 信號,實現:

初始化 GPIO

與 W25Q64 通信(讀ID、擦除扇區、寫數據、讀數據)

OLED 顯示驗證數據讀寫是否成功

通信的整體邏輯步驟(功能流程)

初始化 SPI 引腳(MySPI_Init)

啟動 SPI 通信(CS 拉低,MySPI_Start)

發送命令(如讀 ID,擦除、寫數據)

可選:寫入地址或數據內容

讀取或寫入數據

結束通信(CS 拉高,MySPI_Stop)

在 OLED 上顯示通信結果

第一階段:軟件 SPI 的本質與引腳配置

SPI 是什么?
SPI 是一種同步串行通信協議,使用 4 根信號線:

CS:片選(低電平有效)

SCK:時鐘,由主機控制

MOSI:主出從入,主機發給從機

MISO:主入從出,從機回應主機

在 Mode 0 模式下(CPOL=0,CPHA=0):

SCK 空閑為低電平

在 SCK 上升沿采樣輸入數據(MISO)

MOSI 數據必須在 SCK 上升沿前準備好

軟件模擬 SPI 的基本操作函數
模擬 SPI 片選信號 CS(/SS)
void MySPI_W_SS(uint8_t BitValue)
{GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)BitValue);
}

使用 PA4 模擬 SPI 的 CS(Chip Select)信號線

BitValue = 0 表示選中從機(W25Q64)

BitValue = 1 表示釋放從機

W25Q64 是在 CS 低電平有效 時才響應 SPI 命令。這個函數用于 SPI 通信的開始與結束。

模擬時鐘線 SCK
void MySPI_W_SCK(uint8_t BitValue)
{GPIO_WriteBit(GPIOA, GPIO_Pin_5, (BitAction)BitValue);
}

使用 PA5 模擬 SPI 的時鐘線 SCK(Serial Clock)

SPI 模式 0 規定:空閑時為低電平,在 上升沿采樣

?模擬 MOSI 輸出
uint8_t MySPI_R_MISO(void)
{return GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6);
}

使用 PA7 作為 MOSI(主出從入)

STM32 控制這根線向 W25Q64 發送數據位(高位先發)

?引腳初始化:MySPI_Init引腳初始化:?

模擬讀取 MISO(主入從出)
void MySPI_W_MOSI(uint8_t BitValue)
{GPIO_WriteBit(GPIOA, GPIO_Pin_7, (BitAction)BitValue);
}

使用 PA6 作為 MISO,從 W25Q64 讀取回來的每一位數據就在這里被讀取。

讀取的是從機在時鐘上升沿送出的位電平。

// 1. 打開 GPIOA 的時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);// 2. 配置 MOSI(PA7)、SCK(PA5)、CS(PA4)為推挽輸出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);// 3. 配置 MISO(PA6)為上拉輸入
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOA, &GPIO_InitStructure);// 4. 初始狀態:SS = 1 表示未選中,SCK = 0 表示時鐘空閑
MySPI_W_SS(1);
MySPI_W_SCK(0);

推挽能拉高/拉低,速度快,適合 SPI?

SPI 通信控制函數
void MySPI_Start(void)
{MySPI_W_SS(0);   // 選中從機(CS 拉低)
}
void MySPI_Stop(void)
{MySPI_W_SS(1);   // 釋放從機(CS 拉高)
}

第二階段:模擬傳輸一個字節的過程(MySPI_SwapByte)

實現原理
SPI 每傳輸 1 個字節(8 位):

每一位數據在 MOSI 上輸出(主機發)

在 SCK 上升沿讓從機采樣(主出)

同時主機也在上升沿讀取 MISO(主入)

uint8_t MySPI_SwapByte(uint8_t ByteSend)
{uint8_t i, ByteReceive = 0x00;for (i = 0; i < 8; i++){// 第 i 位:先將 MOSI 輸出(最高位先)MySPI_W_MOSI(ByteSend & (0x80 >> i));  // 將第 i 位送到 MOSIMySPI_W_SCK(1); // SCK 拉高(上升沿)// 在上升沿采樣 MISO 線,主機讀取從機的回應位if (MySPI_R_MISO() == 1) ByteReceive |= (0x80 >> i);MySPI_W_SCK(0); // SCK 拉低,準備下一位}return ByteReceive;
}

初始化變量:i 為循環索引;ByteReceive 用來存儲收到的數據。?

例如 ByteSend = 0b10100001

第一次發送 bit7:ByteSend & 0x80 = 0x80

輸出對應位電平到 MOSI

SPI Mode 0:從機在 SCK 上升沿采樣數據

主機此時也應從 MISO 線上采樣數據

若當前位為高電平,則置 ByteReceive 的對應位為 1

第三階段:JEDEC ID 的讀取過程(讀取芯片型號)

第三階段:JEDEC ID 的讀取過程(讀取芯片型號)

void W25Q64_ReadID(uint8_t *MID, uint16_t *DID)
{MySPI_Start();                  // CS = 0,激活 FlashMySPI_SwapByte(0x9F);           // 發送 JEDEC ID 指令*MID = MySPI_SwapByte(0x00);    // 接收廠商 ID(通常為 0xEF)*DID = MySPI_SwapByte(0x00);    // 高位 Device ID(如 0x40)*DID <<= 8;*DID |= MySPI_SwapByte(0x00);   // 低位 Device ID(如 0x17)MySPI_Stop();                   // CS = 1,結束通信}

?每個字節都通過 MySPI_SwapByte() 傳輸,從機 MISO 返回對應 ID 信息。

第四階段:擦除操作(扇區擦除)

寫使能
void W25Q64_WriteEnable(void)
{MySPI_Start();MySPI_SwapByte(W25Q64_WRITE_ENABLE); // 0x06MySPI_Stop();
}

?所有寫操作前必須執行該命令。否則寫入失敗。

等待芯片空閑
void W25Q64_WaitBusy(void)
{uint32_t Timeout;MySPI_Start();MySPI_SwapByte(W25Q64_READ_STATUS_REGISTER_1); // 0x05,讀取狀態寄存器Timeout = 100000;while ((MySPI_SwapByte(W25Q64_DUMMY_BYTE) & 0x01) == 0x01) // bit0=WIP=1表示忙{Timeout --;if (Timeout == 0) break;}MySPI_Stop();
}

為什么要擦除?
W25Q64 的 NOR Flash 寫入特性:

不能直接改寫為 0 → 1

必須先將 1 全部清零(擦除為 0xFF),才能寫入

void W25Q64_SectorErase(uint32_t Address)
{W25Q64_WriteEnable();          // 必須先寫使能(WEL=1)MySPI_Start();                 // CS = 0MySPI_SwapByte(0x20);          // 發送擦除指令:Sector EraseMySPI_SwapByte(addr >> 16);    // 地址高8位MySPI_SwapByte(addr >> 8);     // 地址中8位MySPI_SwapByte(addr);          // 地址低8位MySPI_Stop();                  // CS = 1W25Q64_WaitBusy();             // 等待擦除完成(最多100ms)}

地址不需要對齊 0x000;芯片內部按地址所在扇區處理(每 4KB 為一個)

第五階段:寫入數據(頁寫)

寫前必須:
寫使能(0x06)

地址不要跨頁(每頁 256 字節)

void W25Q64_PageProgram(uint32_t Address, uint8_t *DataArray, uint16_t Count)
{W25Q64_WriteEnable();               // 打開寫使能(WEL=1)MySPI_Start();                      // 開始通信MySPI_SwapByte(0x02);               // Page Program 指令MySPI_SwapByte(addr >> 16);         // 地址高8位MySPI_SwapByte(addr >> 8);          // 地址中8位MySPI_SwapByte(addr);               // 地址低8位for (i = 0; i < Count; i++){MySPI_SwapByte(DataArray[i]);   // 發送要寫入的數據(MOSI)}MySPI_Stop();                       // 結束通信W25Q64_WaitBusy();                  // 等待寫入完成}

第六階段:讀取數據(Read Data)

void W25Q64_ReadData(uint32_t Address, uint8_t *DataArray, uint32_t Count)
{MySPI_Start();MySPI_SwapByte(0x03);                // Read Data 指令MySPI_SwapByte(addr >> 16);          // 地址高8位MySPI_SwapByte(addr >> 8);           // 中8位MySPI_SwapByte(addr);                // 低8位for (i = 0; i < Count; i++){DataArray[i] = MySPI_SwapByte(0x00); // 每讀取一個字節,發一個 dummy byte}MySPI_Stop();}

?主機在 每個 SCK 上升沿讀取 MISO,從機按地址返回數據。

?5.指令函數

#ifndef __W25Q64_INS_H
#define __W25Q64_INS_H#define W25Q64_WRITE_ENABLE							0x06
#define W25Q64_WRITE_DISABLE						0x04
#define W25Q64_READ_STATUS_REGISTER_1				0x05
#define W25Q64_READ_STATUS_REGISTER_2				0x35
#define W25Q64_WRITE_STATUS_REGISTER				0x01
#define W25Q64_PAGE_PROGRAM							0x02
#define W25Q64_QUAD_PAGE_PROGRAM					0x32
#define W25Q64_BLOCK_ERASE_64KB						0xD8
#define W25Q64_BLOCK_ERASE_32KB						0x52
#define W25Q64_SECTOR_ERASE_4KB						0x20
#define W25Q64_CHIP_ERASE							0xC7
#define W25Q64_ERASE_SUSPEND						0x75
#define W25Q64_ERASE_RESUME							0x7A
#define W25Q64_POWER_DOWN							0xB9
#define W25Q64_HIGH_PERFORMANCE_MODE				0xA3
#define W25Q64_CONTINUOUS_READ_MODE_RESET			0xFF
#define W25Q64_RELEASE_POWER_DOWN_HPM_DEVICE_ID		0xAB
#define W25Q64_MANUFACTURER_DEVICE_ID				0x90
#define W25Q64_READ_UNIQUE_ID						0x4B
#define W25Q64_JEDEC_ID								0x9F
#define W25Q64_READ_DATA							0x03
#define W25Q64_FAST_READ							0x0B
#define W25Q64_FAST_READ_DUAL_OUTPUT				0x3B
#define W25Q64_FAST_READ_DUAL_IO					0xBB
#define W25Q64_FAST_READ_QUAD_OUTPUT				0x6B
#define W25Q64_FAST_READ_QUAD_IO					0xEB
#define W25Q64_OCTAL_WORD_READ_QUAD_IO				0xE3#define W25Q64_DUMMY_BYTE							0xFF#endif
類別宏定義指令碼用途說明
?寫控制W25Q64_WRITE_ENABLE0x06使能寫操作(寫/擦前必須執行)
W25Q64_WRITE_DISABLE0x04禁止寫操作,防止誤寫
?狀態寄存器W25Q64_READ_STATUS_REGISTER_10x05讀取狀態寄存器1(BUSY/寫使能位)
W25Q64_READ_STATUS_REGISTER_20x35讀取狀態寄存器2(包含QE位)
W25Q64_WRITE_STATUS_REGISTER0x01同時寫SR1 和 SR2(共2字節)
寫入操作W25Q64_PAGE_PROGRAM0x02頁編程(最多256字節)
W25Q64_QUAD_PAGE_PROGRAM0x32四線頁編程(用于Quad SPI)
?擦除操作W25Q64_SECTOR_ERASE_4KB0x20擦除一個 4KB 扇區
W25Q64_BLOCK_ERASE_32KB0x52擦除一個 32KB 塊
W25Q64_BLOCK_ERASE_64KB0xD8擦除一個 64KB 塊
W25Q64_CHIP_ERASE0xC7整片擦除(耗時較久)
W25Q64_ERASE_SUSPEND0x75暫停擦除操作(用于多任務)
W25Q64_ERASE_RESUME0x7A恢復擦除操作
電源管理W25Q64_POWER_DOWN0xB9進入低功耗待機模式
W25Q64_RELEASE_POWER_DOWN_HPM_DEVICE_ID0xAB喚醒 + 讀取設備ID
模式控制W25Q64_HIGH_PERFORMANCE_MODE0xA3啟用高性能模式(某些版本支持)
W25Q64_CONTINUOUS_READ_MODE_RESET0xFF重置連續讀模式
識別IDW25Q64_MANUFACTURER_DEVICE_ID0x90讀取制造商 + 設備ID(需發送地址)
W25Q64_READ_UNIQUE_ID0x4B讀取唯一芯片ID(64-bit)
W25Q64_JEDEC_ID0x9FJEDEC 標準ID(1字節廠商 + 2字節設備)
讀取數據W25Q64_READ_DATA0x03標準讀取(低速,最兼容)
W25Q64_FAST_READ0x0B快速讀取(需發送 Dummy Byte)
W25Q64_FAST_READ_DUAL_OUTPUT0x3B雙線輸出快速讀
W25Q64_FAST_READ_DUAL_IO0xBB雙線輸入輸出快速讀
W25Q64_FAST_READ_QUAD_OUTPUT0x6B四線輸出快速讀
W25Q64_FAST_READ_QUAD_IO0xEB四線輸入輸出快速讀
W25Q64_OCTAL_WORD_READ_QUAD_IO0xE3八線 32-bit 快速讀取(部分芯片支持)
占位字節W25Q64_DUMMY_BYTE0xFF常用于讀取時“填充”MOSI

6.main函數

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "W25Q64.h"uint8_t MID;
uint16_t DID;uint8_t ArrayWrite[] = {0x01, 0x02, 0x03, 0x04};
uint8_t ArrayRead[4];int main(void)
{OLED_Init();W25Q64_Init();OLED_ShowString(1, 1, "MID:   DID:");OLED_ShowString(2, 1, "W:");OLED_ShowString(3, 1, "R:");W25Q64_ReadID(&MID, &DID);OLED_ShowHexNum(1, 5, MID, 2);OLED_ShowHexNum(1, 12, DID, 4);W25Q64_SectorErase(0x000000);W25Q64_PageProgram(0x000000, ArrayWrite, 4);W25Q64_ReadData(0x000000, ArrayRead, 4);OLED_ShowHexNum(2, 3, ArrayWrite[0], 2);OLED_ShowHexNum(2, 6, ArrayWrite[1], 2);OLED_ShowHexNum(2, 9, ArrayWrite[2], 2);OLED_ShowHexNum(2, 12, ArrayWrite[3], 2);OLED_ShowHexNum(3, 3, ArrayRead[0], 2);OLED_ShowHexNum(3, 6, ArrayRead[1], 2);OLED_ShowHexNum(3, 9, ArrayRead[2], 2);OLED_ShowHexNum(3, 12, ArrayRead[3], 2);while (1){}
}

擦除第一個扇區(地址 0x000000 起始的 4KB)

NOR Flash 寫入前必須擦除,否則無法從 0 改寫為 1!(擦除后,所有數據位變為1)

7.SPI通信與I2C區別

對比項SPI(Serial Peripheral Interface)I2C(Inter-Integrated Circuit)
通信方式全雙工,主從同步通信半雙工,主從同步通信
信號線數量通常需要 4 根線:MISO, MOSI, SCLK, CS(每個從機單獨 CS)只需 2 根線:SCL(時鐘), SDA(數據)
通信速率較高,可達幾十 Mbps較低,一般為 100kHz、400kHz,最多幾 Mbps
引腳數量多(每個從機需獨立 CS 引腳)少(多個從機共用總線)
總線架構一主多從,但每個從機需要獨立片選一主多從,多個從機可共享 2 根線
地址機制無地址,主機用 CS 選中具體從機有 7 位或 10 位設備地址
傳輸控制主機控制時鐘(SCLK)與片選主機控制時鐘(SCL),通過地址訪問從機
數據方向MOSI、MISO 分別用于寫入和讀取(全雙工SDA 單線收發數據(半雙工
硬件成本較高(線多,占用 GPIO 多)較低(線少,占用 GPIO 少)
軟件協議復雜度簡單,無握手或仲裁較復雜,有起始/停止位、ACK/NACK、仲裁機制等
常見應用場景Flash、SD 卡、屏幕、W25Q64 等高速外設EEPROM、RTC、傳感器、OLED、MPU6050 等低速外設

具體外設舉例?

外設使用通信協議原因簡述
W25Q64SPI高速讀寫需求,SPI 支持頁寫、塊擦除等
MPU6050I2C內置 I2C 接口,低速傳感器,節省引腳
OLED (SSD1306)I2C 或 SPI小數據量,I2C 節省引腳,SPI 提高速度
SD 卡SPI大容量文件操作,SPI 高速全雙工性能優越

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/92343.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/92343.shtml
英文地址,請注明出處:http://en.pswp.cn/web/92343.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

子詞分詞器(Byte Pair Encoding + WordPiece)

參考文章&#xff1a;子詞分詞器BPE和WordPiece理解_wordpeice-CSDN博客 子詞分詞器BPE和WordPiece理解_wordpeice-CSDN博客 WordPiece 和 BPE 的區別-CSDN博客 點互信息&#xff08;PMI&#xff09;和正點互信息&#xff08;PPMI&#xff09;-CSDN博客 https://zhuanlan.z…

阿里招AI產品運營

AI產品運營&#xff08;崗位信息已經過jobleap.cn授權&#xff0c;可在csdn發布&#xff09;靈犀互娛 廣州收錄時間&#xff1a; 2025年08月05日職位描述負責AI技術在游戲行業的應用與落地&#xff0c;專注于海外市場的運營中臺建設&#xff1b; 將結合AI技術與游戲行業特點&a…

Git 分支遷移完整指南(結合分支圖分析)

基于分支圖的當前狀態分析 分支圖關鍵信息解讀?分支結構?&#xff1a; #mermaid-svg-gc9SPnwlbrM2FzHf {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-gc9SPnwlbrM2FzHf .error-icon{fill:#552222;}#mermaid-svg-…

小程序省市級聯組件使用

背景。uni-data-picker組件用起來不方便。調整后級聯效果欠佳&#xff0c;會關閉彈窗需要重新選擇。解決方案。讓cursor使用uniapp 原生組件生成懶加載省市級聯 <template><view class"picker-cascader"><view class"cascader-label">&l…

Java技術棧/面試題合集(8)-Redis篇

場景 Java入門、進階、強化、擴展、知識體系完善等知識點學習、性能優化、源碼分析專欄分享: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/140870227 通過對面試題進行系統的復習可以對Java體系的知識點進行查漏補缺。 注: 博客: 霸道流氓氣質-CSDN博…

川翔云電腦:引領開啟算力無邊界時代

一、何為云電腦&#xff1f;重新定義“主機”概念 云電腦將傳統本地計算機的核心硬件資源&#xff08;CPU、GPU、內存、硬盤等&#xff09;集中部署于遠程高性能數據中心&#xff0c;通過網絡技術將虛擬桌面實時傳輸到您的任意訪問設備上。 ??如同將高配主機裝入云端&#…

tc 介紹

目錄 1.背景 2. tc介紹 3. tc 丟包 1.背景 需要使用tc 構造丟包場景&#xff0c;注意tc 丟包不能確定丟棄的是否是payload 數據包&#xff0c;有可能丟棄 ack 包。 2. tc介紹 1. 無法正常使用 [rootpool-100-1-1-18 /]# [rootpool-100-1-1-18 /]# tc qdisc add dev swif…

LabVIEW注冊表操作

?本文圍繞LabVIEW中操作Windows 注冊表的 4 個 VI 展開&#xff0c;介紹其功能、使用場景等并對比&#xff0c;助力工程師高效運用注冊表交互功能。各 VI 功能說明&#xff08;一&#xff09;Write the Key功能&#xff1a;創建新注冊表鍵&#xff0c;設置其值&#xff0c;隨后…

阿里云部署若依后,瀏覽器能正常訪問,但是apifox和小程序訪問后報錯鏈接被重置

項目場景&#xff1a;阿里云部署若依后瀏覽器能正常通過https訪問,但是在apifox和小程序調用接口的時候生報錯E問題描述apifox報錯&#xff1a;curl報錯&#xff1a;通過curl可以清楚的看到通過域名是能準確的訪問到IP地址的&#xff0c;說明這個DNS是沒有問題的&#xff0c;但…

升級 Elasticsearch 到新的 AWS Java SDK

作者&#xff1a;來自 Elastic David Turner, Dianna Hohensee Elasticsearch 使用官方的 AWS Java SDK 集成了某些 Amazon Web Services (AWS) 功能。這些集成最早在近 10 年前發布的 Elasticsearch 2.0 版本中引入。 最近&#xff0c;AWS 宣布 Elasticsearch 過去十年使用的…

從0到1學習微服務項目黑馬頭條day01-《APP端登錄功能實現》

個人主頁&#xff1a;VON文章所屬專欄&#xff1a;黑馬頭條個人唯一微信&#xff1a;微信 有一起學習微服務的小伙伴可以加作者微信&#xff1a;單擊即可添加 目錄 一、前言 二、項目概述 1、技術棧 2、項目引入 三、改造項目 1、創建heima-leadnews-user 2、創建實體…

Renesas Electronics RZ/V2N 評估套件

簡介Renesas Electronics RZ/V2N評估套件采用RZ/V2N中檔嵌入式AI微處理器 (MPU) 為嵌入式人工智能 (AI) 應用提供全面的開發平臺。該評估套件包括兩塊板&#xff1a;主板 (RTK0EF0186C02000BJ)&#xff0c;緊湊的153mm x 100mm外形尺寸和RTK0EF0168B00000BJ擴展板。其核心是RZ/…

使用PHP與Apache實現服務器端文件管理

引言 作為前端開發者&#xff0c;你可能經常需要與服務器文件系統交互。本文將詳細介紹如何通過PHP配合Apache實現服務器端文件管理功能。即使你沒有任何PHP經驗&#xff0c;也能按照本教程實現完整解決方案&#xff01; 系統準備 PHP下載與安裝 訪問PHP官網下載頁面 選擇與…

在Word和WPS文字中如何輸入漢字的偏旁部首

如何在Word和WPS文字中輸入偏旁部首&#xff1f;許多輸入法會把常見的偏旁部首直接放到詞庫&#xff0c;對于詞庫中沒有的可以試試這個方法&#xff1a;先輸入一個有這個偏旁部首的字&#xff0c;盡量簡單一點的&#xff0c;然后選中這個字插入-符號-其他符號。滾動到這個偏旁部…

day44 力扣1143.最長公共子序列 力扣1035.不相交的線 力扣53. 最大子序和 力扣392.判斷子序列

最長公共子序列 給定兩個字符串 text1 和 text2&#xff0c;返回這兩個字符串的最長 公共子序列 的長度。如果不存在 公共子序列 &#xff0c;返回 0 。 一個字符串的 子序列 是指這樣一個新的字符串&#xff1a;它是由原字符串在不改變字符的相對順序的情況下刪除某些字符&…

應用7:用小白量化智能體金融模塊做一個股票選股工具

應用7&#xff1a;用小白量化智能體金融模塊做一個股票選股工具 【小白量化智能體】包含有豐富的金融模塊。可以讓智能體寫各種金融量化工具。 我用讓小白量化智能體寫一個股票選股工具。 我們給【小白量化智能體】一個程序生成話術。 幫我寫一個 選股 的應用程序&#xff0c;要…

Qt Frameless Widget跨平臺無邊框窗口

Qt開發的窗口程序&#xff0c;它的標題欄樣式是無法修改的&#xff0c;這個是系統來控制&#xff0c;程序可以調整標題&#xff0c;圖標等&#xff0c;但是各個系統可能表現不一致&#xff0c;比如說標題&#xff0c;window10下在標題欄最左邊&#xff0c;而UOS則在中間&#x…

使用 IntelliJ IDEA + Spring JdbcTemplate 操作 MySQL 指南

使用 IntelliJ IDEA Spring JdbcTemplate 操作 MySQL 完全指南 一、開發環境搭建&#xff08;基于 IDEA&#xff09; 1. 創建 Spring Boot 項目 打開 IDEA → New Project → Spring Initializr選擇&#xff1a; Project SDK: Java 17依賴項&#xff1a;Spring Web, Spring…

從憤怒的小鳥來看Unity武器拖尾的特效優化

目錄 前言 素材下載 介紹 官方文檔 不添加拖尾的效果 添加拖尾 代碼控制拖尾生成 拖尾排序問題 效果 修改拖尾高度和存活時間 效果 待機時無拖尾 效果 參考 前言 在游戲開發過程中&#xff0c;我們經常需要為武器添加拖尾特效&#xff0c;效果如下所示 Unity 自…

Web開發模式 前端渲染 后端渲染 身份認證

Web 開發模式 # 目前主流的Web 開發模式 兩種 一、基于 服務器端渲染 的傳統 Web開發模式 二、基于 前后端分離 的新型 Web開發模式# 服務端渲染的優缺點# 優點&#xff1a;1. 前端耗時少因為服務端負責動態生成 HTML內容&#xff0c;瀏覽器&#xff08;包括手…