little cmds

repo forall -p -c 'git log --since="3 days"'


#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(5000); // 每 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 留空 } 这是ble蓝牙从机代码,现在要求取消使用加密,直接发送采集到的cell1-16与temp数据,不做计算
10-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值