✨ feat(main): 新增usb连接状态检测与自动文件系统管理功能
- 新增usb连接状态检测函数,根据usb连接状态自动切换数据采集模式 - 新增文件系统动态挂载/卸载功能,usb连接时卸载文件系统,断开时重新挂载 - 修改系统启动逻辑,根据初始usb连接状态决定是否开始数据采集 - 新增usb模式系统状态,完善系统状态机 🐛 fix(sdio): 修复sdio配置问题并启用中断 - 修改sdio时钟分频为2,优化sd nand通信时序 - 启用sdio数据线内部上拉电阻,提高信号稳定性 - 提高sdio dma传输优先级至最高,确保数据传输实时性 - 启用sdio全局中断并设置优先级为9 🔧 chore(config): 优化系统配置参数 - 修改系统滴答定时器中断优先级为0(最高优先级) - 增加堆栈大小至0x1000,增加堆大小至0x800 - 修改usb msc媒体数据包大小至32768,提高usb传输效率 - 修改fatfs配置,设置最大最小扇区大小为512字节 ♻️ refactor(usb): 重构usb存储接口实现 - 修改usb存储初始化逻辑,避免重复初始化sd卡 - 优化usb存储容量报告机制,强制报告512字节扇区 - 增加sd nand读写超时等待机制,确保数据传输完成 - 修改usb中断优先级为11,避免与sdio中断冲突 📝 docs(headers): 更新头文件声明 - 在stm32f4xx_it.h中添加sdio中断处理函数声明 - 在system_monitor.h中添加usb模式系统状态定义 - 更新data_storage.h中的数据存储路径配置
This commit is contained in:
parent
4598f8f34f
commit
87bdfa09d9
@ -148,7 +148,7 @@
|
||||
* @brief This is the HAL system configuration section
|
||||
*/
|
||||
#define VDD_VALUE 3300U /*!< Value of VDD in mv */
|
||||
#define TICK_INT_PRIORITY 15U /*!< tick interrupt priority */
|
||||
#define TICK_INT_PRIORITY 0U /*!< tick interrupt priority */
|
||||
#define USE_RTOS 0U
|
||||
#define PREFETCH_ENABLE 1U
|
||||
#define INSTRUCTION_CACHE_ENABLE 1U
|
||||
|
||||
@ -59,6 +59,7 @@ void EXTI1_IRQHandler(void);
|
||||
void DMA1_Stream0_IRQHandler(void);
|
||||
void DMA1_Stream3_IRQHandler(void);
|
||||
void TIM2_IRQHandler(void);
|
||||
void SDIO_IRQHandler(void);
|
||||
void DMA2_Stream0_IRQHandler(void);
|
||||
void DMA2_Stream3_IRQHandler(void);
|
||||
void OTG_FS_IRQHandler(void);
|
||||
|
||||
@ -60,7 +60,7 @@ void MX_GPIO_Init(void)
|
||||
/*Configure GPIO pin : PC3 */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_3;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pin : ADC_DRY_Pin */
|
||||
|
||||
192
Core/Src/main.c
192
Core/Src/main.c
@ -84,6 +84,11 @@ 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;
|
||||
static uint8_t g_fatfs_mounted_for_sampling = 0;
|
||||
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;
|
||||
@ -98,6 +103,12 @@ static void StartRecording(void);
|
||||
static void StopRecording(void);
|
||||
static void ProcessAdcData(void);
|
||||
|
||||
// USB连接状态管理函数
|
||||
static uint8_t CheckUSBConnectionStatus(void);
|
||||
static void HandleUSBConnectionChange(void);
|
||||
static HAL_StatusTypeDef MountFileSystemForSampling(void);
|
||||
static void UnmountFileSystemForSampling(void);
|
||||
|
||||
static void DebugOutput_Init(void);
|
||||
static void DebugOutput_SendString(const char* str);
|
||||
static void DebugOutput_PrintSystemStats(void);
|
||||
@ -396,6 +407,141 @@ static void DebugOutput_PrintPerformanceStats(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 检查USB连接状态
|
||||
* @retval 1: USB已连接, 0: USB未连接
|
||||
*/
|
||||
static uint8_t CheckUSBConnectionStatus(void)
|
||||
{
|
||||
// 通过检查USB设备状态来判断是否连接到PC
|
||||
extern USBD_HandleTypeDef hUsbDeviceFS;
|
||||
|
||||
// 检查USB设备是否已配置(枚举完成)
|
||||
if (hUsbDeviceFS.dev_state == USBD_STATE_CONFIGURED) {
|
||||
return 1; // USB已连接并配置
|
||||
}
|
||||
|
||||
return 0; // USB未连接或未配置
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 处理USB连接状态变化
|
||||
* @retval None
|
||||
*/
|
||||
static void HandleUSBConnectionChange(void)
|
||||
{
|
||||
uint8_t current_usb_status = CheckUSBConnectionStatus();
|
||||
|
||||
if (current_usb_status != g_usb_connected) {
|
||||
g_usb_connected = current_usb_status;
|
||||
|
||||
if (g_usb_connected) {
|
||||
// USB连接:停止数据采集,卸载文件系统用于USB存储
|
||||
DebugOutput_SendString("USB Connected: Stopping data acquisition\r\n");
|
||||
|
||||
// 停止数据记录
|
||||
StopRecording();
|
||||
|
||||
// 卸载用于采样的文件系统
|
||||
UnmountFileSystemForSampling();
|
||||
|
||||
#if ENABLE_SYSTEM_MONITOR
|
||||
SystemMonitor_SetState(SYSTEM_STATE_USB_MODE);
|
||||
#endif
|
||||
} else {
|
||||
// USB断开:重新挂载文件系统,开始数据采集
|
||||
DebugOutput_SendString("USB Disconnected: Starting data acquisition\r\n");
|
||||
|
||||
// 挂载文件系统用于数据采集
|
||||
if (MountFileSystemForSampling() == HAL_OK) {
|
||||
// 重新初始化数据存储
|
||||
if (DataStorage_Init(&g_data_storage) == HAL_OK) {
|
||||
StartRecording();
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLE_SYSTEM_MONITOR
|
||||
SystemMonitor_SetState(SYSTEM_STATE_IDLE);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 为数据采集挂载文件系统
|
||||
* @retval HAL_OK: 成功, HAL_ERROR: 失败
|
||||
*/
|
||||
static HAL_StatusTypeDef MountFileSystemForSampling(void)
|
||||
{
|
||||
extern FATFS SDFatFS;
|
||||
extern char SDPath[4];
|
||||
extern SD_HandleTypeDef hsd;
|
||||
|
||||
if (g_fatfs_mounted_for_sampling) {
|
||||
return HAL_OK; // 已经挂载
|
||||
}
|
||||
|
||||
// 初始化SD卡
|
||||
if (HAL_SD_Init(&hsd) != HAL_OK) {
|
||||
DebugOutput_SendString("SD card init failed\r\n");
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
// FRESULT format_result = f_mkfs(SDPath, FM_FAT32, 0, NULL, 0);
|
||||
|
||||
// 尝试挂载文件系统
|
||||
FRESULT mount_result = f_mount(&SDFatFS, SDPath, 1);
|
||||
|
||||
if (mount_result != FR_OK) {
|
||||
if (mount_result == FR_NO_FILESYSTEM)
|
||||
{
|
||||
DebugOutput_SendString("No filesystem found, formatting...\r\n");
|
||||
|
||||
// 格式化为FAT32
|
||||
FRESULT format_result = f_mkfs(SDPath, FM_FAT32, 0, NULL, 0);
|
||||
|
||||
if (format_result == FR_OK) {
|
||||
DebugOutput_SendString("Format successful, remounting...\r\n");
|
||||
mount_result = f_mount(&SDFatFS, SDPath, 1);
|
||||
if (mount_result != FR_OK) {
|
||||
DebugOutput_SendString("Remount after format failed\r\n");
|
||||
return HAL_ERROR;
|
||||
}
|
||||
} else {
|
||||
DebugOutput_SendString("Format failed\r\n");
|
||||
return HAL_ERROR;
|
||||
}
|
||||
} else {
|
||||
DebugOutput_SendString("Mount failed with other error\r\n");
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
g_fatfs_mounted_for_sampling = 1;
|
||||
DebugOutput_SendString("Filesystem mounted for sampling\r\n");
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 卸载用于数据采集的文件系统
|
||||
* @retval None
|
||||
*/
|
||||
static void UnmountFileSystemForSampling(void)
|
||||
{
|
||||
extern FATFS SDFatFS;
|
||||
extern char SDPath[4];
|
||||
|
||||
if (!g_fatfs_mounted_for_sampling) {
|
||||
return; // 已经卸载
|
||||
}
|
||||
|
||||
// 卸载文件系统
|
||||
f_mount(NULL, SDPath, 0);
|
||||
g_fatfs_mounted_for_sampling = 0;
|
||||
|
||||
DebugOutput_SendString("Filesystem unmounted for USB mode\r\n");
|
||||
}
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/**
|
||||
@ -422,7 +568,7 @@ int main(void)
|
||||
SystemClock_Config();
|
||||
|
||||
/* USER CODE BEGIN SysInit */
|
||||
|
||||
HAL_Delay(200);
|
||||
/* USER CODE END SysInit */
|
||||
|
||||
/* Initialize all configured peripherals */
|
||||
@ -439,6 +585,11 @@ int main(void)
|
||||
MX_USART3_UART_Init();
|
||||
MX_TIM2_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
|
||||
// SD_NAND_Init_And_Mount();
|
||||
// SD_Test_Write();
|
||||
// SD_Test_Read();
|
||||
|
||||
// 初始化系统监控
|
||||
#if ENABLE_SYSTEM_MONITOR
|
||||
SystemMonitor_Init();
|
||||
@ -468,15 +619,35 @@ int main(void)
|
||||
Init_CorrectionParams(&g_correction_params);
|
||||
Load_CorrectionParams_FromFlash(&g_correction_params);
|
||||
|
||||
// 初始化数据存储
|
||||
if (DataStorage_Init(&g_data_storage) != HAL_OK) {
|
||||
// 检查初始USB连接状态并相应初始化
|
||||
HAL_Delay(2000);
|
||||
g_usb_connected = CheckUSBConnectionStatus();
|
||||
if (!g_usb_connected) {
|
||||
// USB未连接,挂载文件系统用于数据采集
|
||||
if (MountFileSystemForSampling() == HAL_OK) {
|
||||
// 初始化数据存储
|
||||
if (DataStorage_Init(&g_data_storage) == HAL_OK) {
|
||||
// 开始数据记录
|
||||
StartRecording();
|
||||
} else {
|
||||
#if ENABLE_SYSTEM_MONITOR
|
||||
SystemMonitor_ReportError(SYSTEM_ERROR_STORAGE);
|
||||
SystemMonitor_ReportError(SYSTEM_ERROR_STORAGE);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#if ENABLE_SYSTEM_MONITOR
|
||||
SystemMonitor_ReportError(SYSTEM_ERROR_STORAGE);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
// USB已连接,不进行数据采集
|
||||
DebugOutput_SendString("USB connected at startup - data acquisition disabled\r\n");
|
||||
|
||||
// 开始数据记录
|
||||
StartRecording();
|
||||
while(1)
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
// 系统初始化完成
|
||||
#if ENABLE_SYSTEM_MONITOR
|
||||
@ -519,8 +690,11 @@ int main(void)
|
||||
g_last_monitor_update = current_tick;
|
||||
}
|
||||
|
||||
// ADC数据处理已移至1ms定时器中断中处理
|
||||
|
||||
// USB连接状态检测 (每500ms检测一次)
|
||||
if (current_tick - g_last_usb_check >= 500) {
|
||||
HandleUSBConnectionChange();
|
||||
g_last_usb_check = current_tick;
|
||||
}
|
||||
|
||||
// 处理数据存储后台任务 (轮询方式)
|
||||
if (g_recording_enabled) {
|
||||
|
||||
@ -46,7 +46,7 @@ void MX_SDIO_SD_Init(void)
|
||||
hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
|
||||
hsd.Init.BusWide = SDIO_BUS_WIDE_1B;
|
||||
hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
|
||||
hsd.Init.ClockDiv = 0;
|
||||
hsd.Init.ClockDiv = 2;
|
||||
/* USER CODE BEGIN SDIO_Init 2 */
|
||||
|
||||
/* USER CODE END SDIO_Init 2 */
|
||||
@ -75,8 +75,14 @@ void HAL_SD_MspInit(SD_HandleTypeDef* sdHandle)
|
||||
PC12 ------> SDIO_CK
|
||||
PD2 ------> SDIO_CMD
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
|
||||
|GPIO_PIN_12;
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_12;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
@ -85,7 +91,7 @@ void HAL_SD_MspInit(SD_HandleTypeDef* sdHandle)
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_2;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
|
||||
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
|
||||
@ -100,7 +106,7 @@ void HAL_SD_MspInit(SD_HandleTypeDef* sdHandle)
|
||||
hdma_sdio_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
|
||||
hdma_sdio_rx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
|
||||
hdma_sdio_rx.Init.Mode = DMA_PFCTRL;
|
||||
hdma_sdio_rx.Init.Priority = DMA_PRIORITY_LOW;
|
||||
hdma_sdio_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
|
||||
hdma_sdio_rx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
|
||||
hdma_sdio_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
|
||||
hdma_sdio_rx.Init.MemBurst = DMA_MBURST_INC4;
|
||||
@ -121,7 +127,7 @@ void HAL_SD_MspInit(SD_HandleTypeDef* sdHandle)
|
||||
hdma_sdio_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
|
||||
hdma_sdio_tx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
|
||||
hdma_sdio_tx.Init.Mode = DMA_PFCTRL;
|
||||
hdma_sdio_tx.Init.Priority = DMA_PRIORITY_LOW;
|
||||
hdma_sdio_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
|
||||
hdma_sdio_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
|
||||
hdma_sdio_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
|
||||
hdma_sdio_tx.Init.MemBurst = DMA_MBURST_INC4;
|
||||
@ -133,6 +139,9 @@ void HAL_SD_MspInit(SD_HandleTypeDef* sdHandle)
|
||||
|
||||
__HAL_LINKDMA(sdHandle,hdmatx,hdma_sdio_tx);
|
||||
|
||||
/* SDIO interrupt Init */
|
||||
HAL_NVIC_SetPriority(SDIO_IRQn, 9, 0);
|
||||
HAL_NVIC_EnableIRQ(SDIO_IRQn);
|
||||
/* USER CODE BEGIN SDIO_MspInit 1 */
|
||||
|
||||
/* USER CODE END SDIO_MspInit 1 */
|
||||
@ -166,6 +175,9 @@ void HAL_SD_MspDeInit(SD_HandleTypeDef* sdHandle)
|
||||
/* SDIO DMA DeInit */
|
||||
HAL_DMA_DeInit(sdHandle->hdmarx);
|
||||
HAL_DMA_DeInit(sdHandle->hdmatx);
|
||||
|
||||
/* SDIO interrupt Deinit */
|
||||
HAL_NVIC_DisableIRQ(SDIO_IRQn);
|
||||
/* USER CODE BEGIN SDIO_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END SDIO_MspDeInit 1 */
|
||||
|
||||
@ -60,6 +60,7 @@
|
||||
extern PCD_HandleTypeDef hpcd_USB_OTG_FS;
|
||||
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_spi2_rx;
|
||||
extern DMA_HandleTypeDef hdma_spi3_rx;
|
||||
@ -266,6 +267,20 @@ void TIM2_IRQHandler(void)
|
||||
/* USER CODE END TIM2_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles SDIO global interrupt.
|
||||
*/
|
||||
void SDIO_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN SDIO_IRQn 0 */
|
||||
|
||||
/* USER CODE END SDIO_IRQn 0 */
|
||||
HAL_SD_IRQHandler(&hsd);
|
||||
/* USER CODE BEGIN SDIO_IRQn 1 */
|
||||
|
||||
/* USER CODE END SDIO_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles DMA2 stream0 global interrupt.
|
||||
*/
|
||||
|
||||
@ -20,7 +20,7 @@ Dma.SDIO_RX.3.Mode=DMA_PFCTRL
|
||||
Dma.SDIO_RX.3.PeriphBurst=DMA_PBURST_INC4
|
||||
Dma.SDIO_RX.3.PeriphDataAlignment=DMA_PDATAALIGN_WORD
|
||||
Dma.SDIO_RX.3.PeriphInc=DMA_PINC_DISABLE
|
||||
Dma.SDIO_RX.3.Priority=DMA_PRIORITY_LOW
|
||||
Dma.SDIO_RX.3.Priority=DMA_PRIORITY_VERY_HIGH
|
||||
Dma.SDIO_RX.3.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,FIFOThreshold,MemBurst,PeriphBurst
|
||||
Dma.SDIO_TX.4.Direction=DMA_MEMORY_TO_PERIPH
|
||||
Dma.SDIO_TX.4.FIFOMode=DMA_FIFOMODE_ENABLE
|
||||
@ -33,7 +33,7 @@ Dma.SDIO_TX.4.Mode=DMA_PFCTRL
|
||||
Dma.SDIO_TX.4.PeriphBurst=DMA_PBURST_INC4
|
||||
Dma.SDIO_TX.4.PeriphDataAlignment=DMA_PDATAALIGN_WORD
|
||||
Dma.SDIO_TX.4.PeriphInc=DMA_PINC_DISABLE
|
||||
Dma.SDIO_TX.4.Priority=DMA_PRIORITY_LOW
|
||||
Dma.SDIO_TX.4.Priority=DMA_PRIORITY_VERY_HIGH
|
||||
Dma.SDIO_TX.4.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,FIFOThreshold,MemBurst,PeriphBurst
|
||||
Dma.SPI1_RX.0.Direction=DMA_PERIPH_TO_MEMORY
|
||||
Dma.SPI1_RX.0.FIFOMode=DMA_FIFOMODE_DISABLE
|
||||
@ -76,8 +76,10 @@ Dma.USART1_TX.5.PeriphInc=DMA_PINC_DISABLE
|
||||
Dma.USART1_TX.5.Priority=DMA_PRIORITY_LOW
|
||||
Dma.USART1_TX.5.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode
|
||||
FATFS.BSP.number=1
|
||||
FATFS.IPParameters=_USE_LFN,USE_DMA_CODE_SD
|
||||
FATFS.IPParameters=_USE_LFN,USE_DMA_CODE_SD,_MAX_SS,_MIN_SS
|
||||
FATFS.USE_DMA_CODE_SD=1
|
||||
FATFS._MAX_SS=512
|
||||
FATFS._MIN_SS=512
|
||||
FATFS._USE_LFN=2
|
||||
FATFS0.BSP.STBoard=false
|
||||
FATFS0.BSP.api=Unknown
|
||||
@ -164,11 +166,12 @@ NVIC.ForceEnableDMAVector=true
|
||||
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
|
||||
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
|
||||
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
|
||||
NVIC.OTG_FS_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true
|
||||
NVIC.OTG_FS_IRQn=true\:11\:0\:true\:false\:true\:false\:true\:true
|
||||
NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
|
||||
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\:15\:0\:false\:false\:true\:false\:true\: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.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
|
||||
PA1.GPIOParameters=GPIO_Label
|
||||
@ -214,22 +217,36 @@ PB3.Mode=RX_Only_Simplex_Unidirect_Slave
|
||||
PB3.Signal=SPI3_SCK
|
||||
PB5.Mode=RX_Only_Simplex_Unidirect_Slave
|
||||
PB5.Signal=SPI3_MOSI
|
||||
PC10.GPIOParameters=GPIO_PuPd
|
||||
PC10.GPIO_PuPd=GPIO_PULLUP
|
||||
PC10.Mode=SD_4_bits_Wide_bus
|
||||
PC10.Signal=SDIO_D2
|
||||
PC11.GPIOParameters=GPIO_PuPd
|
||||
PC11.GPIO_PuPd=GPIO_PULLUP
|
||||
PC11.Mode=SD_4_bits_Wide_bus
|
||||
PC11.Signal=SDIO_D3
|
||||
PC12.GPIOParameters=GPIO_PuPd
|
||||
PC12.GPIO_PuPd=GPIO_NOPULL
|
||||
PC12.Mode=SD_4_bits_Wide_bus
|
||||
PC12.Signal=SDIO_CK
|
||||
PC3.GPIOParameters=GPIO_PuPd
|
||||
PC3.GPIO_PuPd=GPIO_PULLDOWN
|
||||
PC3.Locked=true
|
||||
PC3.Signal=GPIO_Input
|
||||
PC7.GPIOParameters=GPIO_Label
|
||||
PC7.GPIO_Label=RS485_CTL
|
||||
PC7.Locked=true
|
||||
PC7.Signal=GPIO_Output
|
||||
PC8.GPIOParameters=GPIO_PuPd
|
||||
PC8.GPIO_PuPd=GPIO_PULLUP
|
||||
PC8.Mode=SD_4_bits_Wide_bus
|
||||
PC8.Signal=SDIO_D0
|
||||
PC9.GPIOParameters=GPIO_PuPd
|
||||
PC9.GPIO_PuPd=GPIO_PULLUP
|
||||
PC9.Mode=SD_4_bits_Wide_bus
|
||||
PC9.Signal=SDIO_D1
|
||||
PD2.GPIOParameters=GPIO_PuPd
|
||||
PD2.GPIO_PuPd=GPIO_PULLUP
|
||||
PD2.Mode=SD_4_bits_Wide_bus
|
||||
PD2.Signal=SDIO_CMD
|
||||
PH0-OSC_IN.Mode=HSE-External-Oscillator
|
||||
@ -250,7 +267,7 @@ ProjectManager.DeviceId=STM32F405RGTx
|
||||
ProjectManager.FirmwarePackage=STM32Cube FW_F4 V1.28.3
|
||||
ProjectManager.FreePins=false
|
||||
ProjectManager.HalAssertFull=false
|
||||
ProjectManager.HeapSize=0x200
|
||||
ProjectManager.HeapSize=0x1000
|
||||
ProjectManager.KeepUserCode=true
|
||||
ProjectManager.LastFirmware=true
|
||||
ProjectManager.LibraryCopy=1
|
||||
@ -262,7 +279,7 @@ ProjectManager.ProjectFileName=STM_ATEM_F405.ioc
|
||||
ProjectManager.ProjectName=STM_ATEM_F405
|
||||
ProjectManager.ProjectStructure=
|
||||
ProjectManager.RegisterCallBack=
|
||||
ProjectManager.StackSize=0x400
|
||||
ProjectManager.StackSize=0x800
|
||||
ProjectManager.TargetToolchain=STM32CubeIDE
|
||||
ProjectManager.ToolChainLocation=
|
||||
ProjectManager.UAScriptAfterPath=
|
||||
@ -302,6 +319,9 @@ RCC.VCOI2SOutputFreq_Value=192000000
|
||||
RCC.VCOInputFreq_Value=1000000
|
||||
RCC.VCOOutputFreq_Value=336000000
|
||||
RCC.VcooutputI2S=96000000
|
||||
SDIO.ClockDiv=2
|
||||
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
|
||||
@ -332,7 +352,7 @@ USART3.IPParameters=VirtualMode
|
||||
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
|
||||
USB_DEVICE.MSC_MEDIA_PACKET-MSC_FS=8192
|
||||
USB_DEVICE.MSC_MEDIA_PACKET-MSC_FS=32768
|
||||
USB_DEVICE.VirtualMode-MSC_FS=Msc
|
||||
USB_DEVICE.VirtualModeFS=Msc_FS
|
||||
USB_OTG_FS.IPParameters=VirtualMode
|
||||
|
||||
@ -184,15 +184,20 @@ int8_t STORAGE_Init_FS(uint8_t lun)
|
||||
/* USER CODE BEGIN 2 */
|
||||
UNUSED(lun);
|
||||
|
||||
// 初始化SD卡
|
||||
if (HAL_SD_Init(&hsd) != HAL_OK) {
|
||||
return (USBD_FAIL);
|
||||
// 1. 检查 SD 句柄状态
|
||||
// 如果之前在 main.c 里已经 HAL_SD_Init 过了,这里只要确认状态即可
|
||||
HAL_SD_StateTypeDef state = HAL_SD_GetState(&hsd);
|
||||
|
||||
if(state == HAL_SD_STATE_RESET)
|
||||
{
|
||||
// 只有在从未初始化的情况下才初始化
|
||||
if (HAL_SD_Init(&hsd) != HAL_OK) {
|
||||
return (USBD_FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
// 挂载文件系统
|
||||
if (f_mount(&SDFatFS, SDPath, 1) != FR_OK) {
|
||||
return (USBD_FAIL);
|
||||
}
|
||||
// 2. 绝对不要在这里 f_mount 或 f_mkfs !!!
|
||||
// USB 只是搬运工,文件系统由电脑端管理。
|
||||
|
||||
sd_initialized = 1;
|
||||
return (USBD_OK);
|
||||
@ -211,20 +216,26 @@ int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_
|
||||
/* USER CODE BEGIN 3 */
|
||||
UNUSED(lun);
|
||||
|
||||
if (!sd_initialized) {
|
||||
return (USBD_FAIL);
|
||||
}
|
||||
|
||||
HAL_SD_CardInfoTypeDef cardinfo;
|
||||
if (HAL_SD_GetCardInfo(&hsd, &cardinfo) == HAL_OK) {
|
||||
*block_num = cardinfo.LogBlockNbr;
|
||||
*block_size = cardinfo.LogBlockSize;
|
||||
} else {
|
||||
*block_num = STORAGE_BLK_NBR;
|
||||
*block_size = STORAGE_BLK_SIZ;
|
||||
|
||||
if (HAL_SD_GetCardInfo(&hsd, &cardinfo) == HAL_OK)
|
||||
{
|
||||
// 修正 2: 欺骗电脑,强制报告 512 字节扇区
|
||||
*block_size = 512;
|
||||
|
||||
if (cardinfo.LogBlockSize == 512) {
|
||||
*block_num = cardinfo.LogBlockNbr - 1;
|
||||
}
|
||||
else {
|
||||
// 如果 SD NAND 是 2048/4096 字节页,需要转换块数量
|
||||
// 例如:实际 4096,那 USB 看到的块数就是 实际块数 * 8
|
||||
uint32_t ratio = cardinfo.LogBlockSize / 512;
|
||||
*block_num = (cardinfo.LogBlockNbr * ratio) - 1;
|
||||
}
|
||||
return (USBD_OK);
|
||||
}
|
||||
|
||||
return (USBD_OK);
|
||||
return (USBD_FAIL);
|
||||
/* USER CODE END 3 */
|
||||
}
|
||||
|
||||
@ -238,16 +249,14 @@ int8_t STORAGE_IsReady_FS(uint8_t lun)
|
||||
/* USER CODE BEGIN 4 */
|
||||
UNUSED(lun);
|
||||
|
||||
if (!sd_initialized) {
|
||||
return (USBD_FAIL);
|
||||
// 简单检查硬件状态
|
||||
if (hsd.State == HAL_SD_STATE_RESET) {
|
||||
return (USBD_FAIL);
|
||||
}
|
||||
|
||||
HAL_SD_CardStateTypeDef state = HAL_SD_GetCardState(&hsd);
|
||||
if (state == HAL_SD_CARD_TRANSFER) {
|
||||
return (USBD_OK);
|
||||
}
|
||||
|
||||
return (USBD_FAIL);
|
||||
// 对于 SD NAND,即使内部 BUSY,为了不让 USB 掉线,通常也返回 OK
|
||||
// 实际的等待放到 Read/Write 函数里去做
|
||||
return (USBD_OK);
|
||||
/* USER CODE END 4 */
|
||||
}
|
||||
|
||||
@ -278,12 +287,18 @@ int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t bl
|
||||
/* USER CODE BEGIN 6 */
|
||||
UNUSED(lun);
|
||||
|
||||
if (!sd_initialized || buf == NULL) {
|
||||
// 使用较长的超时时间 (SD NAND 读写较慢)
|
||||
uint32_t timeout = 2000;
|
||||
|
||||
if (HAL_SD_ReadBlocks(&hsd, buf, blk_addr, blk_len, timeout) != HAL_OK) {
|
||||
return (USBD_FAIL);
|
||||
}
|
||||
|
||||
if (HAL_SD_ReadBlocks(&hsd, buf, blk_addr, blk_len, HAL_MAX_DELAY) != HAL_OK) {
|
||||
return (USBD_FAIL);
|
||||
// 等待传输完成 (重要: 确保 DMA/中断搬运完毕)
|
||||
uint32_t tickstart = HAL_GetTick();
|
||||
while(HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > timeout) return USBD_FAIL;
|
||||
}
|
||||
|
||||
return (USBD_OK);
|
||||
@ -303,12 +318,19 @@ int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t b
|
||||
/* USER CODE BEGIN 7 */
|
||||
UNUSED(lun);
|
||||
|
||||
if (!sd_initialized || buf == NULL) {
|
||||
// 修正 3: 增加超时时间,并等待 Busy 结束
|
||||
uint32_t timeout = 5000; // 给 5秒,SD NAND 写入由于要擦除/编程,很慢
|
||||
|
||||
if (HAL_SD_WriteBlocks(&hsd, buf, blk_addr, blk_len, timeout) != HAL_OK) {
|
||||
return (USBD_FAIL);
|
||||
}
|
||||
|
||||
if (HAL_SD_WriteBlocks(&hsd, buf, blk_addr, blk_len, HAL_MAX_DELAY) != HAL_OK) {
|
||||
return (USBD_FAIL);
|
||||
// 【最关键的一步】等待 SD NAND 内部编程结束
|
||||
// 如果没有这一步,文件就会丢失!
|
||||
uint32_t tickstart = HAL_GetTick();
|
||||
while(HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > timeout) return USBD_FAIL;
|
||||
}
|
||||
|
||||
return (USBD_OK);
|
||||
|
||||
@ -91,7 +91,7 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef* pcdHandle)
|
||||
__HAL_RCC_USB_OTG_FS_CLK_ENABLE();
|
||||
|
||||
/* Peripheral interrupt init */
|
||||
HAL_NVIC_SetPriority(OTG_FS_IRQn, 0, 0);
|
||||
HAL_NVIC_SetPriority(OTG_FS_IRQn, 11, 0);
|
||||
HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
|
||||
/* USER CODE BEGIN USB_OTG_FS_MspInit 1 */
|
||||
|
||||
|
||||
@ -75,7 +75,7 @@
|
||||
/*---------- -----------*/
|
||||
#define USBD_SELF_POWERED 1U
|
||||
/*---------- -----------*/
|
||||
#define MSC_MEDIA_PACKET 8192U
|
||||
#define MSC_MEDIA_PACKET 32768U
|
||||
|
||||
/****************************************/
|
||||
/* #define for FS and HS identification */
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
// 数据存储配置
|
||||
#define DATA_STORAGE_BUFFER_SIZE 32768 // 缓冲区大小(字节)
|
||||
#define DATA_STORAGE_FILE_MAX_SIZE (10*1024*1024) // 单个文件最大10MB
|
||||
#define DATA_STORAGE_PATH "0:/DATA/" // 数据存储路径
|
||||
#define DATA_STORAGE_PATH "0:/DATA1" // 数据存储路径
|
||||
#define DATA_STORAGE_FILE_PREFIX "ADC_DATA_" // 文件名前缀
|
||||
|
||||
// 缓冲区状态
|
||||
|
||||
168
User/sd_test.c
Normal file
168
User/sd_test.c
Normal file
@ -0,0 +1,168 @@
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include <stdio.h> // 用于 printf 打印调试信息
|
||||
|
||||
#include "fatfs.h"
|
||||
#include "main.h"
|
||||
#include "dma.h"
|
||||
#include "fatfs.h"
|
||||
#include "sdio.h"
|
||||
#include "spi.h"
|
||||
#include "tim.h"
|
||||
#include "usart.h"
|
||||
#include "usb_device.h"
|
||||
#include "gpio.h"
|
||||
#include "main.h"
|
||||
#include "fatfs.h"
|
||||
#include "ff.h"
|
||||
#include "data_packet.h"
|
||||
#include "correction.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* USER CODE BEGIN 4 */
|
||||
|
||||
extern SD_HandleTypeDef hsd;
|
||||
//DMA_HandleTypeDef hdma_sdio_rx;
|
||||
//DMA_HandleTypeDef hdma_sdio_tx;
|
||||
|
||||
/**
|
||||
* @brief 针对 SD NAND 的专用初始化与格式化函数
|
||||
* @return 0: 成功, -1: 失败
|
||||
*/
|
||||
int SD_NAND_Init_And_Mount(void)
|
||||
{
|
||||
FRESULT res;
|
||||
BYTE workBuffer[4096]; // f_mkfs 需要的工作缓存
|
||||
|
||||
|
||||
// 1. 物理层延时:SD NAND 内部初始化比普通卡慢
|
||||
HAL_Delay(500);
|
||||
|
||||
// 2. 检查底层 SDIO 是否通了
|
||||
// 如果这里检测不到,说明硬件接线或 IOC 时钟配置有问题
|
||||
HAL_SD_CardStateTypeDef cardState = HAL_SD_GetCardState(&hsd); // 确认句柄是 hsd1 还是 hsd
|
||||
if (cardState == HAL_SD_CARD_ERROR) {
|
||||
printf("Error: SD Card Hardware Not Ready!\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 3. 尝试挂载 (Force Mount = 1)
|
||||
printf("Attempting to mount SD card...\r\n");
|
||||
res = f_mount(&SDFatFS, SDPath, 1);
|
||||
|
||||
// 4. 分析挂载结果
|
||||
if (res == FR_OK) {
|
||||
// 挂载成功,打印容量信息
|
||||
DWORD free_clusters;
|
||||
FATFS *fs;
|
||||
f_getfree(SDPath, &free_clusters, &fs);
|
||||
uint32_t total_blocks = (fs->n_fatent - 2) * fs->csize;
|
||||
printf("Mount Success! Total: %lu sectors\r\n", total_blocks);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 5. 如果没有文件系统 (新芯片或损坏),执行格式化
|
||||
else if (res == FR_NO_FILESYSTEM)
|
||||
{
|
||||
printf("No Filesystem found. Starting formatting (Legacy Mode)...\r\n");
|
||||
|
||||
/* 针对你的 FatFs 版本 (5个参数) 的修正
|
||||
参数说明:
|
||||
1. path: 路径
|
||||
2. opt: 格式化选项 (FM_FAT32, FM_SFD 等)
|
||||
3. au: 簇大小 (Allocation Unit),设为 4096 适配 SD NAND
|
||||
4. work: 工作缓存指针
|
||||
5. len: 工作缓存大小
|
||||
*/
|
||||
|
||||
// 确保你的 ff.h 中定义了 FM_FAT32。如果没有,尝试用 0x02 代替
|
||||
BYTE format_opt = FM_FAT32; // 或者 FM_ANY | FM_SFD
|
||||
|
||||
// 【关键】针对 SD NAND,强制使用 4096 字节的簇大小
|
||||
DWORD au_size = 512;
|
||||
|
||||
// 修正后的函数调用:传入 5 个参数,而不是结构体
|
||||
res = f_mkfs(SDPath, format_opt, au_size, workBuffer, sizeof(workBuffer));
|
||||
|
||||
if (res == FR_OK) {
|
||||
printf("Format Successful! Remounting...\r\n");
|
||||
// 格式化后建议取消挂载再重新挂载
|
||||
f_mount(NULL, SDPath, 0);
|
||||
res = f_mount(&SDFatFS, SDPath, 1);
|
||||
if (res == FR_OK) {
|
||||
printf("Remount Success!\r\n");
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
printf("Format Failed! Error: %d\r\n", res);
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 简单的测试写文件函数 */
|
||||
void SD_Test_Write(void) {
|
||||
FIL fil;
|
||||
UINT bw;
|
||||
if (f_open(&fil, "SDTest.txt", FA_WRITE | FA_CREATE_ALWAYS) == FR_OK) {
|
||||
f_write(&fil, "Hello SD NAND!", 14, &bw);
|
||||
f_close(&fil);
|
||||
printf("Write Test: OK\r\n");
|
||||
} else {
|
||||
printf("Write Test: Failed\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 读取测试函数
|
||||
* 打开 SDTest.txt,读取内容并通过 printf 打印
|
||||
*/
|
||||
void SD_Test_Read(void)
|
||||
{
|
||||
FIL fil; // 文件对象
|
||||
FRESULT res; // FatFs 返回结果
|
||||
UINT br; // Bytes Read (实际读取到的字节数)
|
||||
BYTE readBuf[128]; // 读取缓存 (根据需要调整大小)
|
||||
|
||||
printf("\r\n--- Starting Read Test ---\r\n");
|
||||
|
||||
// 1. 打开文件 (使用 FA_READ 模式)
|
||||
// 注意:文件名必须与写入时完全一致
|
||||
res = f_open(&fil, "SDTest.txt", FA_READ);
|
||||
|
||||
if (res != FR_OK) {
|
||||
printf("Read Failed: f_open error code %d\r\n", res);
|
||||
if (res == FR_NO_FILE) {
|
||||
printf("Error: File does not exist. Did Write Test run successfully?\r\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 读取文件
|
||||
// 为了安全,读取长度设为 buffer大小 - 1,留一个字节给字符串结束符
|
||||
res = f_read(&fil, readBuf, sizeof(readBuf) - 1, &br);
|
||||
|
||||
if (res == FR_OK) {
|
||||
// 3. 处理读取到的数据
|
||||
readBuf[br] = '\0'; // 手动添加字符串结束符,方便 printf 打印
|
||||
|
||||
printf("Read Success!\r\n");
|
||||
printf("Bytes Read: %d\r\n", br);
|
||||
|
||||
if (br > 0) {
|
||||
printf("File Content: \r\n%s\r\n", readBuf);
|
||||
} else {
|
||||
printf("Warning: File is empty (0 bytes).\r\n");
|
||||
}
|
||||
} else {
|
||||
printf("Read Failed: f_read error code %d\r\n", res);
|
||||
}
|
||||
|
||||
// 4. 关闭文件 (读取完成后也必须关闭,释放句柄)
|
||||
f_close(&fil);
|
||||
|
||||
printf("--- Read Test Finished ---\r\n");
|
||||
}
|
||||
/* USER CODE END 4 */
|
||||
@ -13,7 +13,8 @@ typedef enum {
|
||||
SYSTEM_STATE_SAMPLING,
|
||||
SYSTEM_STATE_RECORDING,
|
||||
SYSTEM_STATE_ERROR,
|
||||
SYSTEM_STATE_MAINTENANCE
|
||||
SYSTEM_STATE_MAINTENANCE,
|
||||
SYSTEM_STATE_USB_MODE
|
||||
} SystemState_t;
|
||||
|
||||
// 系统错误类型
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user