#include <SPI.h>
#include <BLEDevice.h>
#include <BLE2902.h>
#include <Arduino.h>
// ==================== 引脚定义 ====================
#define SCK_PIN 13
#define MISO_PIN 11
#define MOSI_PIN 14
#define CS_PIN 12
// ==================== 启用调试模式 ====================
#define DEBUG_GMD1032
// ==================== GMD1032 命令列表 ====================
const uint16_t CMD_START_MEASUREMENT = 0x2A16;
const uint16_t CMD_CLEAR_ADC_RESULTS = 0x243C;
const uint16_t CMD_READ_CFG0 = 0xC08E;
const uint16_t CMD_READ_STS0 = 0xC9B1;
// CELL 分组命令
const uint16_t CMD_READ_CELL_1_3 = 0xD0FE;
const uint16_t CMD_READ_CELL_4_6 = 0xD1F9;
const uint16_t CMD_READ_CELL_7_9 = 0xD2F0;
const uint16_t CMD_READ_CELL_10_12 = 0xD3F7;
const uint16_t CMD_READ_CELL_13_15 = 0xD4E2;
const uint16_t CMD_READ_CELL_16_18 = 0xD5E5;
// DIS 分组命令
const uint16_t CMD_READ_DIS_1_3 = 0xD6EC;
const uint16_t CMD_READ_DIS_4_6 = 0xD7EB;
const uint16_t CMD_READ_DIS_7_9 = 0xD8C6;
const uint16_t CMD_READ_DIS_10_12 = 0xD9C1;
const uint16_t CMD_READ_DIS_13_15 = 0xDAC8;
const uint16_t CMD_READ_DIS_16_18 = 0xDBCF;
// 其他测量命令
const uint16_t CMD_READ_VREF2_V3 = 0xDFD3;
const uint16_t CMD_READ_V5_DIETEMP_VSTK = 0xE06E;
// ==================== SPI 设置 ====================
SPISettings spiSettings(1000000, MSBFIRST, SPI_MODE3); // 1MHz, Mode3 (CPOL=1, CPHA=1)
// ==================== BLE 配置 ====================
#define SERVICE_UUID “4fafc201-1fb5-459e-8fcc-c5c9c331914b”
#define CHARACTERISTIC_UUID “beb5483e-36e1-4688-b7f5-ea07361b26a8”
BLECharacteristic* pCharacteristic = nullptr;
bool deviceConnected = false;
float sharedCellVoltages[16] = {0};
float sharedDisVoltages[16] = {0};
float sharedVref2 = 0.0f, sharedV3 = 0.0f, sharedV5 = 0.0f, sharedDieTemp = 0.0f, sharedVstk = 0.0f;
portMUX_TYPE sensorMutex = portMUX_INITIALIZER_UNLOCKED; // 保护共享数据
// 回调类声明
class MyServerCallbacks : public BLEServerCallbacks {
void onConnect(BLEServer* pServer) override {
deviceConnected = true;
Serial.println(“设备接入~”);
}
void onDisconnect(BLEServer* pServer) override { deviceConnected = false; Serial.println("设备断开~"); pServer->startAdvertising(); // 重新开始广播 }
};
class MyCharacteristicCallbacks : public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic* pCharacteristic) override {
std::string value = pCharacteristic->getValue();
if (!value.empty()) {
Serial.print("特征值已更新,新值为: ");
Serial.println(value.c_str());
}
}
};
// ==================== 辅助函数:打印二进制 ====================
void printBinary(uint8_t b) {
for (int i = 7; i >= 0; i–) {
Serial.write((b & (1 << i)) ? ‘1’ : ‘0’);
}
}
// ==================== 唤醒芯片 ====================
void wakeUpGMD1032() {
SPI.beginTransaction(spiSettings);
digitalWrite(CS_PIN, LOW);
delayMicroseconds(10);
SPI.transfer(0x00);
digitalWrite(CS_PIN, HIGH);
SPI.endTransaction();
delay(5);
}
// ==================== 发送命令 ====================
bool sendCommand(uint16_t command) {
SPI.beginTransaction(spiSettings);
digitalWrite(CS_PIN, LOW);
SPI.transfer16(command);
digitalWrite(CS_PIN, HIGH);
SPI.endTransaction();
return true;
}
// ==================== 解析逆序字段 ====================
void parseReverseFields(uint8_t* buffer, uint16_t* results, int count) {
for (int i = 0; i < count; i++) {
int bufIdx = i * 2;
results[count - 1 - i] = (buffer[bufIdx] << 8) | buffer[bufIdx + 1];
}
}
// ==================== 读取所有 CELL 电压 ====================
bool readAllCellVoltages(float* cellVoltages) {
const uint16_t cmds[] = {
CMD_READ_CELL_1_3, CMD_READ_CELL_4_6, CMD_READ_CELL_7_9,
CMD_READ_CELL_10_12, CMD_READ_CELL_13_15, CMD_READ_CELL_16_18
};
const int groupCount = 6;
const int perGroup[] = {3, 3, 3, 3, 3, 3};
SPI.beginTransaction(spiSettings); for (int g = 0; g < groupCount; g++) { digitalWrite(CS_PIN, LOW); SPI.transfer16(cmds[g]); uint8_t buffer[8]; for (int i = 0; i < 8; i++) { buffer[i] = SPI.transfer(0x00); } digitalWrite(CS_PIN, HIGH); uint16_t raw[3]; parseReverseFields(buffer, raw, perGroup[g]); for (int i = 0; i < perGroup[g]; i++) { int idx = g * 3 + i; if (idx >= 16) continue; float voltage = (raw[i] - 10240) * 0.0001f; cellVoltages[idx] = voltage; } } SPI.endTransaction(); return true;
}
// ==================== 读取所有 DIS 电压 ====================
bool readAllDisVoltages(float* disVoltages) {
const uint16_t cmds[] = {
CMD_READ_DIS_1_3, CMD_READ_DIS_4_6, CMD_READ_DIS_7_9,
CMD_READ_DIS_10_12, CMD_READ_DIS_13_15, CMD_READ_DIS_16_18
};
const int groupCount = 6;
const int perGroup[] = {3, 3, 3, 3, 3, 3};
SPI.beginTransaction(spiSettings); for (int g = 0; g < groupCount; g++) { digitalWrite(CS_PIN, LOW); SPI.transfer16(cmds[g]); uint8_t buffer[8]; for (int i = 0; i < 8; i++) { buffer[i] = SPI.transfer(0x00); } digitalWrite(CS_PIN, HIGH); uint16_t raw[3]; parseReverseFields(buffer, raw, perGroup[g]); for (int i = 0; i < perGroup[g]; i++) { int idx = g * 3 + i; if (idx >= 16) continue; float voltage = (raw[i] - 10240) * 0.0001f; disVoltages[idx] = voltage; } } SPI.endTransaction(); return true;
}
// ==================== 读取 VREF2 和 V3 ====================
bool readVref2AndV3(float* vref2, float* v3) {
uint8_t buffer[8];
SPI.beginTransaction(spiSettings);
digitalWrite(CS_PIN, LOW);
SPI.transfer16(CMD_READ_VREF2_V3);
for (int i = 0; i < 8; i++) {
buffer[i] = SPI.transfer(0x00);
}
digitalWrite(CS_PIN, HIGH);
SPI.endTransaction();
uint16_t raw_v3 = (buffer[0] << 8) | buffer[1]; uint16_t raw_vref2 = (buffer[2] << 8) | buffer[3]; *v3 = (raw_v3 - 10240) * 0.0001f; *vref2 = (raw_vref2 - 10240) * 0.0001f; return true;
}
// ==================== 读取 V5 / DieTemp / VSTK ====================
bool readV5DieTempVStk(float* v5, float* dieTemp, float* vstk) {
uint8_t buffer[8];
SPI.beginTransaction(spiSettings);
digitalWrite(CS_PIN, LOW);
SPI.transfer16(CMD_READ_V5_DIETEMP_VSTK);
for (int i = 0; i < 8; i++) {
buffer[i] = SPI.transfer(0x00);
}
digitalWrite(CS_PIN, HIGH);
SPI.endTransaction();
uint16_t raw_vstk = (buffer[0] << 8) | buffer[1]; uint16_t raw_dieTemp = (buffer[2] << 8) | buffer[3]; uint16_t raw_v5 = (buffer[4] << 8) | buffer[5]; *vstk = (raw_vstk - 10240) * 0.0016f; *v5 = (raw_v5 - 10240) * 0.0001f; if (raw_dieTemp >= 8000 && raw_dieTemp <= 30000) { *dieTemp = raw_dieTemp * 0.27662 - 3105.59; } else { *dieTemp = NAN; } return true;
}
// ==================== 更新 BLE 特征值(从 Core 1 调用)====================
void updateBLECharacteristic() {
static char jsonBuffer[512]; // 300 足够容纳 cell[16] + temp
int offset = 0;
float cell[16]; float dieTemp; // 安全拷贝共享数据 portENTER_CRITICAL(&sensorMutex); memcpy(cell, sharedCellVoltages, sizeof(cell)); dieTemp = sharedDieTemp; portEXIT_CRITICAL(&sensorMutex); // 构造 JSON: {"cell":[...], "temp": ...} offset += snprintf(jsonBuffer + offset, sizeof(jsonBuffer) - offset, "{\"cell\":["); for (int i = 0; i < 16; i++) { offset += snprintf(jsonBuffer + offset, sizeof(jsonBuffer) - offset, "%.3f%s", cell[i], (i < 15) ? "," : ""); } if (!isnan(dieTemp)) { offset += snprintf(jsonBuffer + offset, sizeof(jsonBuffer) - offset, "],\"temp\":%.2f}", dieTemp); } else { offset += snprintf(jsonBuffer + offset, sizeof(jsonBuffer) - offset, "],\"temp\":null}"); } // 防溢出兜底 if (offset >= sizeof(jsonBuffer)) { strcpy(jsonBuffer, "{\"err\":\"long\"}"); } // 发送到 BLE if (pCharacteristic && deviceConnected) { pCharacteristic->setValue(jsonBuffer); pCharacteristic->notify(); // 触发通知 }
#ifdef DEBUG_GMD1032
Serial.printf(“BLE Data: %s\n”, jsonBuffer);
#endif
}
// ==================== 核心 0:传感器采集任务 ====================
void sensorTask(void *parameter) {
for (;😉 {
yield(); // 让出时间片
wakeUpGMD1032(); delay(2); sendCommand(CMD_START_MEASUREMENT); delay(10); float cellVoltages[16] = {0}; float disVoltages[16] = {0}; float vref2 = 0.0f, v3 = 0.0f, v5 = 0.0f, dieTemp = 0.0f, vstk = 0.0f; readAllCellVoltages(cellVoltages); readAllDisVoltages(disVoltages); readVref2AndV3(&vref2, &v3); readV5DieTempVStk(&v5, &dieTemp, &vstk); // 写入共享变量(加锁) portENTER_CRITICAL(&sensorMutex); memcpy(sharedCellVoltages, cellVoltages, sizeof(cellVoltages)); memcpy(sharedDisVoltages, disVoltages, sizeof(disVoltages)); sharedVref2 = vref2; sharedV3 = v3; sharedV5 = v5; sharedDieTemp = dieTemp; sharedVstk = vstk; portEXIT_CRITICAL(&sensorMutex);
#ifdef DEBUG_GMD1032
Serial.println(“============== GMD1032 全通道数据 ==============”);
for (int i = 0; i < 16; i++) {
if (i % 4 == 0) {
Serial.print(" ");
}
Serial.printf("CELL%2d:%5.3fV ", i + 1, cellVoltages[i]);
if ((i + 1) % 4 == 0 || i == 15) {
Serial.println();
}
}
if (!isnan(dieTemp)) { Serial.printf("芯片温度: %.2f°C\n", dieTemp); } else { Serial.println("芯片温度: 无效数据"); } Serial.println("---------------------------------------------");
#endif
delay(1000); // 每秒采集一次 }
}
// ==================== 核心 1:BLE 服务任务 ====================
void bleTask(void *parameter) {
BLEDevice::init(“GMD1032-BLE-Slave”);
bool mtuSet = BLEDevice::setMTU(256); Serial.printf("MTU 设置 %s\n", mtuSet ? "成功" : "失败"); BLEServer* pServer = BLEDevice::createServer(); pServer->setCallbacks(new MyServerCallbacks()); BLEService* pService = pServer->createService(SERVICE_UUID); pCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_NOTIFY ); pCharacteristic->addDescriptor(new BLE2902()); pCharacteristic->setCallbacks(new MyCharacteristicCallbacks()); pCharacteristic->setValue("GMD1032 Ready"); pService->start(); BLEAdvertising* pAdvertising = pServer->getAdvertising(); pAdvertising->addServiceUUID(SERVICE_UUID); pAdvertising->start(); Serial.println("BLE 广播已启动,等待连接... (运行于 Core 1)"); for (;;) { if (deviceConnected) { updateBLECharacteristic(); } delay(1000); // 每 1000ms 尝试推送一次 }
}
// ==================== setup() ====================
void setup() {
Serial.begin(115200);
while (!Serial && millis() < 3000);
#ifdef DEBUG_GMD1032
Serial.println(“[DEBUG] GMD1032 调试模式已启用”);
#endif
// === 初始化 SPI === pinMode(CS_PIN, OUTPUT); digitalWrite(CS_PIN, HIGH); SPI.begin(SCK_PIN, MISO_PIN, MOSI_PIN, CS_PIN); // === 创建两个独立任务,分别绑定到不同核心 === xTaskCreatePinnedToCore(sensorTask, "SensorTask", 4096, NULL, 1, NULL, 0); // Core 0 xTaskCreatePinnedToCore(bleTask, "BleTask", 4096, NULL, 2, NULL, 1); // Core 1
}
// ==================== loop() ====================
void loop() {
// 所有功能由 FreeRTOS 任务接管,loop 留空
}
以上为从机代码,
#include “spi_slave_server.h”
// spi
#include <SPI.h>
#include <ESP32SPISlave.h>
#include “helper.h”
ESP32SPISlave slave; // 创建ESP32SPISlave对象
#define SPI_SPLAVE_ENABLE 1
// Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS, 1000000, SPI_BITORDER_MSBFIRST, SPI_MODE0);
#define MY_CS 12
#define MY_SCK 13
#define MY_MOSI 14
#define MY_MISO 11 // 自定义spi引脚
// SPIClass my_spi(HSPI); // 创建SPIClass对象my_spi
#define SPI_READ_TIMEROUT 999999 // 10 // 50ms
static constexpr size_t SPI_BUFFER_SIZE = 16 * 2; // 上位机 测试42 字节数据正常,模式1,定义SPI通信缓冲区大小为32字节
static constexpr size_t QUEUE_SIZE = 1;
static uint8_t spi_tx_buf[SPI_BUFFER_SIZE]{1, 2, 3, 4, 5, 6, 7, 8};//发送缓冲区,预置测试数据1-8
static uint8_t spi_rx_buf[SPI_BUFFER_SIZE]{0, 0, 0, 0, 0, 0, 0, 0};//接收缓冲区,初始化为全0
static uint8_t spi_tx_cmd_buf[SPI_BUFFER_SIZE]{0, 0, 0, 0, 0, 0, 0, 0};//命令发送缓冲区,初始化为全0
#define SPI_TX_CACHE_BUF_LEN 1024//发送缓存总大小为1024字节
#define SPI_TX_PAGE_BUF_LEN (SPI_BUFFER_SIZE - 3) // spi 回复数据的最大长度,单次SPI通信有效数据长度
#define SPI_USER_CMD_NULL 0//空指令
#define SPI_USER_CMD_READ 1//读数据
#define SPI_USER_CMD_WRITE 2//写数据
static volatile uint8_t spi_tx_cache_buf[SPI_TX_CACHE_BUF_LEN]{0, 0, 0, 0, 0, 0, 0, 0};
static volatile int spi_tx_cache_buf_cnt = 0; // spi 发送缓存区数据长度
// static int spi_tx_page_cnt=0;//spi 发送缓存区数据长度
static volatile int spi_current_cmd = 0, spi_current_cmd_len = 0;
static uint8_t spi_send_busy = 0;//发送忙标志位
static uint8_t spi_send_mode = 1; // 发送模式选择发串口
int spi_slave_data_cache_add(uint8_t data, uint16_t len)
{
if (len > SPI_TX_CACHE_BUF_LEN)
{
/ code /
len = SPI_TX_CACHE_BUF_LEN;
}
for (int i = 0; i < len; i++)
{
/ code */
spi_tx_cache_buf[i] = data[i];
}
spi_tx_cache_buf_cnt = len;
return 0;
}
void IRAM_ATTR my_post_setup_cb(spi_slave_transaction_t *trans)//强制将函数编译到内部RAM,确保中断快速响应
{
static uint8_t test_send = 0x11;//静态测试变量
int over_len = spi_tx_cache_buf_cnt - spi_current_cmd_len * SPI_TX_PAGE_BUF_LEN; // 剩余待发送数据量 = 总缓存量 - 已发送页数×单页容量
// Serial.printf("spi slave read over_len = %d cache= %d\r\n", over_len,spi_tx_cache_buf_cnt); if (over_len < 0)//数据已全部发送完成时的保护判断 { return; } if (over_len > SPI_TX_PAGE_BUF_LEN)//单包数据超限时截断处理 { over_len = SPI_TX_PAGE_BUF_LEN; } memset((void *)spi_tx_buf, 0, SPI_BUFFER_SIZE);//清空发送缓冲区(32字节全置0) spi_tx_buf[0] = 0xab; spi_tx_buf[1] = over_len; // 实际长度 spi_tx_buf[2] = spi_current_cmd_len; // 包号 for (int i = 0; i < over_len; i++)//将缓存数据拷贝到发送缓冲区(偏移3字节协议头) { /* code */ spi_tx_buf[3 + i] = spi_tx_cache_buf[spi_current_cmd_len * SPI_TX_PAGE_BUF_LEN + i]; } spi_current_cmd_len++;//包序号自增 if (spi_current_cmd_len >= 3)//包序号归零 { /* code */ spi_current_cmd_len = 0; } // Serial.printf("spi slave read cmd_len = %d ,%02x %02x %02x\n", over_len,spi_tx_buf[1], spi_tx_buf[2], spi_tx_buf[3]);
}
/***
spi slave 任务
模式设置4 字节
spi cmd: 0xaa 0x01 ,切换模式1,发串口1数据
数据读取 64字节,发aa 01 0xff …
spi ack: 0xaa 0x01 ,剩余字节全部回复串口数据
*/
static void spi_slave_task(void pvParameters)//FreeRTOS任务函数标准定义
{
size_t received_bytes; // 记录接收到的数据字节数
while (1)//无限循环,保持任务持续运行
{
/ code */
// initializeBuffers(tx_buf, rx_buf, BUFFER_SIZE);
int cs = digitalRead(MY_CS);//读取片选信号(CS)引脚状态,检测主设备是否选中本从设备
#if SPI_SPLAVE_ENABLE//条件编译开关,控制SPI从设备功能是否启用
if (cs == 0)//当片选信号为低电平时(表示被主设备选中)执行通信
{
memset(spi_rx_buf, 0, SPI_BUFFER_SIZE);//清空接受缓存区
// start and wait to complete one BIG transaction (same data will be received from slave)
received_bytes = slave.transfer(spi_tx_buf, spi_rx_buf, SPI_BUFFER_SIZE, SPI_READ_TIMEROUT);
//tx_buf:发送缓冲区,rx_buf:接收缓冲区,BUFFER_SIZE:传输长度,READ_TIMEROUT:超时时间
// verify and dump difference with received data
if (received_bytes > 0)//成功接收到数据时处理数据
{
printf_log_hex(“slave”, spi_rx_buf, received_bytes);
printf_log_hex(“slave”, spi_tx_buf, received_bytes);
if (spi_rx_buf[1] == 0xaa && spi_rx_buf[2] == 0x01) // 当收到0xAA01时设置为读取模式,读取数据cmd
{
spi_current_cmd = SPI_USER_CMD_READ;
// spi_current_cmd_len = spi_rx_buf[3];
}
my_post_setup_cb(NULL);//调用之前分析的发送回调函数 } }
#endif
vTaskDelay(5 / portTICK_PERIOD_MS);//任务延时5ms
}
}
/**
spi slave 初始化
SPI_MODE1
sck 13
miso 14
mosi 11
ss 12
*/
void spi_slave_server_init(void)
{
#if SPI_SPLAVE_ENABLE
slave.setDataMode(SPI_MODE3); // default: SPI_MODE1
slave.setQueueSize(QUEUE_SIZE); // default: 1
slave.begin(HSPI, 13, 11, 14, 12); // default: HSPI (please refer README for pin assignments)
// pinMode(10, INPUT);
// slave.setPostSetupCb(my_post_setup_cb);
xTaskCreate(spi_slave_task, “spi_slave_task”, 8 * 1024, NULL, 2, NULL);
#endif
}
以上为主机spi.cpp
// BLEClient.cpp
#include “BLEClient.h”
#include <Arduino.h>
BLEClientHandler::BLEClientHandler()
doConnect(false),
pServerAddress(nullptr),
pClient(nullptr)
{
}
BLEClientHandler::~BLEClientHandler() {
if (pServerAddress != nullptr) {
delete pServerAddress;
pServerAddress = nullptr;
}
if (pClient != nullptr && !pClient->isConnected()) {
delete pClient;
pClient = nullptr;
}
}
void BLEClientHandler::begin() {
Serial.println(“初始化 BLE 主机…”);
BLEDevice::init(""); BLEScan* pScan = BLEDevice::getScan(); pScan->setAdvertisedDeviceCallbacks(new AdvertisedDeviceCallbacks(this)); pScan->setActiveScan(true); pScan->start(0, false); // 0 表示无限期扫描,直到手动 stop
}
void BLEClientHandler::AdvertisedDeviceCallbacks::onResult(BLEAdvertisedDevice advertisedDevice) {
Serial.printf(“发现设备: %s\n”, advertisedDevice.toString().c_str());
// 改为通过 Service UUID 判断是否为目标设备 if (advertisedDevice.isAdvertisingService(BLEUUID(SERVICE_UUID))) { Serial.println("发现目标服务 UUID,准备连接..."); pHandler->pServerAddress = new BLEAddress(advertisedDevice.getAddress()); pHandler->doConnect = true; BLEDevice::getScan()->stop(); // 停止扫描 }
}
void BLEClientHandler::ClientCallback::onConnect(BLEClient* pClient) {
Serial.println(“BLE 连接成功”);
}
void BLEClientHandler::ClientCallback::onDisconnect(BLEClient* pClient) {
Serial.println(“与从机断开连接,准备重连…”);
pHandler->doConnect = true;
}
void BLEClientHandler::notifyCallback(BLERemoteCharacteristic* pChar, uint8_t* pData, size_t length, bool isNotify) {
String jsonStr = String((char*)pData).substring(0, length);
Serial.printf(“[JSON] 收到数据 (%d 字节): %s\n”, length, jsonStr.c_str());
}
bool BLEClientHandler::isConnected() const {
return pClient != nullptr && pClient->isConnected();
}
void BLEClientHandler::disconnect() {
if (pClient && pClient->isConnected()) {
pClient->disconnect();
}
}
void BLEClientHandler::loop() {
if (doConnect && pServerAddress != nullptr) {
Serial.print("正在连接到: ");
Serial.println(pServerAddress->toString().c_str());
pClient = BLEDevice::createClient(); pClient->setClientCallbacks(new ClientCallback(this)); if (pClient->connect(*pServerAddress)) { Serial.println("成功建立连接"); // =============== 关键:提升 MTU =============== if (pClient->setMTU(256)) { unsigned long timeout = millis() + 3000; while (pClient->getMTU() <= 23 && millis() < timeout) { delay(10); } Serial.printf("协商后的 MTU: %d\n", pClient->getMTU()); } else { Serial.println("setMTU(256) 调用失败"); } // 发现服务 BLERemoteService* pRemoteService = pClient->getService(SERVICE_UUID); if (pRemoteService == nullptr) { Serial.println("未发现指定服务"); doConnect = false; return; } BLERemoteCharacteristic* pRemoteCharacteristic = pRemoteService->getCharacteristic(CHARACTERISTIC_UUID); if (pRemoteCharacteristic == nullptr) { Serial.println("未发现指定特征值"); doConnect = false; return; } // 注册通知 if (pRemoteCharacteristic->canNotify()) { pRemoteCharacteristic->registerForNotify(notifyCallback); Serial.println("已启用 Notify"); } doConnect = false; // 防止重复连接 } else { Serial.println("连接失败"); delete pServerAddress; pServerAddress = nullptr; doConnect = false; } }
}
以上为主机ble,现在要求按照当前spi的格式,esp32作为spi从机,将通过蓝牙收到的来自1032的数据传输给5606,5606会不间断的发送以AA为开头,后跟FF或00的一串数据,要求esp32在收到5606发出的数据时将1032的数据传输给5606