STM32H7S78-DK板载WM8904耳放,有SD卡槽有屏幕,合计着做个播放器。首先读一下SD卡。
鉴于该芯片从零配置较为复杂,第一步使用FatFs_uSD_RTOS例程进行修改做验证。导入工程后没有ioc文件,因此不能使用cubemx来编辑工程,遂手动添加。
增加串口打印,便于之后打印调试信息。从原理图找出调试器连接的串口号
手动添加,需要配置串口参数,GPIO参数,重定向函数。分别如下
- static void MX_UART4_Init(void)
- {
- /* USER CODE BEGIN UART4_Init 0 */
- /* USER CODE END UART4_Init 0 */
- /* USER CODE BEGIN UART4_Init 1 */
- /* USER CODE END UART4_Init 1 */
- huart4.Instance = UART4;
- huart4.Init.BaudRate = 115200;
- huart4.Init.WordLength = UART_WORDLENGTH_8B;
- huart4.Init.StopBits = UART_STOPBITS_1;
- huart4.Init.Parity = UART_PARITY_NONE;
- huart4.Init.Mode = UART_MODE_TX_RX;
- huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
- huart4.Init.OverSampling = UART_OVERSAMPLING_16;
- huart4.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
- huart4.Init.ClockPrescaler = UART_PRESCALER_DIV1;
- huart4.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
- if (HAL_UART_Init(&huart4) != HAL_OK)
- {
- Error_Handler();
- }
- if (HAL_UARTEx_SetTxFifoThreshold(&huart4, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
- {
- Error_Handler();
- }
- if (HAL_UARTEx_SetRxFifoThreshold(&huart4, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
- {
- Error_Handler();
- }
- if (HAL_UARTEx_EnableFifoMode(&huart4) != HAL_OK)
- {
- Error_Handler();
- }
- /* USER CODE BEGIN UART4_Init 2 */
- /* USER CODE END UART4_Init 2 */
- }
复制代码- void HAL_UART_MspInit(UART_HandleTypeDef* huart)
- {
- GPIO_InitTypeDef GPIO_InitStruct = {0};
- RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
- if(huart->Instance==UART4)
- {
- /* USER CODE BEGIN UART4_MspInit 0 */
- /* USER CODE END UART4_MspInit 0 */
- /** Initializes the peripherals clock
- */
- PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART234578;
- PeriphClkInit.Usart234578ClockSelection = RCC_USART234578CLKSOURCE_PCLK1;
- if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
- {
- Error_Handler();
- }
- /* Peripheral clock enable */
- __HAL_RCC_UART4_CLK_ENABLE();
- __HAL_RCC_GPIOD_CLK_ENABLE();
- /**UART4 GPIO Configuration
- PD1 ------> UART4_TX
- PD0 ------> UART4_RX
- */
- GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_0;
- GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
- GPIO_InitStruct.Alternate = GPIO_AF8_UART4;
- HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
- /* USER CODE BEGIN UART4_MspInit 1 */
- /* USER CODE END UART4_MspInit 1 */
- }
- }
复制代码- 使用cubeIDE
- __io_putchar(int ch)
- {
- HAL_UART_Transmit(&huart4, (uint8_t *)&ch, 1, 0xffff);
- return ch;
- }
复制代码 代码修改完还是不能打印出信息的。需要IDE也作下配置,如下
添加输入输出头文件stdio后,就可以试试程序如何了。
以上没有问题,接下来看文件系统。例程已经添加了FatFS,插入SD卡运行程序会在根目录创建STM32.TXT文件,并且写入一串字符。嗯,我已经测试,这是没有问题的。那要改成我需要的显示文件列表。SD卡我已经拷贝了一些歌曲文件,f_opendir(),f_mount(),f_readdir()等接口函数直接操作就行了。记得安富莱电子专门有做测试程序,拷贝过来适应下,对其开源表示感谢。
- static void ViewRootDir(void)
- {
- FRESULT result;
- uint32_t cnt = 0;
- FILINFO fno;
- /* 挂载文件系统 */
- result = f_mount(&fs, DiskPath, 0); /* Mount a logical drive */
- if (result != FR_OK)
- {
- printf("挂载文件系统失败 (%s)\r\n", FR_Table[result]);
- }
- /* 打开根文件夹 */
- result = f_opendir(&DirInf, DiskPath); /* 如果不带参数,则从当前目录开始 */
- if (result != FR_OK)
- {
- printf("打开根目录失败 (%s)\r\n", FR_Table[result]);
- return;
- }
- printf("属性 | 文件大小 | 短文件名 | 长文件名\r\n");
- for (cnt = 0; ;cnt++)
- {
- result = f_readdir(&DirInf, &FileInf); /* 读取目录项,索引会自动下移 */
- if (result != FR_OK || FileInf.fname[0] == 0)
- {
- break;
- }
- if (FileInf.fname[0] == '.')
- {
- continue;
- }
- /* 判断是文件还是子目录 */
- if (FileInf.fattrib & AM_DIR)
- {
- printf("(0x%02d)目录 ", FileInf.fattrib);
- }
- else
- {
- printf("(0x%02d)文件 ", FileInf.fattrib);
- }
- f_stat(FileInf.fname, &fno);
- /* 打印文件大小, 最大4G */
- printf(" %10d", (int)fno.fsize);
- printf(" %s\r\n", (char *)FileInf.fname); /* 长文件名 */
- }
- /* 打印卡速度信息 */
- if(hsd1.SdCard.CardSpeed == CARD_NORMAL_SPEED)
- {
- printf("Normal Speed Card <12.5MB/S, MAX Clock < 25MHz, Spec Version 1.01\r\n");
- }
- else if (hsd1.SdCard.CardSpeed == CARD_HIGH_SPEED)
- {
- printf("High Speed Card <25MB/s, MAX Clock < 50MHz, Spec Version 2.00\r\n");
- }
- else if (hsd1.SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED)
- {
- printf("UHS-I SD Card <50MB/S for SDR50, DDR50 Cards, MAX Clock < 50MHz OR 100MHz\r\n");
- printf("UHS-I SD Card <104MB/S for SDR104, MAX Clock < 108MHz, Spec version 3.01\r\n");
- }
- /* 卸载文件系统 */
- f_mount(NULL, DiskPath, 0);
- }
复制代码 函数末尾还判断了SD卡的速度等级。我这个卡和厂家配送的一摸一样,看看如何。不出意外的话还是出意外了。
中文乱码了。这个应该能够通过修改文件编码格式来解决,不过网上看了下,可以添加编译参数代替修改编辑器。验证了下确实可以。
添加的内容为 -fexec-charset=GBK,还是修改编码的意思。
接下来直接使用有歌曲列表的SD卡来测试,看看意外如何了
很明显,还是意外了,不过问题我也看出来了。应该是长文件命名没有支持吧。然后紧急打开文件名支持,宏定义修改即可
料想这次应该没毛病了。结果,新的意外又出现了。
还好是我能hold住的问题,这文件看着也像是很接近了,看看ffconfig文件有啥没改好的。结果查看,发现code page指向了日文,难怪文字显示的内容参杂中文,这次总算没有意外了。
满是意外的过程也说明尽管使用了例程还是有很多细节容易忽略,接下来计划添加解码器的驱动到工程里来。
|