- /* Initialize COM1 port (115200, 8 bits (7-bit data + 1 stop bit), no parity */
- BspCOMInit.BaudRate = 115200;
- BspCOMInit.WordLength = COM_WORDLENGTH_8B;
- BspCOMInit.StopBits = COM_STOPBITS_1;
- BspCOMInit.Parity = COM_PARITY_NONE;
- BspCOMInit.HwFlowCtl = COM_HWCONTROL_NONE;
- if (BSP_COM_Init(COM1, &BspCOMInit) != BSP_ERROR_NONE)
- {
- Error_Handler();
- }
2、SD_DETECT引脚初始化
SD_DECTECT需要设置为外部中断引脚
- GPIO_InitStruct.Pin = SD_DETECT_Pin;
- GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
- GPIO_InitStruct.Pull = GPIO_PULLUP;
- HAL_GPIO_Init(SD_DETECT_GPIO_Port, &GPIO_InitStruct);
- /* EXTI interrupt init*/
- HAL_NVIC_SetPriority(SD_DETECT_EXTI_IRQn, 5, 0);
- HAL_NVIC_EnableIRQ(SD_DETECT_EXTI_IRQn);
3、SD卡的初始化
MX_SDMMC1_SD_Init()
- /**
- * [url=home.php?mod=space&uid=247401]@brief[/url] SDMMC1 Initialization Function
- * @param None
- * @retval None
- */
- void MX_SDMMC1_SD_Init(void)
- {
- /* USER CODE BEGIN SDMMC1_Init 0 */
- /* USER CODE END SDMMC1_Init 0 */
- /* USER CODE BEGIN SDMMC1_Init 1 */
- /* USER CODE END SDMMC1_Init 1 */
- hsd1.Instance = SDMMC1;
- hsd1.Init.ClockEdge = SDMMC_CLOCK_EDGE_FALLING;
- hsd1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
- hsd1.Init.BusWide = SDMMC_BUS_WIDE_4B;
- hsd1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_ENABLE;
- hsd1.Init.ClockDiv = 0x02;
- if(HAL_SD_Init(&hsd1) != HAL_OK)
- {
- Error_Handler();
- }
- /* USER CODE BEGIN SDMMC1_Init 2 */
- /* USER CODE END SDMMC1_Init 2 */
- }
4、FatFs 初始化
用到了FREERTOS建立了一个uSDThread_Entry和一个队列
- void MX_FATFS_Init(void)
- {
- /* USER CODE BEGIN Init */
- /* additional user code for init */
- /*## FatFS: Link the disk I/O driver(s) ###########################*/
- if (FATFS_LinkDriver(&SD_DMA_Driver, SDPath) == 0)
- {
- /* creation of uSDThread */
- FSAppThreadHandle = osThreadNew(uSDThread_Entry, NULL, &uSDThread_attributes);
- /* Create Storage Message Queue */
- QueueHandle = osMessageQueueNew(1U, sizeof(uint16_t), NULL);
- }
- /* USER CODE END Init */
- }
5、uSDThread_Entry
用来处理队列的各种消息,并做对应处理
- static void uSDThread_Entry(void *argument)
- {
- osStatus_t status;
- if(SD_IsDetected())
- {
- osMessageQueuePut (QueueHandle, &CARD_CONNECTED, 100, 0U);
- }
- /* Infinite Loop */
- for( ;; )
- {
- status = osMessageQueueGet(QueueHandle, &osQueueMsg, NULL, 100);
- if ((status == osOK) && (osQueueMsg== CARD_STATUS_CHANGED))
- {
- if (SD_IsDetected())
- {
- osMessageQueuePut (QueueHandle, &CARD_CONNECTED, 100, 0U);
- }
- else
- {
- osMessageQueuePut (QueueHandle, &CARD_DISCONNECTED, 100, 0U);
- }
- }
- if ((status == osOK) && (osQueueMsg== CARD_CONNECTED))
- {
- //sHAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_SET);
- BSP_LED_On(LED_BLUE);
- //FS_FileOperations();
- FS_listDirectory();
- statusChanged = 0;
- }
- if ((status == osOK) && (osQueueMsg== CARD_DISCONNECTED))
- {
- HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);
- HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);
- osDelay(200);
- f_mount(NULL, (TCHAR const*)"", 0);
- statusChanged = 0;
- }
- }
- }
在收到CARD_CONNECTED消息后,会执行FS_listDirectory()
6、SD_DECTECT外部中断处理函数
判断SD_DETECT状态,如果发生改变,向队列中发送CARD_STATUS_CHANGED消息。
- void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
- {
- if(GPIO_Pin == SD_DETECT_Pin)
- {
- if (statusChanged == 0)
- {
- statusChanged = 1;
- osMessageQueuePut ( QueueHandle, &CARD_STATUS_CHANGED, 100, 0U);
- }
- }
- }
7、FS_listDirectory
在这里利用FatFs提供的函数:
f_mount挂载SD。
f_opendir打开"/"目录
f_readdir读取"/"目录
通过循环打印出目录下所有文件名和文件大小
- static void FS_listDirectory(void)
- {
- FRESULT res;
- DIR dir;
- FILINFO fno;
- uint32_t bytesread;
-
- printf("【1】列出目录中文件内容:\r\n");
- if(f_mount(&SDFatFs, (TCHAR const*)SDPath, 0) == FR_OK)
- {
- printf("mount SD success\r\n");
- res = f_opendir(&dir, "/");
- if (res == FR_OK) {
- printf("open directory success\r\n");
- printf("list directory / files:\r\n");
- for (;;) {
- res = f_readdir(&dir, &fno);
- if (res != FR_OK || fno.fname[0] == 0) break; // 读取错误或结束标志
- if (fno.fname[0] == '.') continue; // 跳过隐藏文件
- printf("%s %d\r\n", fno.fname,fno.fsize); // 打印文件名
- }
-
- f_closedir(&dir);
- }
-
- if(f_open(&SDFile, "STM32_1.TXT", FA_READ) == FR_OK)
- {
- /* Read data from the text file */
- res = f_read(&SDFile, ( void *)rtext, sizeof(rtext), (void *)&bytesread);
- if((bytesread > 0) && (res == FR_OK))
- {
- printf("\r\nSTM32_1.TXT file content:%s\r\n",rtext);
- /* Close the open text file */
- f_close(&SDFile);
- }
- }
- }
- }
8、另外FS_FileOperations函数实现了对文件读写
f_mkfs:建立文件系统,相当于格式化。
- static void FS_FileOperations(void)
- {
- FRESULT res; /* FatFs function common result code */
- uint32_t byteswritten, bytesread; /* File write/read counts */
- /* Register the file system object to the FatFs module */
- if(f_mount(&SDFatFs, (TCHAR const*)SDPath, 0) == FR_OK)
- {
- printf("mount SD success\r\n");
- /* check whether the FS has been already created */
- if (isFsCreated == 0)
- {
- /*
- if(f_mkfs(SDPath, &OptParm, workBuffer, sizeof(workBuffer)) != FR_OK)
- {
- printf("make file system success\r\n");
- HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET);
- return;
- }
- isFsCreated = 1;
- */
- }
- /* Create and Open a new text file object with write access */
- if(f_open(&SDFile, "STM32_1.TXT", FA_CREATE_ALWAYS | FA_WRITE) == FR_OK)
- {
- printf("open STEM32.TXT success\r\n");
- /* Write data to the text file */
- res = f_write(&SDFile, (const void *)wtext, sizeof(wtext), (void *)&byteswritten);
- if((byteswritten > 0) && (res == FR_OK))
- {
- printf("write finished, close STEM32.TXT success\r\n");
- /* Close the open text file */
- f_close(&SDFile);
- /* Open the text file object with read access */
- if(f_open(&SDFile, "STM32_1.TXT", FA_READ) == FR_OK)
- {
- /* Read data from the text file */
- res = f_read(&SDFile, ( void *)rtext, sizeof(rtext), (void *)&bytesread);
- if((bytesread > 0) && (res == FR_OK))
- {
- printf("open finished, close STEM32.TXT success\r\n");
- /* Close the open text file */
- f_close(&SDFile);
- /* Compare read data with the expected data */
- if(bytesread == byteswritten)
- {
- printf("read and written bytes are same\r\n");
- /* Success of the demo: no error occurrence */
- //HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);
- BSP_LED_On(LED_RED);
- return;
- }
- }
- }
- }
- }
- }
- /* Error */
- //HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET);
- BSP_LED_On(LED_BLUE);
- }
三、效果
通过串口获得结果:
列出了SD卡上的3个文件,其中SYSTEM~1是系统文件,其他2个是自己建的,并打印出了STM32_1.TXT文件内容。
将SD卡插入读卡器并连上电脑,我用的带SD卡的收音机,可以看到被识别了U盘,可以看到下面有2个文件。