一、前言
在上两篇文章实现了屏幕显示、触摸和DAC播放音乐的功能,趁周末抽点时间,又编写了从SD卡读取音频文件和界面的设计。
目前实现功能如下:
- 实现从SD卡中读取音频文件
- 实现播放和暂停
- 实现上一曲和下一曲
- 实现界面切换
- 目前测试从SD卡中只读取音频文件一小段,存放到RAM中,然后播放(如需实际应用,关于这一部分还需进行处理)
二、移植SD卡,挂载文件系统
这里之前测试的音频文件是直接取数组放在单片机内部,因为单片机内部空间有限,不能存放很多音频文件,故选择从SD卡中读取音频文件,这里移植了Fatfs,更方便去读取。
关于SD卡的移植,我看社区中已经有相关的教程了,这里就不介绍了。
三、界面介绍
关于音乐播放器界面的设计,采用极简的方式,一共有3个界面,第一个是主界面,只显示了音乐图标,第二个界面是音频文件列表,显示从SD卡中读取的音频文件,第三个界面是播放界面,有暂停、开始、上一首、下一首、返回上一界面和返回主界面功能。
(界面就随便写写,能用)
主界面:
音频列表界面:
播放界面:
四、触摸注册
这里面编写了触摸注册部分,通过注册触摸任务可以方便的去处理和触摸相关的部分,部分代码如下:
触摸任务结构体定义:
typedef struct
{
uint8_t isUse; // 是否使用
/* 触摸的范围 */
uint16_t startX;
uint16_t startY;
uint16_t length;
uint16_t width;
uint8_t page; // 注册在第几页
void (*touchTasks)(void);
uint8_t taskIsRunning; // 任务是否在执行中
}TOUCH_TASK;
TOUCH_TASK touchTaskStruct[TOUCH_TASK_NUM];
触摸任务注册函数:
/********************************************
@功能: 触摸任务注册
@日期:2022-08-21 16:29
@作者:lengyuefeng
@说明:
@参数: void (*touchTasks)(void):要注册的任务
x,y:起始坐标
length: 长
width: 宽
page:注册在第几页
@返回值: 0:注册成功 其他:注册失败
*********************************************/
uint8_t TOUCHTASK_regesiter(uint16_t x,uint16_t y,uint16_t length,uint16_t width,void (*touchTasks)(void),uint8_t page)
{
uint8_t i;
/* 注册触摸任务 */
for(i = 0; i < TOUCH_TASK_NUM;i++)
{
if(touchTaskStruct[i].isUse == noUse) // 当前任务没有被注册过
{
/* 开始注册 */
touchTaskStruct[i].startX = x;
touchTaskStruct[i].startY = y;
touchTaskStruct[i].length = length;
touchTaskStruct[i].width = width;
touchTaskStruct[i].touchTasks = touchTasks; // 链接此任务
touchTaskStruct[i].isUse = use; // 标记为已使用
touchTaskStruct[i].page = page;
return 0; // 链接到任务之后就退出 注册成功
}
}
return 1; // 未注册成功
}
触摸扫描函数:
/********************************************
@功能: 触摸检测
@日期:2022-08-21 15:39
@作者:lengyuefeng
@说明:
@参数: 无
@返回值: 无
*********************************************/
void music_touchDetect(void)
{
uint8_t i;
if(TOUCH_GetSta() == TOUCH_STATE_PRESS) // 触摸按下
{
/* 扫描触摸任务 */
for(i = 0; i< TOUCH_TASK_NUM;i++)
{
if(touchTaskStruct[i].isUse == use) // 先判断此任务有没有注册
{
if(touchTaskStruct[i].page == currentInterface.currentPage) // 判断是否是当前界面触摸
{
// u1_printf("touchTaskStruct[i].page:%d\r\n",touchTaskStruct[i].page);
/* 判断任务有没有触发 */
if(0 == music_touchSetRange(touchTaskStruct[i].startX,touchTaskStruct[i].startY,touchTaskStruct[i].length,touchTaskStruct[i].width))
{
/* 执行触发任务 */
if(touchTaskStruct[i].taskIsRunning == TASK_NO_RUNNING)
{
touchTaskStruct[i].taskIsRunning = TASK_RUNNING;
touchTaskStruct[i].touchTasks();
/* 任务执行完毕之后,可以再次触摸 触摸任务没有执行完,不再扫描任务 */
touchTaskStruct[i].taskIsRunning = TASK_NO_RUNNING;
}
}
}
}
}
}
}
五、结论
目前也算是基本实现了一个简易的音乐播放器的效果。此程序功能流程都有了,算是一个演示版本。
六、实现效果
这里直接放视频给大家看一下。
https://www.youku.com/video/X...
七、工程代码
代码部分放到gitee上了。
音乐播放器源码