ZHDA192 June 2026 MSPM0G5187
本节详细介绍了 LP-MSPM0G5187 上用于实时电弧故障检测的固件架构。
主环路状态机:
图 7-1 固件状态机图. 显示主应用程序循环和中断处理程序的固件状态机图使用 TI SysConfig 配置 MSPM0G5187 外设。密钥设置:
| 外设 | 配置 |
|---|---|
| ADC12_0 | 12 位,SYSOSC 时钟,启用 DMA,通道 ADC0_14 |
| DMA | 乒乓传输,每个缓冲区 512 个样本 |
| GPIO | PA11(继电器),PB4/PB5 (LED),PA31(比较器输入) |
| 闪存存储器 (128KB) | SRAM (32KB) |
|---|---|
| 可用(约 94KB) | 可用(约 23KB) |
| 模型(约 5.5 KB) | 栈(约 2KB) |
| 模型(约 5.5 KB) | 张量空间 (2 KB) |
| 应用程序代码(约 20KB) | 功能 Buf (1 KB) |
| ADC 缓冲器 (1KB) | |
| FFT 暂存 (2KB) |
乒乓缓冲器策略
/* ADC Ping-Pong Buffers */
int16_t gADCSamplesPing[ADC_SAMPLE_SIZE]; // 512 samples
int16_t gADCSamplesPong[ADC_SAMPLE_SIZE]; // 512 samples
volatile bool gPing = true; // Current buffer indicator
volatile bool gCheckADC = false; // New data ready flagDMA 填充一个缓冲区,同时 CPU 处理另一个缓冲区,从而实现连续采样。
/* Scales ADC samples and converts them to Q15 format */
void adc_q15_scale(int16_t *samples)
{
int16_t shift = 2048; // Mid-scale for 12-bit ADC
for (int i = 0; i < ADC_SAMPLE_SIZE; ++i)
{
// Convert from unsigned 12-bit to signed Q15
// Shift of 4 provides 16x gain for better SNR
samples[i] = samples[i]*8
}
}
#include "feature_extract.h"
// Initialize feature extraction (call once at startup)
FE_init();
// Process each frame of ADC samples
FE_process(newSamples, gNewFeatures, 0); // varIndex=0 for single channel
/* NPU Initialization */
DL_NPU_reset(NPU);
DL_NPU_enablePower(NPU);
while (!(DL_SYSCTL_getStatus() & DL_SYSCTL_STATUS_NPU_READY));
/* Input/Output tensor structures */
struct tvmgen_default_inputs tvm_if_map = { (void*) &gIF_Map[0] };
struct tvmgen_default_outputs tvm_of_map = { (void*) &gOF_Map[0] };
/* Run inference */
tvmgen_default_run(&tvm_if_map, &tvm_of_map);
/* Wait for completion */
while (!tvmgen_default_finished) { __WFE(); }
/* Output: gOF_Map[0][0] = arc confidence, gOF_Map[0][1] = normal confidence */
#define INFERENCE_FRAME_THRESHOLD_FOR_ARC 5
/* Circular buffer for predictions */
volatile uint8_t gPredVector[8] = {0};
volatile uint8_t gPredPtr = 0;
volatile uint16_t gPredSum = 0;
int trip_logic(int inf)
{
/* Update circular buffer */
gPredSum -= gPredVector[gPredPtr];
if (inf >= 0) {
gPredVector[gPredPtr] = 1;
gPredSum += 1;
} else {
gPredVector[gPredPtr] = 0;
}
gPredPtr = (gPredPtr + 1) % 8;
/* Majority voting: 5 out of 8 frames must detect arc */
return (gPredSum > INFERENCE_FRAME_THRESHOLD_FOR_ARC) ? 1 : 0;
}