系统优化方案

This document outlines the comprehensive medium-term optimization plan for the STM32L0-based pulse measurement and UART Direct Memory Access (DMA) has been implemented for UART transmission to offload CPU and improve data transfer efficienc

2026-07-04
系统优化性能提升嵌入式

Medium-Term System Optimization Plan

Executive Summary

This document outlines the comprehensive medium-term optimization plan for the STM32L0-based pulse measurement and UART communication system. The optimization focuses on reducing CPU utilization, improving data transfer efficiency, and ensuring reliable communication while maintaining accurate pulse processing capabilities.

1. DMA Implementation for UART Data Transmission

1.1 Overview

Direct Memory Access (DMA) has been implemented for UART transmission to offload CPU and improve data transfer efficiency.

1.2 Implementation Details

Hardware Configuration
Code Changes

File: main.c


DMA_HandleTypeDef hdma_usart2_tx;

File: stm32l0xxhalmsp.c


/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();

/* DMA interrupt init */
HAL_NVIC_SetPriority(DMA1_Channel4_5_6_7_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel4_5_6_7_IRQn);

/* Configure DMA for USART2 TX */
hdma_usart2_tx.Instance = DMA1_Channel7;
hdma_usart2_tx.Init.Request = DMA_REQUEST_4;
hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_tx.Init.Mode = DMA_NORMAL;
hdma_usart2_tx.Init.Priority = DMA_PRIORITY_HIGH;
HAL_DMA_Init(&hdma_usart2_tx);

__HAL_LINKDMA(huart, hdmatx, hdma_usart2_tx);

File: stm32l0xx_it.c


void DMA1_Channel4_5_6_7_IRQHandler(void)
{
  HAL_DMA_IRQHandler(&hdma_usart2_tx);
}

1.3 Usage Example


uint8_t tx_buffer[64];
// Fill buffer with data
HAL_UART_Transmit_DMA(&huart2, tx_buffer, sizeof(tx_buffer));

1.4 Benefits

2. UART 8x Oversampling Configuration

2.1 Overview

UART oversampling has been reduced from 16x to 8x to improve data reception accuracy and noise immunity while reducing processing overhead.

2.2 Implementation

File: main.c


huart2.Init.OverSampling = UART_OVERSAMPLING_8;

2.3 Benefits

2.4 Trade-offs

3. Pulse Processing Optimization

3.1 Overview

The pulse processing mechanism has been optimized to reduce interrupt load and improve system responsiveness.

3.2 Key Features

3.2.1 Pause/Resume Mechanism

volatile uint8_t pulse_processing_enabled = 1;
volatile uint8_t uart_tx_busy = 0;

void pause_pulse_processing(void)
{
  pulse_processing_enabled = 0;
}

void resume_pulse_processing(void)
{
  pulse_processing_enabled = 1;
}

void uart_tx_callback(void)
{
  uart_tx_busy = 0;
  resume_pulse_processing();
}
3.2.2 Reduced Processing Frequency

uint16_t pulse_process_counter = 0;
#define PULSE_PROCESS_INTERVAL 10

void process_raw_pulse_data(void)
{
  if (!pulse_processing_enabled)
  {
    return;
  }

  if (raw_pulse_index == 0)
  {
    return;
  }

  pulse_process_counter++;
  
  if (pulse_process_counter >= PULSE_PROCESS_INTERVAL)
  {
    pulse_process_counter = 0;
    
    uint16_t pulse_to_process = raw_pulse_buffer[0];
    
    data_processing_pipeline(pulse_to_process);
    
    for (uint16_t i = 1; i < raw_pulse_index; i++)
    {
      raw_pulse_buffer[i - 1] = raw_pulse_buffer[i];
    }
    raw_pulse_index--;
  }
}

3.3 Benefits

4. Architecture Refactoring

4.1 Overview

The system architecture has been refactored to move pulse processing from interrupt context to the main loop.

4.2 Before Optimization


void ADC1_COMP_IRQHandler(void)
{
  // Raw data acquisition
  uint16_t t = __HAL_TIM_GET_COUNTER(&htim22);
  __HAL_TIM_SET_COUNTER(&htim22, 0);
  
  // Data storage
  if ((t > 50) && (t < 2000))
  {
    if (index < 300)
      p[index++] = t;
    else
    {
      index = 0;
      p[index++] = t;
    }
    
    process_pulse(t);  // COMPLEX PROCESSING IN INTERRUPT
  }
  
  // Data validity check
  if ((ok == 0) && (index >= 100))
    ok = 1;
    
  HAL_COMP_IRQHandler(&hcomp2);
}

