【RTT大赛作品连载】AB32VG1评估板 音乐播放器

电子说

1.3w人已加入

描述

        之前,记录了从新建项目到点灯,按钮控制彩灯测试!接下来看看在如何AB32VG1评估板实现音乐播放器!

硬件如图:

RTOS要用到TF卡,和美标3.2mm耳机

在RT-ThreadStudio的音乐播放器项目到对应开发配置!!!整体配置:

RTOS

详细配置如下:

内核设置如图(注意不要多选,或者少选!!!)

RTOSRTOS

组件如图:

RTOSRTOS

软件包如图:

RTOSRTOS

硬件设置如图:

RTOS

以上就是在RT-ThreadStudio的设置,这是我验证过的设置!!!其他的设置是否可用存在很大问题!!!我自己试过选择MP3格式,结果异常一大堆!!!所以建议在设置项目的时候尽量要注意!!!我也希望用截图这种直观的方式,快速记录项目设置的每个细节!尽量保证照着这个记录重新建类似的项目一次成功!!!

下面就是软件实现!有了前两次的AB32VG1评估板项目调试经验!这次相对就顺利多了!

软件逻辑是初始化后先获取对应目录下的.wav格式文件列表!在自动播放第一首歌!效果如图!

RTOS

接下来就是通过按键实现各种操作!如图:

RTOS

增加了两个关联变量,控制声音,及播放完毕

RTOS

配合以下源码:

/* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date           Author       Notes
* 2021-11-12     panshi90      the first version
*/
#include
#include
#include "board.h"
#include
#include "wavplayer.h"
#include
#include
#include
#include
//S3
#define BUTTON_PIN_0 rt_pin_get("PF.0")
//S2
#define BUTTON_PIN_1 rt_pin_get("PF.1")
//#define NUM_OF_SONGS    (1000u)
static struct button btn_0;
static struct button btn_1;
uint8_t cur_volume = 50;
int stopstate = 0;
rt_mutex_t mutex1;
int EndState = 0;
static uint32_t cnt_0 = 0;
//static uint32_t cnt_1 = 0;
uint16_t currentSong = 0;
static uint32_t NUM_OF_SONGS = 0;
char table[200];

