news 2026/5/3 8:55:21

GD32F103 SPI实战:手把手教你配置全双工通信(附主机从机完整代码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
GD32F103 SPI实战:手把手教你配置全双工通信(附主机从机完整代码)

GD32F103 SPI全双工通信实战:从硬件配置到调试技巧

1. 硬件连接与基础概念

SPI通信的硬件连接看似简单,但实际项目中常因接线问题导致通信失败。以GD32F103为例,主机使用SPI0(PA4-PA7),从机使用SPI1(PB12-PB15),正确的物理连接是:

  • 主机MOSI(PA7)→从机MOSI(PB15)
  • 主机MISO(PA6)←从机MISO(PB14)
  • 主机SCK(PA5)→从机SCK(PB13)
  • 主机NSS(PA4)→从机NSS(PB12)

注意:GD32的硬件NSS信号是低电平有效,若使用软件控制NSS,需手动拉低对应GPIO

SPI时钟配置中容易混淆的两个参数:

参数可选值实际影响
CKPL0/1时钟空闲时为低(0)/高(1)电平
CKPH0/1数据在第一个(0)/第二个(1)边沿采样

常见组合方案:

// 模式0:CKPL=0, CKPH=0 (最常用) spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE; // 模式3:CKPL=1, CKPH=1 spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;

2. 工程配置详解

2.1 主机初始化关键代码

void SPI_MasterInit(void) { // GPIO时钟使能 rcu_periph_clock_enable(RCU_GPIOA); // 配置SPI引脚:NSS/PA4, SCK/PA5, MOSI/PA7为推挽输出 gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_7); // MISO/PA6配置为浮空输入 gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_6); // SPI外设时钟使能 rcu_periph_clock_enable(RCU_SPI0); spi_parameter_struct spi_init_struct = {0}; spi_struct_para_init(&spi_init_struct); // 关键参数配置 spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX; spi_init_struct.device_mode = SPI_MASTER; spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT; spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE; spi_init_struct.nss = SPI_NSS_HARD; // 硬件NSS spi_init_struct.prescale = SPI_PSC_8; // 108MHz/8=13.5MHz spi_init_struct.endian = SPI_ENDIAN_MSB; spi_init(SPI0, &spi_init_struct); spi_nss_output_enable(SPI0); // 使能NSS输出 spi_enable(SPI0); }

2.2 从机配置差异点

从机配置有三处关键不同:

  1. device_mode设为SPI_SLAVE
  2. NSS引脚配置为输入模式
  3. 不需要设置分频系数(时钟由主机提供)
// 从机GPIO配置 gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_14); // MISO gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_15); // NSS,SCK,MOSI // 从机模式设置 spi_init_struct.device_mode = SPI_SLAVE;

3. 全双工通信实现

3.1 数据收发流程

主机和从机同时收发数据的典型流程:

  1. 初始化数据缓冲区

    uint8_t master_tx_buf[16] = {0x80,0x81,...,0x8F}; uint8_t slave_tx_buf[16] = {0x40,0x41,...,0x4F};
  2. 启动传输过程

    • 主机自动产生SCK时钟
    • 从机检测到NSS低电平后准备接收时钟
  3. 双工数据交换

    for(uint8_t i=0; i<16; i++){ // 从机发送准备 while(!spi_i2s_flag_get(SPI1, SPI_FLAG_TBE)); spi_i2s_data_transmit(SPI1, slave_tx_buf[i]); // 主机发送数据 while(!spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)); spi_i2s_data_transmit(SPI0, master_tx_buf[i]); // 从机接收 while(!spi_i2s_flag_get(SPI1, SPI_FLAG_RBNE)); slave_rx_buf[i] = spi_i2s_data_receive(SPI1); // 主机接收 while(!spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE)); master_rx_buf[i] = spi_i2s_data_receive(SPI0); }

3.2 调试输出建议

添加串口打印可直观验证通信结果:

printf("Master Received: "); for(int i=0; i<16; i++) printf("%02X ", master_rx_buf[i]); printf("\nSlave Received: "); for(int i=0; i<16; i++) printf("%02X ", slave_rx_buf[i]);

4. 常见问题排查指南

4.1 无数据通信

检查清单:

  • [ ] 确认SPI外设时钟已使能(RCU_SPIx)
  • [ ] 验证GPIO模式配置正确(MOSI、SCK为AF推挽输出)
  • [ ] 检查硬件连接是否接触良好
  • [ ] 测量SCK信号是否正常产生(逻辑分析仪最佳)

4.2 数据错位或丢失

可能原因及解决方案:

现象可能原因解决方法
高位错位端序设置错误检查endian参数
偶发丢数据未检测状态标志增加TBE/RBNE检查
全部为0xFF从机未响应检查从机供电及NSS信号

4.3 性能优化技巧

  1. DMA传输:对于大数据量传输,配置DMA可大幅降低CPU占用

    dma_parameter_struct dma_init_struct; dma_deinit(DMA0, DMA_CH0); dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL; dma_init_struct.memory_addr = (uint32_t)tx_buffer; dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT; dma_init_struct.number = BUFFER_SIZE; dma_init_struct.periph_addr = (uint32_t)&SPI_DATA(SPI0); dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; dma_init_struct.periph_width = DMA_PERIPH_WIDTH_8BIT; dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; dma_init(DMA0, DMA_CH0, &dma_init_struct);
  2. 中断处理:利用SPI中断实现异步通信

    spi_i2s_interrupt_enable(SPI0, SPI_I2S_INT_TBE); nvic_irq_enable(SPI0_IRQn, 0, 0);

实际项目中遇到过一个典型问题:当主机发送速率过快时,从机处理不及时会导致数据覆盖。后来通过增加硬件流控(使用GPIO作为就绪信号)解决了这个问题。这种实战经验在手册中很少提及,却是保证通信可靠的关键。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/3 8:53:07

Femtocell技术与TR-069协议管理详解

1. Femtocell技术背景与TR-069协议概述Femtocell&#xff08;家庭基站&#xff09;是一种低功率的无线接入点设备&#xff0c;通常部署在室内环境&#xff0c;通过用户的宽带连接回传至运营商核心网络。这种技术最早出现在3G时代&#xff0c;用于解决室内覆盖问题&#xff0c;如…

作者头像 李华
网站建设 2026/5/3 8:51:53

3分钟极速上手:Degrees of Lewdity中文汉化终极配置指南

3分钟极速上手&#xff1a;Degrees of Lewdity中文汉化终极配置指南 【免费下载链接】Degrees-of-Lewdity-Chinese-Localization Degrees of Lewdity 游戏的授权中文社区本地化版本 项目地址: https://gitcode.com/gh_mirrors/de/Degrees-of-Lewdity-Chinese-Localization …

作者头像 李华
网站建设 2026/5/3 8:49:09

图数据库与记忆体融合:轻量级知识管理工程实践

1. 项目概述&#xff1a;当图数据库遇上记忆体&#xff0c;一个面向复杂知识管理的工程实践最近在折腾一个需要处理大量关联性数据的项目&#xff0c;传统的键值存储或者文档数据库在处理“关系”时总感觉力不从心&#xff0c;而直接上全功能的图数据库&#xff0c;又觉得有点“…

作者头像 李华
网站建设 2026/5/3 8:36:36

开源硬件社区补丁应用指南:从OpenClaw机械臂实践到固件定制

1. 项目概述与核心价值最近在折腾一个叫“OpenClaw Mechanicus”的桌面机械臂项目&#xff0c;发现它的开源固件和社区补丁生态非常有意思。这个项目标题“JoeSzeles/openclaw-mechanicus-patches”直译过来&#xff0c;就是开发者Joe Szeles为OpenClaw Mechanicus项目维护的一…

作者头像 李华
网站建设 2026/5/3 8:33:59

容器安全调用宿主机命令:acp-bridge架构原理与实战部署指南

1. 项目概述与核心价值最近在折腾一些跨平台的应用部署和自动化任务时&#xff0c;我遇到了一个挺有意思的需求&#xff1a;如何让一个运行在容器环境里的应用&#xff0c;能够安全、便捷地调用宿主机上的命令行工具或服务&#xff1f;比如&#xff0c;我在一个 Docker 容器里跑…

作者头像 李华
网站建设 2026/5/3 8:33:57

如何快速批量下载微博高清图片:终极微博图片爬虫使用指南

如何快速批量下载微博高清图片&#xff1a;终极微博图片爬虫使用指南 【免费下载链接】weibo-image-spider 微博图片爬虫&#xff0c;极速下载、高清原图、多种命令、简单实用。 项目地址: https://gitcode.com/gh_mirrors/we/weibo-image-spider 还在为一张张手动保存微…

作者头像 李华