4.3 After Optimization


void ADC1_COMP_IRQHandler(void)
{
  // Raw data acquisition ONLY
  uint16_t t = __HAL_TIM_GET_COUNTER(&htim22);
  __HAL_TIM_SET_COUNTER(&htim22, 0);
  
  if ((t > 50) && (t < 2000))
  {
    // Store raw data in buffer
    if (index < 300)
      p[index++] = t;
    else
    {
      index = 0;
      p[index++] = t;
    }
    
    // Store in processing buffer
    if (raw_pulse_index < 300)
      raw_pulse_buffer[raw_pulse_index++] = t;
    else
    {
      raw_pulse_index = 0;
      raw_pulse_buffer[raw_pulse_index++] = t;
    }
  }
  
  // Data validity check
  if ((ok == 0) && (index >= 100))
    ok = 1;
    
  HAL_COMP_IRQHandler(&hcomp2);
}

4.4 Main Loop Processing


while (1)
{
  process_raw_pulse_data();  // Process in main loop
  
  if (need_pwm_update)
  {
    uint32_t pwm_value = calculate_pwm_from_current(400);
    update_pwm_output(pwm_value);
    need_pwm_update = 0;
  }
  
  // Other tasks...
}

4.5 Benefits

5. Standardized Data Processing Pipeline

5.1 Overview

A standardized data processing pipeline has been implemented with clear separation of concerns.

5.2 Pipeline Stages

Stage 1: Raw Data Acquisition

void ADC1_COMP_IRQHandler(void)
{
  uint16_t t = __HAL_TIM_GET_COUNTER(&htim22);
  __HAL_TIM_SET_COUNTER(&htim22, 0);
  
  if ((t > 50) && (t < 2000))
  {
    raw_pulse_buffer[raw_pulse_index++] = t;
  }
}
Stage 2: Digital Filtering

uint16_t moving_average(uint16_t new_value)
{
  static uint16_t window[8] = {0};
  static uint8_t window_index = 0;
  static uint8_t window_filled = 0;
  uint32_t sum = 0;
  uint8_t i;

  window[window_index] = new_value;
  window_index = (window_index + 1) % 8;

  if (window_index == 0)
  {
    window_filled = 1;
  }

  uint8_t count = window_filled ? 8 : window_index;

  for (i = 0; i < count; i++)
  {
    sum += window[i];
  }

  return (uint16_t)(sum / count);
}
Stage 3: Baseline Update

void update_baseline(uint16_t pulse)
{
  pulse_history[history_index] = pulse;
  history_index = (history_index + 1) % 8;

  if (history_index == 0 && !baseline_valid)
  {
    baseline_valid = 1;
  }

  if (baseline_valid)
  {
    baseline_pulse = median_filter(pulse_history, 8);
    if (baseline_pulse != 0)
    {
      para.O_Hz = calculate_frequency_from_pulse(baseline_pulse);
    }
  }
}
Stage 4: Anomaly Detection

uint8_t is_abnormal_pulse(uint16_t pulse, uint16_t baseline_pulse)
{
  if (baseline_pulse == 0) return 0;

  uint16_t upper_limit = baseline_pulse + (baseline_pulse * 30 / 100);
  uint16_t lower_limit = baseline_pulse - (baseline_pulse * 30 / 100);

  return (pulse > upper_limit) || (pulse < lower_limit);
}

5.3 Integrated Pipeline


void data_processing_pipeline(uint16_t raw_pulse)
{
  // Stage 1: Validation
  if (!validate_pulse_width(raw_pulse))
  {
    return;
  }

  // Stage 2: Digital Filtering
  uint16_t filtered_value = moving_average(raw_pulse);
  
  // Stage 3: Baseline Management
  if (startup_phase)
  {
    startup_count++;

    if (startup_count >= 20)
    {
      startup_phase = 0;
      baseline_valid = 1;
      baseline_pulse = filtered_value;
      last_valid_pulse = baseline_pulse;
      last_valid_time = t_ms;

      if (filtered_index < 300)
      {
        filtered_p[filtered_index++] = baseline_pulse;
      }
      else
      {
        filtered_index = 0;
        filtered_p[filtered_index++] = baseline_pulse;
      }
    }
  }
  else
  {
    // Stage 4: Anomaly Detection
    if (!is_abnormal_pulse(raw_pulse, baseline_pulse))
    {
      update_baseline(filtered_value);
      last_valid_pulse = filtered_value;
      last_valid_time = t_ms;

      if (filtered_index < 300)
      {
        filtered_p[filtered_index++] = filtered_value;
      }
      else
      {
        filtered_index = 0;
        filtered_p[filtered_index++] = filtered_value;
      }
    }
  }
}

6. Interrupt Priority Optimization

6.1 Overview

Interrupt priorities have been reconfigured to ensure UART communication has the highest priority.

6.2 Priority Configuration

File: stm32l0xxhalmsp.c


// UART2 - Highest priority (0,0)
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);

// DMA - Highest priority (0,0)
HAL_NVIC_SetPriority(DMA1_Channel4_5_6_7_IRQn, 0, 0);

// ADC1_COMP - Medium priority (1,0)
HAL_NVIC_SetPriority(ADC1_COMP_IRQn, 1, 0);

// TIM2 - Lowest priority (2,0)
HAL_NVIC_SetPriority(TIM2_IRQn, 2, 0);

6.3 Priority Rationale

  1. USART2 (0,0): Critical communication, data loss is unacceptable
  2. DMA (0,0): High-speed data transfer, time-sensitive
  3. ADC1_COMP (1,0): Pulse measurement, can tolerate some delay
  4. TIM2 (2,0): System timing, lowest priority

7. Performance Metrics

7.1 Before Optimization

7.2 After Optimization

7.3 Improvement Summary

8. Usage Guidelines

8.1 UART Transmission with DMA


// Example: Send data using DMA
uint8_t tx_data[128];
// Prepare data...

// Pause pulse processing during critical transmission
pause_pulse_processing();
uart_tx_busy = 1;

// Start DMA transmission
HAL_StatusTypeDef status = HAL_UART_Transmit_DMA(&huart2, tx_data, sizeof(tx_data));

if (status != HAL_OK)
{
  // Handle error
  uart_tx_busy = 0;
  resume_pulse_processing();
}

// Processing will resume automatically when transmission completes

8.2 Monitoring Pulse Processing


// Check if pulse processing is enabled
if (pulse_processing_enabled)
{
  // Pulse processing is active
}
else
{
  // Pulse processing is paused (e.g., during UART transmission)
}

// Check raw pulse buffer status
if (raw_pulse_index > 0)
{
  // There are pulses waiting to be processed
}

8.3 Adjusting Processing Frequency


// Modify processing interval as needed
// Current: Process every 10th pulse
#define PULSE_PROCESS_INTERVAL 10

// For more frequent processing (every 5th pulse):
#define PULSE_PROCESS_INTERVAL 5

// For less frequent processing (every 20th pulse):
#define PULSE_PROCESS_INTERVAL 20

9. Testing and Verification

9.1 Unit Tests

9.2 Integration Tests

9.3 Performance Tests

9.4 Stress Tests

10. Troubleshooting

10.1 Common Issues

Issue: UART Data Loss

Symptoms: Missing or corrupted UART data Solutions:

  1. Verify DMA configuration
  2. Check interrupt priorities
  3. Ensure buffer sizes are adequate
  4. Monitor CPU utilization
Issue: Pulse Processing Delays

Symptoms: Inaccurate pulse measurements Solutions:

  1. Reduce PULSEPROCESSINTERVAL
  2. Check pulseprocessingenabled flag
  3. Verify rawpulsebuffer status
  4. Monitor interrupt execution time
Issue: System Instability

Symptoms: Unexpected resets or crashes Solutions:

  1. Check stack usage
  2. Verify interrupt nesting
  3. Review memory allocation
  4. Monitor watchdog timers

11. Future Enhancements

11.1 Short-term

11.2 Medium-term

11.3 Long-term

12. Conclusion

This medium-term optimization plan significantly improves system performance, reliability, and maintainability. The implementation of DMA, optimized pulse processing, and standardized data processing pipeline provides a solid foundation for future enhancements while ensuring robust operation in production environments.

Key Achievements

Next Steps

  1. Complete testing and verification
  2. Deploy to production environment
  3. Monitor performance metrics
  4. Gather user feedback
  5. Plan future enhancements

Document Version: 1.0 Last Updated: 2026-02-23 Author: System Optimization Team Status: Implementation Complete - Testing Phase