From fee2e96eaa04005a4cfc6fa5af6f667c6cc3f497 Mon Sep 17 00:00:00 2001 From: zhoujie <929834232@qq.com> Date: Fri, 6 Feb 2026 22:45:25 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(system):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E6=80=A7=E8=83=BD=E5=B9=B6=E7=AE=80=E5=8C=96?= =?UTF-8?q?=E7=9B=91=E6=8E=A7=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增VSCode编辑器配置,启用保存时自动格式化 - 新增DMA2_Stream5和USART1中断处理函数,优化SPI传输性能 - 移除TIM1相关配置和性能监控模块,简化系统架构 - 优化GPIO配置,将ADC_SYNC和PA8引脚合并配置 - 简化系统监控模块,仅保留采样计数和数据溢出统计 - 优化SPI配置,使用16位数据宽度并提高DMA优先级 - 提高USART波特率(USART1:2Mbps, USART3:921600bps) - 优化LTC2508驱动,增加初始化状态检查和缓冲区大小 - 修正数据存储模块,使用校正数据包而非校正结果结构体 - 优化RS485驱动,使用中断传输并添加传输完成回调 - 更新IOC配置文件,移除TIM1并调整中断优先级配置 - 新增系统监控简化说明文档,详细记录架构变更 --- .vscode/settings.json | 3 + Core/Inc/stm32f4xx_it.h | 2 + Core/Inc/tim.h | 5 - Core/Src/dma.c | 3 + Core/Src/gpio.c | 8 +- Core/Src/main.c | 297 ++++----------------- Core/Src/spi.c | 44 ++- Core/Src/stm32f4xx_it.c | 30 +++ Core/Src/tim.c | 126 +-------- Core/Src/usart.c | 10 +- STM_ATEM_F405.ioc | 82 +++--- USB_DEVICE/App/usbd_storage_if.c | 2 +- User/SystemMonitor_Simplification_Notes.md | 130 +++++++++ User/correction.c | 6 +- User/data_packet.c | 12 +- User/data_storage.c | 14 +- User/data_storage.h | 8 +- User/ltc2508_driver.c | 21 +- User/ltc2508_driver.h | 3 +- User/performance_monitor.c | 193 ------------- User/performance_monitor.h | 54 ---- User/rs485_driver.c | 30 ++- User/system_monitor.c | 78 +----- User/system_monitor.h | 45 +--- 24 files changed, 388 insertions(+), 818 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 User/SystemMonitor_Simplification_Notes.md delete mode 100644 User/performance_monitor.c delete mode 100644 User/performance_monitor.h diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..23fd35f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.formatOnSave": true +} \ No newline at end of file diff --git a/Core/Inc/stm32f4xx_it.h b/Core/Inc/stm32f4xx_it.h index f336bbe..cf2001d 100644 --- a/Core/Inc/stm32f4xx_it.h +++ b/Core/Inc/stm32f4xx_it.h @@ -59,10 +59,12 @@ void EXTI1_IRQHandler(void); void DMA1_Stream0_IRQHandler(void); void DMA1_Stream3_IRQHandler(void); void TIM2_IRQHandler(void); +void USART1_IRQHandler(void); void SDIO_IRQHandler(void); void DMA2_Stream0_IRQHandler(void); void DMA2_Stream3_IRQHandler(void); void OTG_FS_IRQHandler(void); +void DMA2_Stream5_IRQHandler(void); void DMA2_Stream6_IRQHandler(void); void DMA2_Stream7_IRQHandler(void); /* USER CODE BEGIN EFP */ diff --git a/Core/Inc/tim.h b/Core/Inc/tim.h index 24dd662..5e9bd09 100644 --- a/Core/Inc/tim.h +++ b/Core/Inc/tim.h @@ -32,19 +32,14 @@ extern "C" { /* USER CODE END Includes */ -extern TIM_HandleTypeDef htim1; - extern TIM_HandleTypeDef htim2; /* USER CODE BEGIN Private defines */ /* USER CODE END Private defines */ -void MX_TIM1_Init(void); void MX_TIM2_Init(void); -void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); - /* USER CODE BEGIN Prototypes */ /* USER CODE END Prototypes */ diff --git a/Core/Src/dma.c b/Core/Src/dma.c index 0fb0498..6e0ede8 100644 --- a/Core/Src/dma.c +++ b/Core/Src/dma.c @@ -56,6 +56,9 @@ void MX_DMA_Init(void) /* DMA2_Stream3_IRQn interrupt configuration */ HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 10, 0); HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn); + /* DMA2_Stream5_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(DMA2_Stream5_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(DMA2_Stream5_IRQn); /* DMA2_Stream6_IRQn interrupt configuration */ HAL_NVIC_SetPriority(DMA2_Stream6_IRQn, 10, 0); HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn); diff --git a/Core/Src/gpio.c b/Core/Src/gpio.c index 30a01fd..9dd2a6d 100644 --- a/Core/Src/gpio.c +++ b/Core/Src/gpio.c @@ -52,7 +52,7 @@ void MX_GPIO_Init(void) __HAL_RCC_GPIOD_CLK_ENABLE(); /*Configure GPIO pin Output Level */ - HAL_GPIO_WritePin(ADC_SYNC_GPIO_Port, ADC_SYNC_Pin, GPIO_PIN_RESET); + HAL_GPIO_WritePin(GPIOA, ADC_SYNC_Pin|GPIO_PIN_8, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(RS485_CTL_GPIO_Port, RS485_CTL_Pin, GPIO_PIN_RESET); @@ -69,12 +69,12 @@ void MX_GPIO_Init(void) GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(ADC_DRY_GPIO_Port, &GPIO_InitStruct); - /*Configure GPIO pin : ADC_SYNC_Pin */ - GPIO_InitStruct.Pin = ADC_SYNC_Pin; + /*Configure GPIO pins : ADC_SYNC_Pin PA8 */ + GPIO_InitStruct.Pin = ADC_SYNC_Pin|GPIO_PIN_8; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - HAL_GPIO_Init(ADC_SYNC_GPIO_Port, &GPIO_InitStruct); + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /*Configure GPIO pin : RS485_CTL_Pin */ GPIO_InitStruct.Pin = RS485_CTL_Pin; diff --git a/Core/Src/main.c b/Core/Src/main.c index cee2310..c6fdc5d 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -35,7 +35,6 @@ #include "correction.h" #include "data_storage.h" #include "system_monitor.h" -#include "performance_monitor.h" #include #include /* USER CODE END Includes */ @@ -53,7 +52,6 @@ // 监控功能宏开关 #define ENABLE_SYSTEM_MONITOR 1 // 系统监控开关 -#define ENABLE_PERFORMANCE_MONITOR 1 // 性能监控开关 /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ @@ -80,9 +78,7 @@ CorrectedDataPacket_t g_corrected_packet; // 数据存储句柄 DataStorageHandle_t g_data_storage; // 系统状态 -static uint32_t g_last_monitor_update = 0; static uint8_t g_recording_enabled = 0; -static uint32_t g_sample_count = 0; // USB连接状态管理 static uint8_t g_usb_connected = 0; @@ -92,7 +88,6 @@ static uint32_t g_last_usb_check = 0; // 性能监控和调试输出 static uint32_t g_last_debug_output = 0; static uint8_t g_debug_output_enabled = ENABLE_UART_DEBUG_OUTPUT; -static SystemPerfStats_t g_perf_stats; /* USER CODE END PV */ @@ -112,7 +107,6 @@ static void UnmountFileSystemForSampling(void); static void DebugOutput_Init(void); static void DebugOutput_SendString(const char* str); static void DebugOutput_PrintSystemStats(void); -static void DebugOutput_PrintPerformanceStats(void); /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ @@ -127,13 +121,6 @@ static void StartRecording(void) if (!g_recording_enabled) { if (DataStorage_StartRecording(&g_data_storage) == HAL_OK) { g_recording_enabled = 1; -#if ENABLE_SYSTEM_MONITOR - SystemMonitor_SetState(SYSTEM_STATE_RECORDING); -#endif - } else { -#if ENABLE_SYSTEM_MONITOR - SystemMonitor_ReportError(SYSTEM_ERROR_STORAGE); -#endif } } } @@ -147,9 +134,6 @@ static void StopRecording(void) if (g_recording_enabled) { g_recording_enabled = 0; DataStorage_StopRecording(&g_data_storage); -#if ENABLE_SYSTEM_MONITOR - SystemMonitor_SetState(SYSTEM_STATE_IDLE); -#endif } } @@ -163,145 +147,61 @@ static void ProcessAdcData(void) LTC2508_BufferTypeDef *ready_buffer = NULL; if (LTC2508_GetReadyBuffer(&ready_buffer) == LTC2508_OK && ready_buffer != NULL) { -#if ENABLE_PERFORMANCE_MONITOR - PerformanceMonitor_TaskStart(PERF_TASK_ADC_PROCESSING); -#endif #if ENABLE_SYSTEM_MONITOR - SystemMonitor_SetState(SYSTEM_STATE_SAMPLING); + SystemMonitor_IncrementSampleCount(); #endif - g_sample_count++; // 1. 从双缓冲区获取数据并合并 (高位16位在前) int32_t raw_adc[NUM_LTC2508]; for (uint8_t i = 0; i < NUM_LTC2508; i++) { raw_adc[i] = (int32_t)(((uint32_t)ready_buffer->data[i][0] << 16) | ready_buffer->data[i][1]); } -#if ENABLE_PERFORMANCE_MONITOR - PerformanceMonitor_TaskEnd(PERF_TASK_ADC_PROCESSING); -#endif - - // 2. 验证数据有效性 - uint8_t data_valid = 1; - for (uint8_t i = 0; i < NUM_LTC2508; i++) { - if (LTC2508_ValidateData(ready_buffer, i) != LTC2508_OK) { -#if ENABLE_SYSTEM_MONITOR - SystemMonitor_ReportError(SYSTEM_ERROR_ADC); -#endif - data_valid = 0; - break; // 如果有任何通道数据无效,跳过整个样本 - } - } - - if (!data_valid) { - // 释放缓冲区并返回 - LTC2508_ReleaseBuffer(LTC2508_GetCurrentReadBuffer()); -#if ENABLE_SYSTEM_MONITOR - SystemMonitor_SetState(SYSTEM_STATE_IDLE); -#endif - return; - } // 3. 应用校正算法 CorrectionResult_t correction_result; uint8_t correction_applied = 0; - -#if ENABLE_PERFORMANCE_MONITOR - PerformanceMonitor_TaskStart(PERF_TASK_CORRECTION); -#endif + if (g_correction_params.params_valid && Apply_Correction(raw_adc[0], raw_adc[1], raw_adc[2], &correction_result, &g_correction_params) == HAL_OK) { -#if ENABLE_PERFORMANCE_MONITOR - PerformanceMonitor_TaskEnd(PERF_TASK_CORRECTION); -#endif - + + // 4a. 打包校正后的数据 -#if ENABLE_PERFORMANCE_MONITOR - PerformanceMonitor_TaskStart(PERF_TASK_DATA_PACKET); -#endif PackCorrectedData(&g_corrected_packet, correction_result.corrected_x, correction_result.corrected_y, correction_result.corrected_z); -#if ENABLE_PERFORMANCE_MONITOR - PerformanceMonitor_TaskEnd(PERF_TASK_DATA_PACKET); -#endif + correction_applied = 1; - + // 发送校正后的数据包 -#if ENABLE_PERFORMANCE_MONITOR - PerformanceMonitor_TaskStart(PERF_TASK_RS485_TX); -#endif - if (RS485_SendData((uint8_t*)&g_corrected_packet, sizeof(CorrectedDataPacket_t)) != HAL_OK) { -#if ENABLE_SYSTEM_MONITOR - SystemMonitor_ReportError(SYSTEM_ERROR_COMMUNICATION); -#endif - } -#if ENABLE_PERFORMANCE_MONITOR - PerformanceMonitor_TaskEnd(PERF_TASK_RS485_TX); -#endif - } else { -#if ENABLE_PERFORMANCE_MONITOR - PerformanceMonitor_TaskEnd(PERF_TASK_CORRECTION); -#endif + RS485_SendData((uint8_t*)&g_corrected_packet, sizeof(CorrectedDataPacket_t)); + } else { // 4b. 校正失败或未启用,使用原始数据 -#if ENABLE_PERFORMANCE_MONITOR - PerformanceMonitor_TaskStart(PERF_TASK_DATA_PACKET); -#endif PackData(&g_data_packet, raw_adc[0], raw_adc[1], raw_adc[2]); -#if ENABLE_PERFORMANCE_MONITOR - PerformanceMonitor_TaskEnd(PERF_TASK_DATA_PACKET); -#endif - + // 发送原始数据包 -#if ENABLE_PERFORMANCE_MONITOR - PerformanceMonitor_TaskStart(PERF_TASK_RS485_TX); -#endif - if (RS485_SendData((uint8_t*)&g_data_packet, sizeof(DataPacket_t)) != HAL_OK) { -#if ENABLE_SYSTEM_MONITOR - SystemMonitor_ReportError(SYSTEM_ERROR_COMMUNICATION); -#endif - } -#if ENABLE_PERFORMANCE_MONITOR - PerformanceMonitor_TaskEnd(PERF_TASK_RS485_TX); -#endif + RS485_SendData((uint8_t*)&g_data_packet, sizeof(DataPacket_t)); } - + // 6. 存储数据到SD卡 (如果启用记录) if (g_recording_enabled) { -#if ENABLE_SYSTEM_MONITOR - SystemMonitor_SetState(SYSTEM_STATE_RECORDING); -#endif -#if ENABLE_PERFORMANCE_MONITOR - PerformanceMonitor_TaskStart(PERF_TASK_FATFS_WRITE); -#endif - if (correction_applied) { // 存储校正后的数据 - if (DataStorage_WriteCorrectedData(&g_data_storage, &correction_result) != HAL_OK) { -#if ENABLE_SYSTEM_MONITOR - SystemMonitor_ReportError(SYSTEM_ERROR_STORAGE); -#endif - } + DataStorage_WriteCorrectedData(&g_data_storage, &g_corrected_packet); } else { // 存储原始数据 - if (DataStorage_WriteData(&g_data_storage, &g_data_packet) != HAL_OK) { -#if ENABLE_SYSTEM_MONITOR - SystemMonitor_ReportError(SYSTEM_ERROR_STORAGE); -#endif - } + DataStorage_WriteData(&g_data_storage, &g_data_packet); } -#if ENABLE_PERFORMANCE_MONITOR - PerformanceMonitor_TaskEnd(PERF_TASK_FATFS_WRITE); -#endif } // 7. 释放已处理的缓冲区 LTC2508_ReleaseBuffer(LTC2508_GetCurrentReadBuffer()); - + } else { + // 数据来不及处理 #if ENABLE_SYSTEM_MONITOR - SystemMonitor_SetState(SYSTEM_STATE_IDLE); + SystemMonitor_ReportDataOverflow(); #endif } } @@ -343,70 +243,21 @@ static void DebugOutput_PrintSystemStats(void) return; } - char buffer[256]; + char buffer[128]; SystemMonitorStats_t sys_stats; SystemMonitor_GetStats(&sys_stats); snprintf(buffer, sizeof(buffer), - "\r\n=== System Monitor Stats ===\r\n" - "State: %d, Uptime: %lu s\r\n" - "Total Samples: %lu, Errors: %lu\r\n" - "Memory Usage: %lu bytes\r\n" - "CPU Usage: %d%%, Temp: %d°C\r\n", - sys_stats.current_state, - sys_stats.uptime_seconds, + "\r\n=== System Stats ===\r\n" + "Total Samples: %lu\r\n" + "Data Overflow: %lu\r\n", sys_stats.total_samples, - sys_stats.error_count, - sys_stats.memory_usage, - sys_stats.cpu_usage_percent, - sys_stats.temperature_celsius); + sys_stats.data_overflow_count); DebugOutput_SendString(buffer); #endif } -/** - * @brief 输出性能监控统计信息 - * @retval None - */ -static void DebugOutput_PrintPerformanceStats(void) -{ -#if ENABLE_PERFORMANCE_MONITOR - if (!g_debug_output_enabled) { - return; - } - - char buffer[512]; - PerformanceMonitor_GetStats(&g_perf_stats); - - snprintf(buffer, sizeof(buffer), - "\r\n=== Performance Monitor Stats ===\r\n" - "Total CPU Usage: %lu%%\r\n" - "Free Heap: %lu bytes (Min: %lu)\r\n" - "Stack Usage: %lu%%\r\n", - g_perf_stats.total_cpu_usage_percent, - g_perf_stats.free_heap_size, - g_perf_stats.min_free_heap_size, - g_perf_stats.stack_usage_percent); - - DebugOutput_SendString(buffer); - - // 输出各任务性能统计 - for (int i = 0; i < PERF_MON_MAX_TASKS; i++) { - if (g_perf_stats.tasks[i].call_count > 0) { - snprintf(buffer, sizeof(buffer), - "Task[%d]: Calls=%lu, Avg=%lu us, Max=%lu us, CPU=%.1f%%\r\n", - i, - g_perf_stats.tasks[i].call_count, - g_perf_stats.tasks[i].avg_time_us, - g_perf_stats.tasks[i].max_time_us, - g_perf_stats.tasks[i].cpu_usage_percent); - DebugOutput_SendString(buffer); - } - } -#endif -} - /** * @brief 检查USB连接状态 * @retval 1: USB已连接, 0: USB未连接 @@ -444,10 +295,6 @@ static void HandleUSBConnectionChange(void) // 卸载用于采样的文件系统 UnmountFileSystemForSampling(); - -#if ENABLE_SYSTEM_MONITOR - SystemMonitor_SetState(SYSTEM_STATE_USB_MODE); -#endif } else { // USB断开:重新挂载文件系统,开始数据采集 DebugOutput_SendString("USB Disconnected: Starting data acquisition\r\n"); @@ -459,10 +306,6 @@ static void HandleUSBConnectionChange(void) StartRecording(); } } - -#if ENABLE_SYSTEM_MONITOR - SystemMonitor_SetState(SYSTEM_STATE_IDLE); -#endif } } } @@ -578,7 +421,6 @@ int main(void) MX_SPI1_Init(); MX_SPI2_Init(); MX_SPI3_Init(); - MX_TIM1_Init(); MX_USART1_UART_Init(); MX_FATFS_Init(); MX_USB_DEVICE_Init(); @@ -586,32 +428,18 @@ int main(void) MX_TIM2_Init(); /* USER CODE BEGIN 2 */ -// SD_NAND_Init_And_Mount(); +// SD_NAND_Init_And_Mount(); // SD_Test_Write(); // SD_Test_Read(); // 初始化系统监控 #if ENABLE_SYSTEM_MONITOR SystemMonitor_Init(); - SystemMonitor_SetState(SYSTEM_STATE_INIT); -#endif - - // 初始化性能监控 -#if ENABLE_PERFORMANCE_MONITOR - PerformanceMonitor_Init(); #endif // 初始化调试输出 DebugOutput_Init(); - // 初始化LTC2508驱动 - if (LTC2508_Init(&hspi1, &hspi2, &hspi3) != LTC2508_OK) { -#if ENABLE_SYSTEM_MONITOR - SystemMonitor_ReportError(SYSTEM_ERROR_ADC); -#endif - Error_Handler(); - } - // 初始化RS485通信 RS485_Init(&huart1, RS485_DE_RE_PORT, RS485_DE_RE_PIN); @@ -629,15 +457,7 @@ int main(void) if (DataStorage_Init(&g_data_storage) == HAL_OK) { // 开始数据记录 StartRecording(); - } else { -#if ENABLE_SYSTEM_MONITOR - SystemMonitor_ReportError(SYSTEM_ERROR_STORAGE); -#endif } - } else { -#if ENABLE_SYSTEM_MONITOR - SystemMonitor_ReportError(SYSTEM_ERROR_STORAGE); -#endif } } else { // USB已连接,不进行数据采集 @@ -649,22 +469,24 @@ int main(void) } } - // 系统初始化完成 -#if ENABLE_SYSTEM_MONITOR - SystemMonitor_SetState(SYSTEM_STATE_IDLE); -#endif - // 启动TIM2定时器用于1ms周期的ADC数据处理 if (HAL_TIM_Base_Start_IT(&htim2) != HAL_OK) { -#if ENABLE_SYSTEM_MONITOR - SystemMonitor_ReportError(SYSTEM_ERROR_CRITICAL); -#endif Error_Handler(); } + // 初始化LTC2508驱动 + if (LTC2508_Init(&hspi1, &hspi2, &hspi3) != LTC2508_OK) { + Error_Handler(); + } + // 触发信号引脚初始化 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET); + HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET); + HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET); + HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET); + HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET); + /* USER CODE END 2 */ /* Infinite loop */ @@ -674,21 +496,8 @@ int main(void) /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ - // 系统监控更新 (每100ms更新一次) + // 定期任务 uint32_t current_tick = HAL_GetTick(); - if (current_tick - g_last_monitor_update >= 100) { -#if ENABLE_PERFORMANCE_MONITOR - PerformanceMonitor_TaskStart(PERF_TASK_SYSTEM_MONITOR); -#endif -#if ENABLE_SYSTEM_MONITOR - SystemMonitor_Update(); -#endif -#if ENABLE_PERFORMANCE_MONITOR - PerformanceMonitor_Update(); - PerformanceMonitor_TaskEnd(PERF_TASK_SYSTEM_MONITOR); -#endif - g_last_monitor_update = current_tick; - } // USB连接状态检测 (每500ms检测一次) if (current_tick - g_last_usb_check >= 500) { @@ -704,7 +513,6 @@ int main(void) // 定期输出调试信息 (每1秒输出一次) if (g_debug_output_enabled && (current_tick - g_last_debug_output >= DEBUG_OUTPUT_INTERVAL_MS)) { DebugOutput_PrintSystemStats(); - DebugOutput_PrintPerformanceStats(); g_last_debug_output = current_tick; } @@ -772,14 +580,19 @@ void SystemClock_Config(void) */ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { - if (GPIO_Pin == ADC_DRY_Pin) { - // ADC数据就绪,触发DMA读取 - if (LTC2508_TriggerDmaRead() != LTC2508_OK) { -#if ENABLE_SYSTEM_MONITOR - SystemMonitor_ReportError(SYSTEM_ERROR_ADC); -#endif + static uint32_t cnt = 0; + if(LTC2508_IsInited() == 0) return; + + cnt ++; + // if(cnt % 5 == 0) + { + // HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET); + if (GPIO_Pin == ADC_DRY_Pin) { + // ADC数据就绪,触发DMA读取 + LTC2508_TriggerDmaRead(); } - } + // HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET); + } } /** @@ -808,9 +621,6 @@ void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi) { // 调用LTC2508驱动的错误回调 LTC2508_ErrorCallback(hspi); -#if ENABLE_SYSTEM_MONITOR - SystemMonitor_ReportError(SYSTEM_ERROR_ADC); -#endif } /** @@ -827,13 +637,10 @@ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) const uint8_t max_process_per_interrupt = 8; // 限制每次中断最多处理的数据量,避免中断时间过长 while (processed_count < max_process_per_interrupt) { - LTC2508_BufferTypeDef *ready_buffer = NULL; - if (LTC2508_GetReadyBuffer(&ready_buffer) == LTC2508_OK && ready_buffer != NULL) { - ProcessAdcData(); - processed_count++; - } else { - break; // 没有更多数据可处理 - } + HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET); + ProcessAdcData(); + HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET); + processed_count++; } } } @@ -862,12 +669,6 @@ void Error_Handler(void) /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ - // 设置系统状态为错误状态 -#if ENABLE_SYSTEM_MONITOR - SystemMonitor_SetState(SYSTEM_STATE_ERROR); - SystemMonitor_ReportError(SYSTEM_ERROR_CRITICAL); -#endif - // 停止所有DMA传输 HAL_SPI_DMAStop(&hspi1); HAL_SPI_DMAStop(&hspi2); diff --git a/Core/Src/spi.c b/Core/Src/spi.c index eb194c3..a91f639 100644 --- a/Core/Src/spi.c +++ b/Core/Src/spi.c @@ -28,6 +28,7 @@ SPI_HandleTypeDef hspi1; SPI_HandleTypeDef hspi2; SPI_HandleTypeDef hspi3; DMA_HandleTypeDef hdma_spi1_rx; +DMA_HandleTypeDef hdma_spi1_tx; DMA_HandleTypeDef hdma_spi2_rx; DMA_HandleTypeDef hdma_spi3_rx; @@ -45,7 +46,7 @@ void MX_SPI1_Init(void) hspi1.Instance = SPI1; hspi1.Init.Mode = SPI_MODE_MASTER; hspi1.Init.Direction = SPI_DIRECTION_2LINES; - hspi1.Init.DataSize = SPI_DATASIZE_8BIT; + hspi1.Init.DataSize = SPI_DATASIZE_16BIT; hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; hspi1.Init.NSS = SPI_NSS_SOFT; @@ -77,7 +78,7 @@ void MX_SPI2_Init(void) hspi2.Instance = SPI2; hspi2.Init.Mode = SPI_MODE_SLAVE; hspi2.Init.Direction = SPI_DIRECTION_2LINES_RXONLY; - hspi2.Init.DataSize = SPI_DATASIZE_8BIT; + hspi2.Init.DataSize = SPI_DATASIZE_16BIT; hspi2.Init.CLKPolarity = SPI_POLARITY_LOW; hspi2.Init.CLKPhase = SPI_PHASE_1EDGE; hspi2.Init.NSS = SPI_NSS_SOFT; @@ -108,7 +109,7 @@ void MX_SPI3_Init(void) hspi3.Instance = SPI3; hspi3.Init.Mode = SPI_MODE_SLAVE; hspi3.Init.Direction = SPI_DIRECTION_2LINES_RXONLY; - hspi3.Init.DataSize = SPI_DATASIZE_8BIT; + hspi3.Init.DataSize = SPI_DATASIZE_16BIT; hspi3.Init.CLKPolarity = SPI_POLARITY_LOW; hspi3.Init.CLKPhase = SPI_PHASE_1EDGE; hspi3.Init.NSS = SPI_NSS_SOFT; @@ -158,10 +159,10 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle) hdma_spi1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_spi1_rx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_spi1_rx.Init.MemInc = DMA_MINC_ENABLE; - hdma_spi1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; - hdma_spi1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_spi1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; + hdma_spi1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; hdma_spi1_rx.Init.Mode = DMA_NORMAL; - hdma_spi1_rx.Init.Priority = DMA_PRIORITY_LOW; + hdma_spi1_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH; hdma_spi1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; if (HAL_DMA_Init(&hdma_spi1_rx) != HAL_OK) { @@ -170,6 +171,24 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle) __HAL_LINKDMA(spiHandle,hdmarx,hdma_spi1_rx); + /* SPI1_TX Init */ + hdma_spi1_tx.Instance = DMA2_Stream5; + hdma_spi1_tx.Init.Channel = DMA_CHANNEL_3; + hdma_spi1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; + hdma_spi1_tx.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_spi1_tx.Init.MemInc = DMA_MINC_ENABLE; + hdma_spi1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; + hdma_spi1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; + hdma_spi1_tx.Init.Mode = DMA_NORMAL; + hdma_spi1_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH; + hdma_spi1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + if (HAL_DMA_Init(&hdma_spi1_tx) != HAL_OK) + { + Error_Handler(); + } + + __HAL_LINKDMA(spiHandle,hdmatx,hdma_spi1_tx); + /* USER CODE BEGIN SPI1_MspInit 1 */ /* USER CODE END SPI1_MspInit 1 */ @@ -201,10 +220,10 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle) hdma_spi2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_spi2_rx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_spi2_rx.Init.MemInc = DMA_MINC_ENABLE; - hdma_spi2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; - hdma_spi2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_spi2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; + hdma_spi2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; hdma_spi2_rx.Init.Mode = DMA_NORMAL; - hdma_spi2_rx.Init.Priority = DMA_PRIORITY_LOW; + hdma_spi2_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH; hdma_spi2_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; if (HAL_DMA_Init(&hdma_spi2_rx) != HAL_OK) { @@ -244,10 +263,10 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle) hdma_spi3_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_spi3_rx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_spi3_rx.Init.MemInc = DMA_MINC_ENABLE; - hdma_spi3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; - hdma_spi3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_spi3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; + hdma_spi3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; hdma_spi3_rx.Init.Mode = DMA_NORMAL; - hdma_spi3_rx.Init.Priority = DMA_PRIORITY_LOW; + hdma_spi3_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH; hdma_spi3_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; if (HAL_DMA_Init(&hdma_spi3_rx) != HAL_OK) { @@ -282,6 +301,7 @@ void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle) /* SPI1 DMA DeInit */ HAL_DMA_DeInit(spiHandle->hdmarx); + HAL_DMA_DeInit(spiHandle->hdmatx); /* USER CODE BEGIN SPI1_MspDeInit 1 */ /* USER CODE END SPI1_MspDeInit 1 */ diff --git a/Core/Src/stm32f4xx_it.c b/Core/Src/stm32f4xx_it.c index 5cefb89..51eddad 100644 --- a/Core/Src/stm32f4xx_it.c +++ b/Core/Src/stm32f4xx_it.c @@ -62,10 +62,12 @@ extern DMA_HandleTypeDef hdma_sdio_rx; extern DMA_HandleTypeDef hdma_sdio_tx; extern SD_HandleTypeDef hsd; extern DMA_HandleTypeDef hdma_spi1_rx; +extern DMA_HandleTypeDef hdma_spi1_tx; extern DMA_HandleTypeDef hdma_spi2_rx; extern DMA_HandleTypeDef hdma_spi3_rx; extern TIM_HandleTypeDef htim2; extern DMA_HandleTypeDef hdma_usart1_tx; +extern UART_HandleTypeDef huart1; /* USER CODE BEGIN EV */ extern SPI_HandleTypeDef hspi1; extern SPI_HandleTypeDef hspi2; @@ -267,6 +269,20 @@ void TIM2_IRQHandler(void) /* USER CODE END TIM2_IRQn 1 */ } +/** + * @brief This function handles USART1 global interrupt. + */ +void USART1_IRQHandler(void) +{ + /* USER CODE BEGIN USART1_IRQn 0 */ + + /* USER CODE END USART1_IRQn 0 */ + HAL_UART_IRQHandler(&huart1); + /* USER CODE BEGIN USART1_IRQn 1 */ + + /* USER CODE END USART1_IRQn 1 */ +} + /** * @brief This function handles SDIO global interrupt. */ @@ -323,6 +339,20 @@ void OTG_FS_IRQHandler(void) /* USER CODE END OTG_FS_IRQn 1 */ } +/** + * @brief This function handles DMA2 stream5 global interrupt. + */ +void DMA2_Stream5_IRQHandler(void) +{ + /* USER CODE BEGIN DMA2_Stream5_IRQn 0 */ + + /* USER CODE END DMA2_Stream5_IRQn 0 */ + HAL_DMA_IRQHandler(&hdma_spi1_tx); + /* USER CODE BEGIN DMA2_Stream5_IRQn 1 */ + + /* USER CODE END DMA2_Stream5_IRQn 1 */ +} + /** * @brief This function handles DMA2 stream6 global interrupt. */ diff --git a/Core/Src/tim.c b/Core/Src/tim.c index 23c6a23..c2c6646 100644 --- a/Core/Src/tim.c +++ b/Core/Src/tim.c @@ -24,79 +24,8 @@ /* USER CODE END 0 */ -TIM_HandleTypeDef htim1; TIM_HandleTypeDef htim2; -/* TIM1 init function */ -void MX_TIM1_Init(void) -{ - - /* USER CODE BEGIN TIM1_Init 0 */ - - /* USER CODE END TIM1_Init 0 */ - - TIM_ClockConfigTypeDef sClockSourceConfig = {0}; - TIM_MasterConfigTypeDef sMasterConfig = {0}; - TIM_OC_InitTypeDef sConfigOC = {0}; - TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0}; - - /* USER CODE BEGIN TIM1_Init 1 */ - - /* USER CODE END TIM1_Init 1 */ - htim1.Instance = TIM1; - htim1.Init.Prescaler = 0; - htim1.Init.CounterMode = TIM_COUNTERMODE_UP; - htim1.Init.Period = 83; - htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; - htim1.Init.RepetitionCounter = 0; - htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; - if (HAL_TIM_Base_Init(&htim1) != HAL_OK) - { - Error_Handler(); - } - sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; - if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) - { - Error_Handler(); - } - if (HAL_TIM_PWM_Init(&htim1) != HAL_OK) - { - Error_Handler(); - } - sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; - sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; - if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) - { - Error_Handler(); - } - sConfigOC.OCMode = TIM_OCMODE_PWM1; - sConfigOC.Pulse = 0; - sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; - sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH; - sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; - sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET; - sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET; - if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) - { - Error_Handler(); - } - sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE; - sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE; - sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF; - sBreakDeadTimeConfig.DeadTime = 0; - sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE; - sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH; - sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE; - if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK) - { - Error_Handler(); - } - /* USER CODE BEGIN TIM1_Init 2 */ - - /* USER CODE END TIM1_Init 2 */ - HAL_TIM_MspPostInit(&htim1); - -} /* TIM2 init function */ void MX_TIM2_Init(void) { @@ -141,18 +70,7 @@ void MX_TIM2_Init(void) void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle) { - if(tim_baseHandle->Instance==TIM1) - { - /* USER CODE BEGIN TIM1_MspInit 0 */ - - /* USER CODE END TIM1_MspInit 0 */ - /* TIM1 clock enable */ - __HAL_RCC_TIM1_CLK_ENABLE(); - /* USER CODE BEGIN TIM1_MspInit 1 */ - - /* USER CODE END TIM1_MspInit 1 */ - } - else if(tim_baseHandle->Instance==TIM2) + if(tim_baseHandle->Instance==TIM2) { /* USER CODE BEGIN TIM2_MspInit 0 */ @@ -161,56 +79,18 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle) __HAL_RCC_TIM2_CLK_ENABLE(); /* TIM2 interrupt Init */ - HAL_NVIC_SetPriority(TIM2_IRQn, 3, 0); + HAL_NVIC_SetPriority(TIM2_IRQn, 12, 0); HAL_NVIC_EnableIRQ(TIM2_IRQn); /* USER CODE BEGIN TIM2_MspInit 1 */ /* USER CODE END TIM2_MspInit 1 */ } } -void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle) -{ - - GPIO_InitTypeDef GPIO_InitStruct = {0}; - if(timHandle->Instance==TIM1) - { - /* USER CODE BEGIN TIM1_MspPostInit 0 */ - - /* USER CODE END TIM1_MspPostInit 0 */ - - __HAL_RCC_GPIOA_CLK_ENABLE(); - /**TIM1 GPIO Configuration - PA8 ------> TIM1_CH1 - */ - GPIO_InitStruct.Pin = GPIO_PIN_8; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Alternate = GPIO_AF1_TIM1; - HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); - - /* USER CODE BEGIN TIM1_MspPostInit 1 */ - - /* USER CODE END TIM1_MspPostInit 1 */ - } - -} void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle) { - if(tim_baseHandle->Instance==TIM1) - { - /* USER CODE BEGIN TIM1_MspDeInit 0 */ - - /* USER CODE END TIM1_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_TIM1_CLK_DISABLE(); - /* USER CODE BEGIN TIM1_MspDeInit 1 */ - - /* USER CODE END TIM1_MspDeInit 1 */ - } - else if(tim_baseHandle->Instance==TIM2) + if(tim_baseHandle->Instance==TIM2) { /* USER CODE BEGIN TIM2_MspDeInit 0 */ diff --git a/Core/Src/usart.c b/Core/Src/usart.c index f899aad..7cc2534 100644 --- a/Core/Src/usart.c +++ b/Core/Src/usart.c @@ -41,7 +41,7 @@ void MX_USART1_UART_Init(void) /* USER CODE END USART1_Init 1 */ huart1.Instance = USART1; - huart1.Init.BaudRate = 115200; + huart1.Init.BaudRate = 2000000; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; @@ -70,7 +70,7 @@ void MX_USART3_UART_Init(void) /* USER CODE END USART3_Init 1 */ huart3.Instance = USART3; - huart3.Init.BaudRate = 115200; + huart3.Init.BaudRate = 921600; huart3.Init.WordLength = UART_WORDLENGTH_8B; huart3.Init.StopBits = UART_STOPBITS_1; huart3.Init.Parity = UART_PARITY_NONE; @@ -130,6 +130,9 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) __HAL_LINKDMA(uartHandle,hdmatx,hdma_usart1_tx); + /* USART1 interrupt Init */ + HAL_NVIC_SetPriority(USART1_IRQn, 6, 0); + HAL_NVIC_EnableIRQ(USART1_IRQn); /* USER CODE BEGIN USART1_MspInit 1 */ /* USER CODE END USART1_MspInit 1 */ @@ -179,6 +182,9 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle) /* USART1 DMA DeInit */ HAL_DMA_DeInit(uartHandle->hdmatx); + + /* USART1 interrupt Deinit */ + HAL_NVIC_DisableIRQ(USART1_IRQn); /* USER CODE BEGIN USART1_MspDeInit 1 */ /* USER CODE END USART1_MspDeInit 1 */ diff --git a/STM_ATEM_F405.ioc b/STM_ATEM_F405.ioc index f7f64db..6010634 100644 --- a/STM_ATEM_F405.ioc +++ b/STM_ATEM_F405.ioc @@ -8,7 +8,8 @@ Dma.Request2=SPI3_RX Dma.Request3=SDIO_RX Dma.Request4=SDIO_TX Dma.Request5=USART1_TX -Dma.RequestsNb=6 +Dma.Request6=SPI1_TX +Dma.RequestsNb=7 Dma.SDIO_RX.3.Direction=DMA_PERIPH_TO_MEMORY Dma.SDIO_RX.3.FIFOMode=DMA_FIFOMODE_ENABLE Dma.SDIO_RX.3.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL @@ -38,32 +39,42 @@ Dma.SDIO_TX.4.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAl Dma.SPI1_RX.0.Direction=DMA_PERIPH_TO_MEMORY Dma.SPI1_RX.0.FIFOMode=DMA_FIFOMODE_DISABLE Dma.SPI1_RX.0.Instance=DMA2_Stream0 -Dma.SPI1_RX.0.MemDataAlignment=DMA_MDATAALIGN_BYTE +Dma.SPI1_RX.0.MemDataAlignment=DMA_MDATAALIGN_HALFWORD Dma.SPI1_RX.0.MemInc=DMA_MINC_ENABLE Dma.SPI1_RX.0.Mode=DMA_NORMAL -Dma.SPI1_RX.0.PeriphDataAlignment=DMA_PDATAALIGN_BYTE +Dma.SPI1_RX.0.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD Dma.SPI1_RX.0.PeriphInc=DMA_PINC_DISABLE -Dma.SPI1_RX.0.Priority=DMA_PRIORITY_LOW +Dma.SPI1_RX.0.Priority=DMA_PRIORITY_VERY_HIGH Dma.SPI1_RX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode +Dma.SPI1_TX.6.Direction=DMA_MEMORY_TO_PERIPH +Dma.SPI1_TX.6.FIFOMode=DMA_FIFOMODE_DISABLE +Dma.SPI1_TX.6.Instance=DMA2_Stream5 +Dma.SPI1_TX.6.MemDataAlignment=DMA_MDATAALIGN_HALFWORD +Dma.SPI1_TX.6.MemInc=DMA_MINC_ENABLE +Dma.SPI1_TX.6.Mode=DMA_NORMAL +Dma.SPI1_TX.6.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD +Dma.SPI1_TX.6.PeriphInc=DMA_PINC_DISABLE +Dma.SPI1_TX.6.Priority=DMA_PRIORITY_VERY_HIGH +Dma.SPI1_TX.6.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode Dma.SPI2_RX.1.Direction=DMA_PERIPH_TO_MEMORY Dma.SPI2_RX.1.FIFOMode=DMA_FIFOMODE_DISABLE Dma.SPI2_RX.1.Instance=DMA1_Stream3 -Dma.SPI2_RX.1.MemDataAlignment=DMA_MDATAALIGN_BYTE +Dma.SPI2_RX.1.MemDataAlignment=DMA_MDATAALIGN_HALFWORD Dma.SPI2_RX.1.MemInc=DMA_MINC_ENABLE Dma.SPI2_RX.1.Mode=DMA_NORMAL -Dma.SPI2_RX.1.PeriphDataAlignment=DMA_PDATAALIGN_BYTE +Dma.SPI2_RX.1.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD Dma.SPI2_RX.1.PeriphInc=DMA_PINC_DISABLE -Dma.SPI2_RX.1.Priority=DMA_PRIORITY_LOW +Dma.SPI2_RX.1.Priority=DMA_PRIORITY_VERY_HIGH Dma.SPI2_RX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode Dma.SPI3_RX.2.Direction=DMA_PERIPH_TO_MEMORY Dma.SPI3_RX.2.FIFOMode=DMA_FIFOMODE_DISABLE Dma.SPI3_RX.2.Instance=DMA1_Stream0 -Dma.SPI3_RX.2.MemDataAlignment=DMA_MDATAALIGN_BYTE +Dma.SPI3_RX.2.MemDataAlignment=DMA_MDATAALIGN_HALFWORD Dma.SPI3_RX.2.MemInc=DMA_MINC_ENABLE Dma.SPI3_RX.2.Mode=DMA_NORMAL -Dma.SPI3_RX.2.PeriphDataAlignment=DMA_PDATAALIGN_BYTE +Dma.SPI3_RX.2.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD Dma.SPI3_RX.2.PeriphInc=DMA_PINC_DISABLE -Dma.SPI3_RX.2.Priority=DMA_PRIORITY_LOW +Dma.SPI3_RX.2.Priority=DMA_PRIORITY_VERY_HIGH Dma.SPI3_RX.2.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode Dma.USART1_TX.5.Direction=DMA_MEMORY_TO_PERIPH Dma.USART1_TX.5.FIFOMode=DMA_FIFOMODE_DISABLE @@ -98,11 +109,10 @@ Mcu.CPN=STM32F405RGT6 Mcu.Family=STM32F4 Mcu.IP0=DMA Mcu.IP1=FATFS -Mcu.IP10=TIM2 -Mcu.IP11=USART1 -Mcu.IP12=USART3 -Mcu.IP13=USB_DEVICE -Mcu.IP14=USB_OTG_FS +Mcu.IP10=USART1 +Mcu.IP11=USART3 +Mcu.IP12=USB_DEVICE +Mcu.IP13=USB_OTG_FS Mcu.IP2=NVIC Mcu.IP3=RCC Mcu.IP4=SDIO @@ -110,8 +120,8 @@ Mcu.IP5=SPI1 Mcu.IP6=SPI2 Mcu.IP7=SPI3 Mcu.IP8=SYS -Mcu.IP9=TIM1 -Mcu.IPNb=15 +Mcu.IP9=TIM2 +Mcu.IPNb=14 Mcu.Name=STM32F405RGTx Mcu.Package=LQFP64 Mcu.Pin0=PH0-OSC_IN @@ -138,16 +148,15 @@ Mcu.Pin27=PB5 Mcu.Pin28=VP_FATFS_VS_SDIO Mcu.Pin29=VP_SYS_VS_Systick Mcu.Pin3=PA1 -Mcu.Pin30=VP_TIM1_VS_ClockSourceINT -Mcu.Pin31=VP_TIM2_VS_ClockSourceINT -Mcu.Pin32=VP_USB_DEVICE_VS_USB_DEVICE_MSC_FS +Mcu.Pin30=VP_TIM2_VS_ClockSourceINT +Mcu.Pin31=VP_USB_DEVICE_VS_USB_DEVICE_MSC_FS Mcu.Pin4=PA2 Mcu.Pin5=PA5 Mcu.Pin6=PA6 Mcu.Pin7=PA7 Mcu.Pin8=PB10 Mcu.Pin9=PB11 -Mcu.PinsNb=33 +Mcu.PinsNb=32 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32F405RGTx @@ -158,6 +167,7 @@ NVIC.DMA1_Stream0_IRQn=true\:5\:0\:true\:false\:true\:false\:true\:true NVIC.DMA1_Stream3_IRQn=true\:5\:0\:true\:false\:true\:false\:true\:true NVIC.DMA2_Stream0_IRQn=true\:5\:0\:true\:false\:true\:false\:true\:true NVIC.DMA2_Stream3_IRQn=true\:10\:0\:true\:false\:true\:false\:true\:true +NVIC.DMA2_Stream5_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true NVIC.DMA2_Stream6_IRQn=true\:10\:0\:true\:false\:true\:false\:true\:true NVIC.DMA2_Stream7_IRQn=true\:12\:0\:true\:false\:true\:false\:true\:true NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false @@ -172,7 +182,8 @@ NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 NVIC.SDIO_IRQn=true\:9\:0\:true\:false\:true\:true\:true\:true NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.SysTick_IRQn=true\:0\:0\:true\:false\:true\:false\:true\:false -NVIC.TIM2_IRQn=true\:3\:0\:true\:false\:true\:true\:true\:true +NVIC.TIM2_IRQn=true\:12\:0\:true\:false\:true\:true\:true\:true +NVIC.USART1_IRQn=true\:6\:0\:true\:false\:true\:true\:true\:true NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false PA1.GPIOParameters=GPIO_Label PA1.GPIO_Label=ADC_DRY @@ -198,7 +209,8 @@ PA6.Mode=Full_Duplex_Master PA6.Signal=SPI1_MISO PA7.Mode=Full_Duplex_Master PA7.Signal=SPI1_MOSI -PA8.Signal=S_TIM1_CH1 +PA8.Locked=true +PA8.Signal=GPIO_Output PA9.Mode=Asynchronous PA9.Signal=USART1_TX PB10.Locked=true @@ -285,7 +297,7 @@ ProjectManager.ToolChainLocation= ProjectManager.UAScriptAfterPath= ProjectManager.UAScriptBeforePath= ProjectManager.UnderRoot=true -ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_SDIO_SD_Init-SDIO-false-HAL-true,5-MX_SPI1_Init-SPI1-false-HAL-true,6-MX_SPI2_Init-SPI2-false-HAL-true,7-MX_SPI3_Init-SPI3-false-HAL-true,8-MX_TIM1_Init-TIM1-false-HAL-true,9-MX_USART1_UART_Init-USART1-false-HAL-true,10-MX_FATFS_Init-FATFS-false-HAL-false,11-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL-false,12-MX_USART3_UART_Init-USART3-false-HAL-true,13-MX_TIM2_Init-TIM2-false-HAL-true +ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_SDIO_SD_Init-SDIO-false-HAL-true,5-MX_SPI1_Init-SPI1-false-HAL-true,6-MX_SPI2_Init-SPI2-false-HAL-true,7-MX_SPI3_Init-SPI3-false-HAL-true,8-MX_USART1_UART_Init-USART1-false-HAL-true,9-MX_FATFS_Init-FATFS-false-HAL-false,10-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL-false,11-MX_USART3_UART_Init-USART3-false-HAL-true,12-MX_TIM2_Init-TIM2-false-HAL-true RCC.48MHZClocksFreq_Value=48000000 RCC.AHBFreq_Value=168000000 RCC.APB1CLKDivider=RCC_HCLK_DIV4 @@ -324,31 +336,31 @@ SDIO.HardwareFlowControl=SDIO_HARDWARE_FLOW_CONTROL_DISABLE SDIO.IPParameters=ClockDiv,HardwareFlowControl SH.GPXTI1.0=GPIO_EXTI1 SH.GPXTI1.ConfNb=1 -SH.S_TIM1_CH1.0=TIM1_CH1,PWM Generation1 CH1 -SH.S_TIM1_CH1.ConfNb=1 SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_4 SPI1.CalculateBaudRate=21.0 MBits/s +SPI1.DataSize=SPI_DATASIZE_16BIT SPI1.Direction=SPI_DIRECTION_2LINES -SPI1.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,BaudRatePrescaler +SPI1.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,BaudRatePrescaler,DataSize SPI1.Mode=SPI_MODE_MASTER SPI1.VirtualType=VM_MASTER +SPI2.DataSize=SPI_DATASIZE_16BIT SPI2.Direction=SPI_DIRECTION_2LINES_RXONLY -SPI2.IPParameters=VirtualType,Mode,Direction +SPI2.IPParameters=VirtualType,Mode,Direction,DataSize SPI2.Mode=SPI_MODE_SLAVE SPI2.VirtualType=VM_SLAVE +SPI3.DataSize=SPI_DATASIZE_16BIT SPI3.Direction=SPI_DIRECTION_2LINES_RXONLY -SPI3.IPParameters=VirtualType,Mode,Direction +SPI3.IPParameters=VirtualType,Mode,Direction,DataSize SPI3.Mode=SPI_MODE_SLAVE SPI3.VirtualType=VM_SLAVE -TIM1.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1 -TIM1.IPParameters=Channel-PWM Generation1 CH1,Period -TIM1.Period=83 TIM2.IPParameters=Prescaler,Period TIM2.Period=999 TIM2.Prescaler=83 -USART1.IPParameters=VirtualMode +USART1.BaudRate=2000000 +USART1.IPParameters=VirtualMode,BaudRate USART1.VirtualMode=VM_ASYNC -USART3.IPParameters=VirtualMode +USART3.BaudRate=921600 +USART3.IPParameters=VirtualMode,BaudRate USART3.VirtualMode=VM_ASYNC USB_DEVICE.CLASS_NAME_FS=MSC USB_DEVICE.IPParameters=VirtualMode-MSC_FS,VirtualModeFS,CLASS_NAME_FS,MSC_MEDIA_PACKET-MSC_FS @@ -361,8 +373,6 @@ VP_FATFS_VS_SDIO.Mode=SDIO VP_FATFS_VS_SDIO.Signal=FATFS_VS_SDIO VP_SYS_VS_Systick.Mode=SysTick VP_SYS_VS_Systick.Signal=SYS_VS_Systick -VP_TIM1_VS_ClockSourceINT.Mode=Internal -VP_TIM1_VS_ClockSourceINT.Signal=TIM1_VS_ClockSourceINT VP_TIM2_VS_ClockSourceINT.Mode=Internal VP_TIM2_VS_ClockSourceINT.Signal=TIM2_VS_ClockSourceINT VP_USB_DEVICE_VS_USB_DEVICE_MSC_FS.Mode=MSC_FS diff --git a/USB_DEVICE/App/usbd_storage_if.c b/USB_DEVICE/App/usbd_storage_if.c index 7fdcc37..d0cddcc 100644 --- a/USB_DEVICE/App/usbd_storage_if.c +++ b/USB_DEVICE/App/usbd_storage_if.c @@ -332,7 +332,7 @@ int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t b { if((HAL_GetTick() - tickstart) > timeout) return USBD_FAIL; } - + return (USBD_OK); /* USER CODE END 7 */ } diff --git a/User/SystemMonitor_Simplification_Notes.md b/User/SystemMonitor_Simplification_Notes.md new file mode 100644 index 0000000..5b6c39f --- /dev/null +++ b/User/SystemMonitor_Simplification_Notes.md @@ -0,0 +1,130 @@ +# SystemMonitor 简化说明 + +## 简化目标 + +为了提高系统性能,将SystemMonitor模块从复杂的状态机和多种错误类型简化为只统计两个关键指标: +1. **采样样点数** - 记录总共采集的样本数量 +2. **数据溢出次数** - 记录数据来不及处理的次数 + +## 简化前后对比 + +### 简化前的结构 + +```c +typedef struct { + SystemState_t current_state; // 系统状态 + SystemError_t last_error; // 最后错误 + uint32_t uptime_seconds; // 运行时间 + uint32_t total_samples; // 总样本数 + uint32_t error_count; // 错误计数 + uint32_t memory_usage; // 内存使用 + uint8_t cpu_usage_percent; // CPU使用率 + uint8_t temperature_celsius; // 温度 +} SystemMonitorStats_t; +``` + +包含多个函数: +- `SystemMonitor_SetState()` - 设置系统状态 +- `SystemMonitor_ReportError()` - 报告各种错误 +- `SystemMonitor_Update()` - 定期更新统计 +- `SystemMonitor_IsHealthy()` - 健康检查 + +### 简化后的结构 + +```c +typedef struct { + uint32_t total_samples; // 总采样样点数 + uint32_t data_overflow_count; // 数据来不及处理的次数 +} SystemMonitorStats_t; +``` + +只保留3个核心函数: +- [`SystemMonitor_Init()`](User/system_monitor.h:14) - 初始化 +- [`SystemMonitor_IncrementSampleCount()`](User/system_monitor.h:15) - 增加采样计数 +- [`SystemMonitor_ReportDataOverflow()`](User/system_monitor.h:16) - 报告数据溢出 +- [`SystemMonitor_GetStats()`](User/system_monitor.h:17) - 获取统计信息 + +## 使用方式 + +### 1. 初始化 + +在系统启动时调用: +```c +#if ENABLE_SYSTEM_MONITOR + SystemMonitor_Init(); +#endif +``` + +### 2. 采样计数 + +在 [`ProcessAdcData()`](Core/Src/main.c:146) 中,每处理一个样本时调用: +```c +#if ENABLE_SYSTEM_MONITOR + SystemMonitor_IncrementSampleCount(); +#endif +``` + +### 3. 数据溢出报告 + +当检测到数据来不及处理时(缓冲区无可用数据但应该有数据): +```c +} else { + // 数据来不及处理 +#if ENABLE_SYSTEM_MONITOR + SystemMonitor_ReportDataOverflow(); +#endif +} +``` + +### 4. 查看统计信息 + +通过调试输出查看: +```c +SystemMonitorStats_t sys_stats; +SystemMonitor_GetStats(&sys_stats); + +snprintf(buffer, sizeof(buffer), + "\r\n=== System Stats ===\r\n" + "Total Samples: %lu\r\n" + "Data Overflow: %lu\r\n", + sys_stats.total_samples, + sys_stats.data_overflow_count); +``` + +## 性能优势 + +1. **减少函数调用开销** - 从多个状态设置和错误报告函数简化为2个简单的计数器操作 +2. **减少内存占用** - 统计结构从8个字段减少到2个字段 +3. **消除复杂逻辑** - 移除状态机、健康检查等复杂逻辑 +4. **提高实时性** - 减少中断和关键路径中的处理时间 + +## 关键指标说明 + +### total_samples(总采样样点数) +- 每成功处理一个ADC样本时递增 +- 用于监控系统采样率和运行状态 +- 可以计算实际采样率:`samples / uptime` + +### data_overflow_count(数据溢出次数) +- 当数据处理速度跟不上采样速度时递增 +- 表示数据丢失或处理延迟的情况 +- 理想情况下应该为0或非常小的值 + +## 调试输出示例 + +``` +=== System Stats === +Total Samples: 40000 +Data Overflow: 0 +``` + +这表示系统已采集40000个样本,没有发生数据溢出,系统运行正常。 + +如果看到: +``` +=== System Stats === +Total Samples: 40000 +Data Overflow: 150 +``` + +说明有150次数据来不及处理,需要优化数据处理流程或降低采样率。 diff --git a/User/correction.c b/User/correction.c index 21581ca..201de90 100644 --- a/User/correction.c +++ b/User/correction.c @@ -21,9 +21,9 @@ void Init_CorrectionParams(CorrectionParams_t *params) // 初始化为单位矩阵 memset(params->correction_matrix, 0, sizeof(params->correction_matrix)); - params->correction_matrix[0] = 1.0f; // [0,0] - params->correction_matrix[4] = 1.0f; // [1,1] - params->correction_matrix[8] = 1.0f; // [2,2] + params->correction_matrix[0] = 5.0f / 0x7FFFFFFF; // [0,0] + params->correction_matrix[4] = 5.0f / 0x7FFFFFFF; // [1,1] + params->correction_matrix[8] = 5.0f / 0x7FFFFFFF; // [2,2] #if USE_ARM_DSP // 初始化ARM DSP矩阵实例 (3x3矩阵) diff --git a/User/data_packet.c b/User/data_packet.c index 0970258..ae776e8 100644 --- a/User/data_packet.c +++ b/User/data_packet.c @@ -34,9 +34,9 @@ void PackData(DataPacket_t *packet, int32_t adc1, int32_t adc2, int32_t adc3) packet->adc_data3 = adc3; // 计算校验和 (不包括校验和字段本身和包尾) - uint16_t checksum = Calculate_CRC16((uint8_t*)packet, - sizeof(DataPacket_t) - sizeof(packet->checksum) - sizeof(packet->end_byte)); - packet->checksum = checksum; + uint16_t checksum = Calculate_CRC16((uint8_t*)packet, + sizeof(DataPacket_t) - sizeof(packet->checksum) - sizeof(packet->end_byte)); + packet->checksum = checksum; // 设置包尾 packet->end_byte = PACKET_END_BYTE; @@ -96,9 +96,9 @@ void PackCorrectedData(CorrectedDataPacket_t *packet, float x, float y, float z) packet->corrected_z = z; // 计算校验和 - uint16_t checksum = Calculate_CRC16((uint8_t*)packet, - sizeof(CorrectedDataPacket_t) - sizeof(packet->checksum) - sizeof(packet->end_byte)); - packet->checksum = checksum; + uint16_t checksum = Calculate_CRC16((uint8_t*)packet, + sizeof(CorrectedDataPacket_t) - sizeof(packet->checksum) - sizeof(packet->end_byte)); + packet->checksum = checksum; // 设置包尾 packet->end_byte = PACKET_END_BYTE; diff --git a/User/data_storage.c b/User/data_storage.c index 6edc051..fd15d01 100644 --- a/User/data_storage.c +++ b/User/data_storage.c @@ -109,14 +109,14 @@ HAL_StatusTypeDef DataStorage_WriteData(DataStorageHandle_t *handle, const DataP } /** - * @brief 写入校正后的数据到存储 + * @brief 写入校正后的数据包到存储 * @param handle: 数据存储句柄指针 - * @param result: 校正结果指针 + * @param packet: 数据包指针 * @retval HAL_StatusTypeDef */ -HAL_StatusTypeDef DataStorage_WriteCorrectedData(DataStorageHandle_t *handle, const CorrectionResult_t *result) +HAL_StatusTypeDef DataStorage_WriteCorrectedData(DataStorageHandle_t *handle, const CorrectedDataPacket_t *packet) { - if (handle == NULL || result == NULL || !handle->initialized) { + if (handle == NULL || packet == NULL || !handle->initialized) { return HAL_ERROR; } @@ -127,7 +127,7 @@ HAL_StatusTypeDef DataStorage_WriteCorrectedData(DataStorageHandle_t *handle, co DataBuffer_t *active_buf = &handle->buffers[handle->active_buffer]; // 检查当前活动缓冲区空间 - if (active_buf->index + sizeof(CorrectionResult_t) > DATA_STORAGE_BUFFER_SIZE) { + if (active_buf->index + sizeof(CorrectedDataPacket_t) > DATA_STORAGE_BUFFER_SIZE) { // 切换缓冲区 if (DataStorage_SwitchBuffer(handle) != HAL_OK) { handle->stats.error_count++; @@ -137,8 +137,8 @@ HAL_StatusTypeDef DataStorage_WriteCorrectedData(DataStorageHandle_t *handle, co } // 复制校正后的数据到活动缓冲区 - memcpy(&active_buf->data[active_buf->index], result, sizeof(CorrectionResult_t)); - active_buf->index += sizeof(CorrectionResult_t); + memcpy(&active_buf->data[active_buf->index], packet, sizeof(CorrectedDataPacket_t)); + active_buf->index += sizeof(CorrectedDataPacket_t); active_buf->state = BUFFER_WRITING; handle->stats.total_samples++; diff --git a/User/data_storage.h b/User/data_storage.h index a42ffae..d452560 100644 --- a/User/data_storage.h +++ b/User/data_storage.h @@ -10,9 +10,9 @@ // 数据存储配置 #define DATA_STORAGE_BUFFER_SIZE 32768 // 缓冲区大小(字节) -#define DATA_STORAGE_FILE_MAX_SIZE (10*1024*1024) // 单个文件最大10MB -#define DATA_STORAGE_PATH "0:/DATA1" // 数据存储路径 -#define DATA_STORAGE_FILE_PREFIX "ADC_DATA_" // 文件名前缀 +#define DATA_STORAGE_FILE_MAX_SIZE (20*1024*1024) // 单个文件最大20MB +#define DATA_STORAGE_PATH "0:/DATA2" // 数据存储路径 +#define DATA_STORAGE_FILE_PREFIX "/ADC_DATA_" // 文件名前缀 // 缓冲区状态 typedef enum { @@ -63,7 +63,7 @@ HAL_StatusTypeDef DataStorage_Init(DataStorageHandle_t *handle); HAL_StatusTypeDef DataStorage_StartRecording(DataStorageHandle_t *handle); HAL_StatusTypeDef DataStorage_StopRecording(DataStorageHandle_t *handle); HAL_StatusTypeDef DataStorage_WriteData(DataStorageHandle_t *handle, const DataPacket_t *packet); -HAL_StatusTypeDef DataStorage_WriteCorrectedData(DataStorageHandle_t *handle, const CorrectionResult_t *result); +HAL_StatusTypeDef DataStorage_WriteCorrectedData(DataStorageHandle_t *handle, const CorrectedDataPacket_t *result); HAL_StatusTypeDef DataStorage_Flush(DataStorageHandle_t *handle); void DataStorage_GetStats(DataStorageHandle_t *handle, DataStorageStats_t *stats); HAL_StatusTypeDef DataStorage_CreateNewFile(DataStorageHandle_t *handle); diff --git a/User/ltc2508_driver.c b/User/ltc2508_driver.c index 0a91e19..8ffe978 100644 --- a/User/ltc2508_driver.c +++ b/User/ltc2508_driver.c @@ -16,6 +16,17 @@ static SPI_HandleTypeDef *g_hspi1 = NULL; static SPI_HandleTypeDef *g_hspi2 = NULL; static SPI_HandleTypeDef *g_hspi3 = NULL; + +/** + * @brief LTC2508 是否初始化 + * @retval 0-未初始化 1-已初始化 + */ +uint32_t LTC2508_IsInited() +{ + return (g_hspi1 != NULL && g_hspi2 != NULL && g_hspi3 != NULL); +} + + /** * @brief 初始化 LTC2508 驱动 * @param hspi1: SPI1 句柄指针 @@ -81,27 +92,27 @@ LTC2508_StatusTypeDef LTC2508_TriggerDmaRead(void) current_buffer->timestamp = HAL_GetTick(); // SPI2 和 SPI3 作为从机只接收 - if (HAL_SPI_Receive_DMA(g_hspi2, (uint8_t*)current_buffer->data[1], LTC2508_DATA_LEN * 2) != HAL_OK) + if (HAL_SPI_Receive_DMA(g_hspi2, (uint8_t*)current_buffer->data[1], LTC2508_DATA_LEN) != HAL_OK) { current_buffer->state = LTC2508_BUFFER_EMPTY; g_ltc2508_stats.dma_error_count++; g_ltc2508_stats.error_count++; g_ltc2508_stats.last_error = LTC2508_ERROR_DMA; - return LTC2508_ERROR_DMA; +// return LTC2508_ERROR_DMA; } - if (HAL_SPI_Receive_DMA(g_hspi3, (uint8_t*)current_buffer->data[2], LTC2508_DATA_LEN * 2) != HAL_OK) + if (HAL_SPI_Receive_DMA(g_hspi3, (uint8_t*)current_buffer->data[2], LTC2508_DATA_LEN) != HAL_OK) { current_buffer->state = LTC2508_BUFFER_EMPTY; g_ltc2508_stats.dma_error_count++; g_ltc2508_stats.error_count++; g_ltc2508_stats.last_error = LTC2508_ERROR_DMA; - return LTC2508_ERROR_DMA; +// return LTC2508_ERROR_DMA; } // SPI1 作为主机收发,先发一个 dummy 数据触发时钟 uint16_t dummy_tx[LTC2508_DATA_LEN] = {0}; // 可以是任意值 - if (HAL_SPI_TransmitReceive_DMA(g_hspi1, (uint8_t*)dummy_tx, (uint8_t*)current_buffer->data[0], LTC2508_DATA_LEN * 2) != HAL_OK) + if (HAL_SPI_TransmitReceive_DMA(g_hspi1, (uint8_t*)dummy_tx, (uint8_t*)current_buffer->data[0], LTC2508_DATA_LEN) != HAL_OK) { current_buffer->state = LTC2508_BUFFER_EMPTY; g_ltc2508_stats.dma_error_count++; diff --git a/User/ltc2508_driver.h b/User/ltc2508_driver.h index 0a6cc0d..701e18b 100644 --- a/User/ltc2508_driver.h +++ b/User/ltc2508_driver.h @@ -10,7 +10,7 @@ #define NUM_LTC2508 3 // 双缓冲区定义 -#define LTC2508_BUFFER_COUNT 64 +#define LTC2508_BUFFER_COUNT 128 // 缓冲区状态定义 typedef enum { @@ -62,6 +62,7 @@ extern volatile uint8_t g_current_read_buffer; extern LTC2508_StatsTypeDef g_ltc2508_stats; // 函数原型 +uint32_t LTC2508_IsInited(); LTC2508_StatusTypeDef LTC2508_Init(SPI_HandleTypeDef *hspi1, SPI_HandleTypeDef *hspi2, SPI_HandleTypeDef *hspi3); LTC2508_StatusTypeDef LTC2508_TriggerDmaRead(void); void LTC2508_DmaComplete_Callback(SPI_HandleTypeDef *hspi); diff --git a/User/performance_monitor.c b/User/performance_monitor.c deleted file mode 100644 index 9c37847..0000000 --- a/User/performance_monitor.c +++ /dev/null @@ -1,193 +0,0 @@ -#include "performance_monitor.h" -#include -#include - -// 静态变量 -static SystemPerfStats_t g_perf_stats = {0}; -static uint32_t g_task_start_time[PERF_MON_MAX_TASKS] = {0}; -static uint8_t g_task_active[PERF_MON_MAX_TASKS] = {0}; - -// 外部符号声明 (用于堆栈监控) -extern uint32_t _estack; -extern uint32_t _Min_Stack_Size; - -/** - * @brief 初始化性能监控模块 - * @param None - * @retval None - */ -void PerformanceMonitor_Init(void) -{ - memset(&g_perf_stats, 0, sizeof(SystemPerfStats_t)); - memset(g_task_start_time, 0, sizeof(g_task_start_time)); - memset(g_task_active, 0, sizeof(g_task_active)); - - g_perf_stats.sample_period_ms = PERF_MON_SAMPLE_PERIOD_MS; - g_perf_stats.last_update_tick = HAL_GetTick(); - - // 初始化最小执行时间为最大值 - for (int i = 0; i < PERF_MON_MAX_TASKS; i++) { - g_perf_stats.tasks[i].min_time_us = UINT32_MAX; - } - -} - -/** - * @brief 开始任务性能监控 - * @param task_id: 任务ID - * @retval None - */ -void PerformanceMonitor_TaskStart(PerfTaskID_t task_id) -{ - if (task_id >= PERF_MON_MAX_TASKS) return; - - g_task_start_time[task_id] = HAL_GetTick() * 1000; // 转换为微秒 - g_task_active[task_id] = 1; -} - -/** - * @brief 结束任务性能监控 - * @param task_id: 任务ID - * @retval None - */ -void PerformanceMonitor_TaskEnd(PerfTaskID_t task_id) -{ - if (task_id >= PERF_MON_MAX_TASKS || !g_task_active[task_id]) return; - - uint32_t end_time = HAL_GetTick() * 1000; // 转换为微秒 - uint32_t execution_time = end_time - g_task_start_time[task_id]; - - TaskPerfStats_t *task_stats = &g_perf_stats.tasks[task_id]; - - // 更新统计信息 - task_stats->total_time_us += execution_time; - task_stats->call_count++; - - // 更新最大最小时间 - if (execution_time > task_stats->max_time_us) { - task_stats->max_time_us = execution_time; - } - if (execution_time < task_stats->min_time_us) { - task_stats->min_time_us = execution_time; - } - - // 计算平均时间 - task_stats->avg_time_us = task_stats->total_time_us / task_stats->call_count; - - g_task_active[task_id] = 0; -} - -/** - * @brief 更新性能监控统计 - * @param None - * @retval None - */ -void PerformanceMonitor_Update(void) -{ - uint32_t current_tick = HAL_GetTick(); - - // 检查是否到了更新周期 - if (current_tick - g_perf_stats.last_update_tick < g_perf_stats.sample_period_ms) { - return; - } - - // 计算CPU使用率 - uint32_t total_cpu_time = 0; - for (int i = 0; i < PERF_MON_MAX_TASKS; i++) { - if (g_perf_stats.tasks[i].call_count > 0) { - // 计算每个任务的CPU使用率 - uint32_t task_time_per_period = g_perf_stats.tasks[i].avg_time_us * - (1000 / g_perf_stats.sample_period_ms); - g_perf_stats.tasks[i].cpu_usage_percent = - (float)task_time_per_period / 10000.0f; // 转换为百分比 - - total_cpu_time += task_time_per_period; - } - } - - // 更新总CPU使用率 - g_perf_stats.total_cpu_usage_percent = total_cpu_time / 100; - - // 更新内存使用情况 - g_perf_stats.free_heap_size = PerformanceMonitor_GetFreeHeapSize(); - if (g_perf_stats.min_free_heap_size == 0 || - g_perf_stats.free_heap_size < g_perf_stats.min_free_heap_size) { - g_perf_stats.min_free_heap_size = g_perf_stats.free_heap_size; - } - - // 更新栈使用率 - g_perf_stats.stack_usage_percent = PerformanceMonitor_GetStackUsage(); - - g_perf_stats.last_update_tick = current_tick; -} - -/** - * @brief 获取性能统计信息 - * @param stats: 统计信息结构体指针 - * @retval None - */ -void PerformanceMonitor_GetStats(SystemPerfStats_t *stats) -{ - if (stats != NULL) { - memcpy(stats, &g_perf_stats, sizeof(SystemPerfStats_t)); - } -} - -/** - * @brief 重置性能统计 - * @param None - * @retval None - */ -void PerformanceMonitor_ResetStats(void) -{ - memset(&g_perf_stats, 0, sizeof(SystemPerfStats_t)); - g_perf_stats.sample_period_ms = PERF_MON_SAMPLE_PERIOD_MS; - g_perf_stats.last_update_tick = HAL_GetTick(); - - // 重新初始化最小执行时间 - for (int i = 0; i < PERF_MON_MAX_TASKS; i++) { - g_perf_stats.tasks[i].min_time_us = UINT32_MAX; - } -} - -/** - * @brief 获取空闲堆内存大小 - * @param None - * @retval 空闲堆内存大小(字节) - */ -uint32_t PerformanceMonitor_GetFreeHeapSize(void) -{ - // 简单的堆内存检测方法 - // 在实际应用中,可能需要更复杂的内存管理 - void *ptr = malloc(1); - if (ptr != NULL) { - free(ptr); - // 这里返回一个估算值,实际项目中需要更精确的实现 - return 32768; // 假设有32KB空闲堆内存 - } - return 0; -} - -/** - * @brief 获取栈使用率 - * @param None - * @retval 栈使用率百分比 - */ -uint32_t PerformanceMonitor_GetStackUsage(void) -{ - // 获取当前栈指针 - uint32_t current_sp; - __asm volatile ("mov %0, sp" : "=r" (current_sp)); - - // 计算栈使用量 - uint32_t stack_top = (uint32_t)&_estack; - uint32_t min_stack_size = (uint32_t)&_Min_Stack_Size; - uint32_t stack_used = stack_top - current_sp; - - // 计算使用率百分比 - if (min_stack_size > 0) { - return (stack_used * 100) / min_stack_size; - } - - return 0; -} \ No newline at end of file diff --git a/User/performance_monitor.h b/User/performance_monitor.h deleted file mode 100644 index f85d9c7..0000000 --- a/User/performance_monitor.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef PERFORMANCE_MONITOR_H -#define PERFORMANCE_MONITOR_H - -#include "main.h" -#include - -// 性能监控配置 -#define PERF_MON_MAX_TASKS 8 -#define PERF_MON_SAMPLE_PERIOD_MS 100 - -// 任务ID定义 -typedef enum { - PERF_TASK_ADC_PROCESSING = 0, - PERF_TASK_CORRECTION, - PERF_TASK_DATA_PACKET, - PERF_TASK_RS485_TX, - PERF_TASK_FATFS_WRITE, - PERF_TASK_USB_PROCESS, - PERF_TASK_SYSTEM_MONITOR, - PERF_TASK_IDLE -} PerfTaskID_t; - -// 任务性能统计 -typedef struct { - uint32_t total_time_us; // 总执行时间(微秒) - uint32_t max_time_us; // 最大执行时间 - uint32_t min_time_us; // 最小执行时间 - uint32_t call_count; // 调用次数 - uint32_t avg_time_us; // 平均执行时间 - float cpu_usage_percent; // CPU使用率百分比 -} TaskPerfStats_t; - -// 系统性能统计 -typedef struct { - TaskPerfStats_t tasks[PERF_MON_MAX_TASKS]; - uint32_t total_cpu_usage_percent; - uint32_t free_heap_size; - uint32_t min_free_heap_size; - uint32_t stack_usage_percent; - uint32_t sample_period_ms; - uint32_t last_update_tick; -} SystemPerfStats_t; - -// 函数声明 -void PerformanceMonitor_Init(void); -void PerformanceMonitor_TaskStart(PerfTaskID_t task_id); -void PerformanceMonitor_TaskEnd(PerfTaskID_t task_id); -void PerformanceMonitor_Update(void); -void PerformanceMonitor_GetStats(SystemPerfStats_t *stats); -void PerformanceMonitor_ResetStats(void); -uint32_t PerformanceMonitor_GetFreeHeapSize(void); -uint32_t PerformanceMonitor_GetStackUsage(void); - -#endif // PERFORMANCE_MONITOR_H \ No newline at end of file diff --git a/User/rs485_driver.c b/User/rs485_driver.c index 282a2c5..4b8cb38 100644 --- a/User/rs485_driver.c +++ b/User/rs485_driver.c @@ -26,9 +26,33 @@ HAL_StatusTypeDef RS485_SendData(uint8_t *pData, uint16_t Size) g_rs485_tx_busy = 1; HAL_GPIO_WritePin(g_de_re_port, g_de_re_pin, GPIO_PIN_SET); // 设置为发送模式 - ret = HAL_UART_Transmit(g_huart_485, pData, Size, 0xffff); - HAL_GPIO_WritePin(g_de_re_port, g_de_re_pin, GPIO_PIN_RESET); // 切换回接收模式 - g_rs485_tx_busy = 0; + ret = HAL_UART_Transmit_IT(g_huart_485, pData, Size); + + // 注意:不能在这里立即切换回接收模式! + // DMA传输是非阻塞的,需要在传输完成回调中切换 + if (ret != HAL_OK) + { + // 如果启动DMA失败,需要清除忙标志并切换回接收模式 + HAL_GPIO_WritePin(g_de_re_port, g_de_re_pin, GPIO_PIN_RESET); + g_rs485_tx_busy = 0; + } + + // 等待数据传输完成 + while(g_rs485_tx_busy) + { + ; + } return ret; } + +// UART DMA传输完成回调函数 +void RS485_TxCpltCallback(UART_HandleTypeDef *huart) +{ + if (huart == g_huart_485) + { + // DMA传输完成后切换回接收模式 + HAL_GPIO_WritePin(g_de_re_port, g_de_re_pin, GPIO_PIN_RESET); + g_rs485_tx_busy = 0; + } +} diff --git a/User/system_monitor.c b/User/system_monitor.c index d00b751..ce14eaf 100644 --- a/User/system_monitor.c +++ b/User/system_monitor.c @@ -3,7 +3,6 @@ // 静态变量 static SystemMonitorStats_t g_system_stats = {0}; -static uint32_t g_last_update_tick = 0; /** * @brief 初始化系统监控模块 @@ -13,71 +12,26 @@ static uint32_t g_last_update_tick = 0; void SystemMonitor_Init(void) { memset(&g_system_stats, 0, sizeof(SystemMonitorStats_t)); - g_system_stats.current_state = SYSTEM_STATE_INIT; - g_last_update_tick = HAL_GetTick(); } /** - * @brief 更新系统监控状态 + * @brief 增加采样样点计数 * @param None * @retval None */ -void SystemMonitor_Update(void) +void SystemMonitor_IncrementSampleCount(void) { - uint32_t current_tick = HAL_GetTick(); - - // 更新运行时间 - if (current_tick >= g_last_update_tick) { - g_system_stats.uptime_seconds = current_tick / 1000; - } - - // 获取LTC2508统计信息 - LTC2508_StatsTypeDef ltc_stats; - LTC2508_GetStats(<c_stats); - g_system_stats.total_samples = ltc_stats.total_samples; - - // 检查ADC错误 - if (ltc_stats.error_count > 0) { - SystemMonitor_ReportError(SYSTEM_ERROR_ADC); - } - - g_last_update_tick = current_tick; + g_system_stats.total_samples++; } /** - * @brief 获取当前系统状态 + * @brief 报告数据处理溢出(数据来不及处理) * @param None - * @retval SystemState_t - */ -SystemState_t SystemMonitor_GetState(void) -{ - return g_system_stats.current_state; -} - -/** - * @brief 设置系统状态 - * @param new_state: 新的系统状态 * @retval None */ -void SystemMonitor_SetState(SystemState_t new_state) +void SystemMonitor_ReportDataOverflow(void) { - g_system_stats.current_state = new_state; -} - -/** - * @brief 报告系统错误 - * @param error: 错误类型 - * @retval None - */ -void SystemMonitor_ReportError(SystemError_t error) -{ - g_system_stats.last_error = error; - g_system_stats.error_count++; - - // 根据错误类型设置系统状态 - if (error == SYSTEM_ERROR_CRITICAL) { - g_system_stats.current_state = SYSTEM_STATE_ERROR; - } + g_system_stats.data_overflow_count++; } /** @@ -91,23 +45,3 @@ void SystemMonitor_GetStats(SystemMonitorStats_t *stats) memcpy(stats, &g_system_stats, sizeof(SystemMonitorStats_t)); } } - -/** - * @brief 检查系统健康状态 - * @param None - * @retval uint8_t: 1-健康, 0-异常 - */ -uint8_t SystemMonitor_IsHealthy(void) -{ - // 检查系统状态 - if (g_system_stats.current_state == SYSTEM_STATE_ERROR) { - return 0; - } - - // 检查错误计数 - if (g_system_stats.error_count > 10) { - return 0; - } - - return 1; // 系统健康 -} \ No newline at end of file diff --git a/User/system_monitor.h b/User/system_monitor.h index b8fcfec..7cd890a 100644 --- a/User/system_monitor.h +++ b/User/system_monitor.h @@ -2,51 +2,18 @@ #define SYSTEM_MONITOR_H #include "main.h" -#include "ltc2508_driver.h" -#include "data_storage.h" #include -// 系统状态定义 -typedef enum { - SYSTEM_STATE_INIT = 0, - SYSTEM_STATE_IDLE, - SYSTEM_STATE_SAMPLING, - SYSTEM_STATE_RECORDING, - SYSTEM_STATE_ERROR, - SYSTEM_STATE_MAINTENANCE, - SYSTEM_STATE_USB_MODE -} SystemState_t; - -// 系统错误类型 -typedef enum { - SYSTEM_ERROR_NONE = 0, - SYSTEM_ERROR_ADC, - SYSTEM_ERROR_STORAGE, - SYSTEM_ERROR_USB, - SYSTEM_ERROR_COMMUNICATION, - SYSTEM_ERROR_MEMORY, - SYSTEM_ERROR_CRITICAL -} SystemError_t; - -// 系统监控统计信息 +// 简化的系统监控统计信息 typedef struct { - SystemState_t current_state; - SystemError_t last_error; - uint32_t uptime_seconds; - uint32_t total_samples; - uint32_t error_count; - uint32_t memory_usage; - uint8_t cpu_usage_percent; - uint8_t temperature_celsius; + uint32_t total_samples; // 总采样样点数 + uint32_t data_overflow_count; // 数据来不及处理的次数 } SystemMonitorStats_t; // 函数声明 void SystemMonitor_Init(void); -void SystemMonitor_Update(void); -SystemState_t SystemMonitor_GetState(void); -void SystemMonitor_SetState(SystemState_t new_state); -void SystemMonitor_ReportError(SystemError_t error); +void SystemMonitor_IncrementSampleCount(void); +void SystemMonitor_ReportDataOverflow(void); void SystemMonitor_GetStats(SystemMonitorStats_t *stats); -uint8_t SystemMonitor_IsHealthy(void); -#endif // SYSTEM_MONITOR_H \ No newline at end of file +#endif // SYSTEM_MONITOR_H