如何实现STM32 NUCLEO-U5A5ZJ-Q与Adafruit BLE SPI Friend模块通信?
实现Adafruit Bluefruit LE SPI Friend与STM32 NUCLEO-U5A5ZJ-Q的SPI通信(基于STM32CubeIDE)
一、硬件接线
- 模块3.3V → NUCLEO 3.3V引脚
- 模块GND → NUCLEO GND引脚
- 模块SCK → NUCLEO SPI1_SCK(PA5)
- 模块MISO → NUCLEO SPI1_MISO(PA6)
- 模块MOSI → NUCLEO SPI1_MOSI(PA7)
- 模块CS → NUCLEO PB0(可自定义GPIO,软件控制)
- 模块RST → NUCLEO PB1(可选,用于复位模块)
二、STM32CubeIDE配置步骤
- 新建项目,选择
NUCLEO-U5A5ZJ-Q开发板生成基础工程 - 配置SPI外设(以SPI1为例):
- 模式:全双工主模式(Full-Duplex Master)
- 硬件NSS:禁用,采用软件控制片选
- 时钟极性(CPOL):0(空闲时低电平)
- 时钟相位(CPHA):0(第一个时钟沿捕获数据)
- 波特率分频器:选
16(对应约1MHz,模块最大支持4MHz) - 数据大小:8位
- 启用SPI1对应GPIO引脚(PA5/PA6/PA7)
- 配置GPIO:
- CS引脚(PB0):推挽输出模式,初始电平设为
高(SPI片选低有效) - RST引脚(PB1):推挽输出模式,初始电平设为
高
- CS引脚(PB0):推挽输出模式,初始电平设为
- 配置USART2(用于调试输出):
- 波特率115200,8位数据,无奇偶校验,1位停止位
- 配置时钟树:确保SPI1、GPIO、USART2的时钟已启用,系统时钟设置为开发板支持的最高频率(U5系列可达160MHz)
- 生成代码,选择将外设初始化代码生成到单独的.c/.h文件
三、核心代码实现
1. 片选与复位控制函数
在main.c中添加:
#define CS_PIN GPIO_PIN_0 #define CS_PORT GPIOB #define RST_PIN GPIO_PIN_1 #define RST_PORT GPIOB void CS_LOW(void) { HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_RESET); } void CS_HIGH(void) { HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_SET); } void Bluefruit_Reset(void) { HAL_GPIO_WritePin(RST_PORT, RST_PIN, GPIO_PIN_RESET); HAL_Delay(100); HAL_GPIO_WritePin(RST_PORT, RST_PIN, GPIO_PIN_SET); HAL_Delay(500); // 等待模块重启完成 }
2. SPI发送接收封装函数
// 发送AT指令并读取响应 uint8_t Bluefruit_SendAT(char *cmd, char *resp_buf, uint16_t buf_len, uint32_t timeout) { uint16_t cmd_len = strlen(cmd); uint16_t resp_idx = 0; uint8_t rx_byte; // 发送指令 CS_LOW(); HAL_SPI_Transmit(&hspi1, (uint8_t*)cmd, cmd_len, timeout); CS_HIGH(); HAL_Delay(10); // 等待模块处理指令 // 读取响应 CS_LOW(); while (HAL_SPI_Receive(&hspi1, &rx_byte, 1, timeout) == HAL_OK) { if (rx_byte == '\n' || resp_idx >= buf_len-1) break; resp_buf[resp_idx++] = rx_byte; } resp_buf[resp_idx] = '\0'; CS_HIGH(); // 检查响应是否包含预期的"OK" return (strstr(resp_buf, "OK") != NULL) ? 1 : 0; }
3. 主函数初始化与测试
在main()函数中添加:
char resp[128]; // 初始化模块 Bluefruit_Reset(); // 测试AT指令连通性 if (Bluefruit_SendAT("AT\r\n", resp, sizeof(resp), 1000)) { printf("Bluefruit通信正常,响应:%s\n", resp); } else { printf("AT指令测试失败,响应:%s\n", resp); } // 设置BLE设备名称 if (Bluefruit_SendAT("AT+GAPDEVNAME=STM32_BLE_Friend\r\n", resp, sizeof(resp), 1000)) { printf("设备名称设置成功\n"); } while (1) { // 循环执行其他任务 HAL_Delay(1000); }
四、常见问题排查
- 通信无响应:检查SPI引脚接线是否正确,CS引脚电平控制是否符合逻辑(发送前拉低,结束后拉高)
- AT指令返回错误:确认SPI模式为CPOL=0、CPHA=0,波特率不超过4MHz
- 模块无反应:确认供电为3.3V(模块不支持5V),尝试通过RST引脚复位模块
- 调试困难:开启USART打印发送指令和接收响应,或用示波器抓取SPI波形分析时序
内容的提问来源于stack exchange,提问作者StarPixel
相关产品推荐
相关产品推荐

