【前言】
经过链表的学习,有了一些了解。因此我准备在我的STM32F769上使用双向链表的实际工程应用。
【设计】
此次使用的环境为获取SD卡中的.wav文件列表。
为什么要用链表,因为我准备把SD卡的目录下的.wav文件读出来,好象在以后的播放中来进行播放当前文件,然后有后一首,前一首,到头到尾等多个操作。所以使用链表相比申请数组比较方便,当然也节约内存。
【节点的设计】
-
- typedef struct WavFileNode
- {
- char filename[256];
- struct WavFileNode *prev;
- struct WavFileNode *next;
- } WavFileNode;
其实这个节点还需要包文件的大小的。这次使用先从简单的做起。
然后就设计新建、追加、插入等函数,代码放在read_wav_filename.c中:
- #include "ff.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include "read_wav_filename.h"
- #include <stdbool.h>
- WavFileNode *fileList = NULL;
-
- WavFileNode *createNode(const char *filename)
- {
- WavFileNode *newNode = (WavFileNode *)malloc(sizeof(WavFileNode));
- if (newNode == NULL)
- {
- printf("内存分配失败\n");
- return NULL;
- }
- sprintf(newNode->filename, "%s", filename);
- newNode->prev = NULL;
- newNode->next = NULL;
- return newNode;
- }
-
-
- void appendNode(WavFileNode **head, const char *filename)
- {
- WavFileNode *newNode = createNode(filename);
- if (*head == NULL)
- {
- *head = newNode;
- }
- else
- {
- WavFileNode *temp = *head;
- while (temp->next != NULL)
- {
- temp = temp->next;
- }
- temp->next = newNode;
- newNode->prev = temp;
- }
- }
-
-
- void freeList(WavFileNode *head)
- {
- WavFileNode *temp = head;
- while (temp != NULL)
- {
- WavFileNode *next = temp->next;
- free(temp);
- temp = next;
- }
- }
-
-
- WavFileNode *getTailNode(WavFileNode *head)
- {
- WavFileNode *temp = head;
- while (temp != NULL && temp->next != NULL)
- {
- temp = temp->next;
- }
- return temp;
- }
-
-
- WavFileNode *getHeadNode(WavFileNode *head)
- {
- WavFileNode *temp = head;
- while (temp != NULL && temp->prev != NULL)
- {
- temp = temp->prev;
- }
- return temp;
- }
-
-
-
- void readWavFiles(const char *folderPath, WavFileNode **head)
- {
- DIR dir;
- FILINFO fileInfo;
- FRESULT res = f_opendir(&dir, folderPath);
- if (res != FR_OK)
- {
- printf("无法打开文件夹\n");
- return;
- }
- while (1)
- {
- res = f_readdir(&dir, &fileInfo);
- if (res != FR_OK || fileInfo.fname[0] == 0)
- {
- break;
- }
- if (fileInfo.fattrib & AM_DIR)
- {
-
- continue;
- }
- else
- {
-
- if (strstr(fileInfo.fname, ".wav") != NULL && fileInfo.fname[0] != 0)
- {
-
- appendNode(head, fileInfo.fname);
- }
- }
- }
- f_closedir(&dir);
- }
-
-
- const char *getNextWavFilename(WavFileNode **head)
- {
- WavFileNode *temp = *head;
- if (temp == NULL)
- {
- return NULL;
- }
- const char *filename = temp->filename;
- *head = temp->next;
- free(temp);
- return filename;
- }
-
-
- bool isWavFileListEmpty(WavFileNode *head)
- {
- return head == NULL;
- }
-
-
- void printWavFileList(WavFileNode *head)
- {
- uint8_t count = 0;
- WavFileNode *temp = head;
- while (temp!= NULL)
- {
- printf("count:%d: %s\n", count, temp->filename);
- temp = temp->next;
- count++;
- }
- }
read_wav_filename.h:
- #ifndef READ_WAV_FILENAME_H
- #define READ_WAV_FILENAME_H
-
- #include "ff.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdbool.h>
-
- typedef struct WavFileNode
- {
- char filename[256];
- struct WavFileNode *prev;
- struct WavFileNode *next;
- } WavFileNode;
-
-
- WavFileNode *createNode(const char *filename);
- void appendNode(WavFileNode **head, const char *filename);
- void freeList(WavFileNode *head);
- WavFileNode *getTailNode(WavFileNode *head);
- WavFileNode *getHeadNode(WavFileNode *head);
- void readWavFiles(const char *folderPath, WavFileNode **head);
- const char *getNextWavFilename(WavFileNode **head);
- bool isWavFileListEmpty(WavFileNode *head);
- void printWavFileList(WavFileNode *head);
- #endif
【应用】
我把这两个文件添加进工程中,在lvgl的工程中进行调用:
- void get_wave_file(lv_ui *ui)
- {
- static get_state_flag = 0;
- if (get_state_flag == 0)
- {
- get_state_flag = 1;
- readWavFiles("/", &fileList);
- }
-
- printWavFileList(fileList);
- if (isWavFileListEmpty(fileList))
- {
- printf("No WAV files found.\n");
- }
- else
- {
- char buff[1024] = {0};
-
- WavFileNode *current = fileList;
- while (current != NULL)
- {
-
- int remaining_space = sizeof(buff) - strlen(buff);
- if (remaining_space > 0)
- {
- snprintf(buff + strlen(buff), remaining_space, "%s\n", current->filename);
- }
- else
- {
- printf("Buffer is full, cannot add more filenames.\n");
- break;
- }
- current = current->next;
- }
- lv_span_set_text(ui->screen_spangroup_1_span, (const char *)buff);
- }
-
- }
经过这样的设计,实现了fatfs的读取,与lvgl的代码进行解耦。
实现效果:
在打印日志中可以看到获取的文件列表:
在LVGL界面中也可以看到:
【总结】
通过对《Hell算法》的学习,我把学到的知识实现应用到了自己的MCU工程,成功的落地。