static struct dfs_fd fd1;
static struct dirent dirent1;
void readFileListos()
{
   struct stat stat;
   int length, fd;
   char* fullpath, * path;

   fullpath = RT_NULL;
   NUM_OF_SONGS = 1;
   //system("cd .");
   rt_thread_mdelay(10);
   rm("wav.txt");
   rt_thread_mdelay(50);
   fd = open("wav.txt", O_WRONLY | O_CREAT | O_APPEND);
   path = rt_strdup("/WAV");
   if (dfs_file_open(&fd1, path, O_DIRECTORY) == 0)
   {
       //rt_kprintf("Directory %s:\n", path);
       do
       {
           memset(&dirent1, 0, sizeof(dirent1));
           length = dfs_file_getdents(&fd1, &dirent1, sizeof(dirent1));
           if (length > 0)
           {
               memset(&stat, 0, sizeof(struct stat));

               //  build full path for each file
               fullpath = dfs_normalize_path(path, dirent1.d_name);
               if (fullpath == RT_NULL)
                   break;

               if (dfs_file_stat(fullpath, &stat) == 0)
               {
                   char songPath[200] = "WAV/";
                   strcat(songPath, dirent1.d_name);
                   strcat(songPath, "\n");
                   write(fd, songPath, sizeof(songPath));
                   //rt_kprintf("%s\n", songPath);
                   if (S_ISDIR(stat.st_mode))
                   {
                       rt_kprintf("%-25s\n", "

 

       while (read(fd, songPath, sizeof(songPath)) > 0)
       {
           if (i == currentSong) {
               int32_t  len = strlen(songPath);
               songPath[len - 1] = '\0';
               strcpy(table, songPath);
           }
           i++;
       }
   }
   close(fd);
}
void saia_channels_set(uint8_t channels);
void saia_volume_set(rt_uint8_t volume);
uint8_t saia_volume_get(void);

static uint8_t button_read_pin_0(void)
{
   return rt_pin_read(BUTTON_PIN_0);
}

static uint8_t button_read_pin_1(void)
{
   return rt_pin_read(BUTTON_PIN_1);
}

static void button_S3_callback(void* btn)
{
   uint32_t btn_event_val;
   btn_event_val = get_button_event((struct button*)btn);
   switch (btn_event_val)
   {
   case SINGLE_CLICK:
       cnt_0++;
       cur_volume = cnt_0 * 10;
       if (cnt_0 == 10)
       {
           cnt_0 = 1;
       }
       saia_volume_set(cur_volume);
       rt_kprintf("vol=%d\n", saia_volume_get());
       rt_kprintf("button S3 single click\n");
       break;
   case DOUBLE_CLICK:
       if (cnt_0 > 1)
       {
           cnt_0--;
       }
       cur_volume = cnt_0 * 10;
       wavplayer_volume_set(cur_volume);
       rt_kprintf("button S3 double click\n");
       break;
   case LONG_PRESS_START:
       rt_kprintf("button S3 long press start\n");
       break;
   case LONG_PRESS_HOLD:
       rt_kprintf("button S3 long press hold\n");
       break;
   }
}

static void button_S2_callback(void* btn)
{
   uint32_t btn_event_val;
   int state = 0;
   EndState = 1;
   btn_event_val = get_button_event((struct button*)btn);

   switch (btn_event_val)
   {
   case SINGLE_CLICK:
       if (currentSong == NUM_OF_SONGS) {
           currentSong = 0;
       }
       GetCurrentPath();
       stopstate = 0;
       wavplayer_play(table);
       currentSong++;

       rt_kprintf("button S2 single click\n");
       break;
   case DOUBLE_CLICK:
       state = wavplayer_state_get();
       switch (state)
       {
       case PLAYER_STATE_PLAYING:
           wavplayer_pause();
           break;
       case PLAYER_STATE_PAUSED:
           wavplayer_resume();
           break;
       case PLAYER_STATE_STOPED:
           GetCurrentPath();
           wavplayer_play(table);
           rt_kprintf("button S2 double click\n");
           break;
       default:
           break;
       }
   default:
       break;
   }

   stopstate = 0;
   EndState = 0;
}

static void btn_thread_entry(void* p)
{
   while (1)
   {
       rt_thread_delay(RT_TICK_PER_SECOND / 500);
       rt_err_t  result = rt_mutex_take(mutex1, 2);
       if (result == RT_EOK) {
           button_ticks();
           rt_mutex_release(mutex1);
       }
   }
}
static void endCheck_thread_entry(void* p)
{
   while (1)
   {
       rt_thread_mdelay(2500);
       rt_err_t  result = rt_mutex_take(mutex1, 2);
       int   state = wavplayer_state_get();
       if (result == RT_EOK) {
           if ((state == PLAYER_STATE_STOPED) && (EndState == 0)) {
               if ((stopstate == 1)) {
                   stopstate = 0;
                   if (currentSong == NUM_OF_SONGS) {
                       currentSong = 0;
                   }
                   GetCurrentPath();
                   wavplayer_play(table);
                   currentSong++;
               }
           }
           rt_mutex_release(mutex1);
       }
   }
}

static int multi_button_test(void)
{
   rt_thread_t thread = RT_NULL, thread1 = RT_NULL;
   mutex1 = rt_mutex_create("xx", RT_IPC_FLAG_PRIO);
   //Create background ticks thread
   rt_thread_mdelay(2000);
   readFileListos();
   GetCurrentPath();
   saia_volume_set(cur_volume);
   wavplayer_play(table);
   currentSong++;
   thread = rt_thread_create("btn", btn_thread_entry, RT_NULL, 2048, 10, 10);
   thread1 = rt_thread_create("endCHeck", endCheck_thread_entry, RT_NULL, 2000, 11, 10);
   if (thread == RT_NULL)
   {
       return RT_ERROR;
   }
   rt_thread_startup(thread);
   if (thread1 == RT_NULL)
   {
       return RT_ERROR;
   }
   rt_thread_startup(thread1);
   // low level drive
   rt_pin_mode(BUTTON_PIN_0, PIN_MODE_INPUT_PULLUP);
   button_init(&btn_0, button_read_pin_0, PIN_LOW);
   button_attach(&btn_0, SINGLE_CLICK, button_S3_callback);
   button_attach(&btn_0, DOUBLE_CLICK, button_S3_callback);
   button_attach(&btn_0, LONG_PRESS_START, button_S3_callback);
   button_attach(&btn_0, LONG_PRESS_HOLD, button_S3_callback);
   button_start(&btn_0);

   rt_pin_mode(BUTTON_PIN_1, PIN_MODE_INPUT_PULLUP);
   button_init(&btn_1, button_read_pin_1, PIN_LOW);
   button_attach(&btn_1, SINGLE_CLICK, button_S2_callback);
   button_attach(&btn_1, DOUBLE_CLICK, button_S2_callback);
   button_attach(&btn_1, LONG_PRESS_START, button_S2_callback);
   button_attach(&btn_1, LONG_PRESS_HOLD, button_S2_callback);
   button_start(&btn_1);
   return RT_EOK;
}

INIT_APP_EXPORT(multi_button_test);

即可实现AB32VG1评估板 音乐播放器!

目前只支持.WAV格式,其实一个好的播放器应该支持多种音频文件格式!如:MP3,AIFF!有兴趣的爱好者可以在此基础上实现更多或者自己更喜欢的方式!!!

欢迎留言点赞!
 

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
评论(0)
发评论
PCB11337525 2021-11-13
0 回复 举报
厉害厉害! 收起回复
jf_61952251 2021-11-12
0 回复 举报
瑞哥厉害了 收起回复
全部评论

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分