目录
简介
- SPI模块可以通过SPI协议与外部设备进行通信。
- 串行外设接口(Serial Peripheral Interface,缩写为 SPI)提供了基于 SPI 协议的数据发送和接收功能,可以工作于主机或从机模式SPI 接口支持具有硬件 CRC 计算和校验的全双工和单工模式。SPI0 还支持 SPI 四线主机模式。
- SPI模块可以在四种模式下运行,包括主机发送模式,主机接收模式,从机发送模式和从机接收模式
引脚配置
使用了SPI0和SPI1,配置如下
接口 | 信号 | MCU 引脚 | 端口 / 管脚 | 复用模式 (GPIO 模式) | 方向* | 备注 |
---|---|---|---|---|---|---|
SPI0 (全 remap) | NSS / CSQ | PA15 | GPIOA 15 | GPIO_MODE_AF_PP (硬件 NSS) | 输出 | 可改为软件片选 |
SCK | PB3 | GPIOB 3 | GPIO_MODE_AF_PP | 输出 | 时钟:CPOL 0 / CPHA 1 | |
MISO | PB4 | GPIOB 4 | GPIO_MODE_IN_FLOATING | 输入 | 16 bit 数据输入 | |
MOSI | PB5 | GPIOB 5 | GPIO_MODE_AF_PP | 输出 | 16 bit 数据输出 | |
SPI1 (默认映射) | NSS / CSQ | PB12 | GPIOB 12 | GPIO_MODE_AF_PP (硬件 NSS) | 输出 | 可改为软件片选 |
SCK | PB13 | GPIOB 13 | GPIO_MODE_AF_PP | 输出 | 时钟:CPOL 0 / CPHA 1 | |
MISO | PB14 | GPIOB 14 | GPIO_MODE_IN_FLOATING | 输入 | 16 bit 数据输入 | |
MOSI | PB15 | GPIOB 15 | GPIO_MODE_AF_PP | 输出 | 16 bit 数据输出 |
代码如下:
#include "gd32f30x.h"
#define SPI1_INST SPI1
#define SPI1_SCK_PORT GPIOB
#define SPI1_SCK_PIN GPIO_PIN_13
#define SPI1_SCK_FUNC GPIO_MODE_AF_PP
#define SPI1_MOSI_PORT GPIOB
#define SPI1_MOSI_PIN GPIO_PIN_15
#define SPI1_MOSI_FUNC GPIO_MODE_AF_PP
#define SPI1_MISO_PORT GPIOB
#define SPI1_MISO_PIN GPIO_PIN_14
#define SPI1_MISO_FUNC GPIO_MODE_IN_FLOATING
#define SPI1_NSS_PORT GPIOB
#define SPI1_NSS_PIN GPIO_PIN_12
#define SPI1_NSS_FUNC GPIO_MODE_AF_PP
#define SPI0_INST SPI0
#define SPI0_SCK_PORT GPIOB
#define SPI0_SCK_PIN GPIO_PIN_3
#define SPI0_SCK_FUNC GPIO_MODE_AF_PP
#define SPI0_MOSI_PORT GPIOB
#define SPI0_MOSI_PIN GPIO_PIN_5
#define SPI0_MOSI_FUNC GPIO_MODE_AF_PP
#define SPI0_MISO_PORT GPIOB
#define SPI0_MISO_PIN GPIO_PIN_4
#define SPI0_MISO_FUNC GPIO_MODE_IN_FLOATING
#define SPI0_NSS_PORT GPIOA
#define SPI0_NSS_PIN GPIO_PIN_15
#define SPI0_NSS_FUNC GPIO_MODE_AF_PP
void gpio_init(void)
{
rcu_periph_clock_enable(RCU_SPI0);
rcu_periph_clock_enable(RCU_SPI1);
/* 关闭 JTAG,仅保留 SWD(释放 PA15、PB3、PB4) */
gpio_pin_remap_config(GPIO_SWJ_SWDPENABLE_REMAP, ENABLE);
/* -------- SPI0 全 remap:PB3/4/5 + PA15 -------- */
gpio_pin_remap_config(GPIO_SPI0_REMAP, ENABLE);
/* PA15 → NSS, 推挽输出 */
gpio_init(SPI0_NSS_PORT, SPI0_NSS_FUNC, GPIO_OSPEED_50MHZ, SPI0_NSS_PIN);
/* PB3 → SCK, PB5 → MOSI, 推挽输出 */
gpio_init(SPI0_SCK_PORT, SPI1_SCK_FUNC, GPIO_OSPEED_50MHZ, SPI0_SCK_PIN | SPI0_MOSI_PIN);
/* PB4 → MISO, 浮空输入 */
gpio_init(SPI0_MISO_PORT, SPI0_MISO_FUNC, GPIO_OSPEED_50MHZ, SPI0_MISO_PIN);
/* -------- SPI1 默认映射:PB12~15 -------- */
gpio_init(SPI1_SCK_PORT, SPI1_SCK_FUNC, GPIO_OSPEED_50MHZ,
SPI1_SCK_PIN | SPI1_MOSI_PIN | SPI1_NSS_PIN); /* NSS, SCK, MOSI */
gpio_init(SPI1_MISO_PORT, SPI1_MISO_FUNC, GPIO_OSPEED_50MHZ,
SPI1_MISO_PIN); /* MISO */
}
SPI配置
SPI配置如下:
void spi_init(void)
{
/* ---------------- SPI 参数 ---------------- */
spi_parameter_struct spi_init_str;
spi_struct_para_init(&spi_init_str);
/* 公共参数:8bit, 主机, 全双工, CPOL=0 CPHA=0, MSB first */
spi_init_str.device_mode = SPI_MASTER;
spi_init_str.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
spi_init_str.frame_size = SPI_FRAMESIZE_8BIT;
spi_init_str.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
spi_init_str.nss = SPI_NSS_HARD; /* 硬件 NSS */
spi_init_str.endian = SPI_ENDIAN_MSB;
spi_init_str.prescale = SPI_PSC_16;
spi_init(SPI0_INST, &spi_init_str);
spi_nss_output_enable(SPI0_INST);
spi_nssp_mode_enable(SPI0_INST);
spi_enable(SPI0_INST);
spi_init_str.prescale = SPI_PSC_16;
spi_init(SPI1_INST, &spi_init_str);
spi_nss_output_enable(SPI1_INST);
spi_nssp_mode_enable(SPI1_INST);
spi_enable(SPI1_INST);
}
结束
然后调用提供的发送数据函数,即可完成数据发送,比如 spi_i2s_data_transmit(SPI0_INST,0x55AA);
结果如下: