找回密码
 立即注册
查看: 176|回复: 0

84-MP3播放器,STC32G144K246实验箱演示程序

[复制链接]
已绑定手机

232

主题

239

回帖

1302

积分

版主

积分
1302
发表于 2026-7-3 17:17:58 | 显示全部楼层 |阅读模式
84-MP3播放器,STC32G144K246实验箱演示程序
主程序main.C代码如下(汇编版本在附件中):


/*---------------------------------------------------------------------*/
/* --- Web: www.STCAI.com ---------------------------------------------*/
/* --- BBS: www.STCAIMCU.com  -----------------------------------------*/
/*---------------------------------------------------------------------*/

/*************  功能说明    **************

音频文件:
16k单声道mp3文件或16k16位小端双声道PCM文件

ffmpeg pcm转码:
ffmpeg -ss 00:01:10 -t 45  -i .\x.mp3  -vn -ac 2 -f s16le -ar 16000 -acodec pcm_s16le out.pcm

ffmpeg mp3转码:
ffmpeg -i .\x.mp3 -vn -c:a libmp3lame -ar 16000 -b:a 32k -ac 1 -joint_stereo 0 out.mp3

简易命令:
test:执行FATFS初始化
ls:文件列表
play x:播放指定文件,x为ls列表序号
stop:停止播放
stat:状态信息打印

SD卡:
使用电脑格式化为FAT32格式或,使用test命令在实验箱上初始化
放入SD卡音频文件使用字母+数字命名,不要使用中文。

下载时, 选择时钟 48MHz

******************************************/

#include "config.h"
#include "I2S.h"
#include "TLV320AIC23.h"
#include "audio.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "spi.h"
#include "file_system.h"
void sys_init();
void print_status();
void CLK_Init(void);
void play();


void main()
{
  sys_init(); // 系统初始化
  CLK_Init(); // 时钟初始化
  fsInitFlag = 0;
  aInfo.isPlay = 0;

  SPI_Init();
  Timer0_Init();
       
        AIC23_Init();
  delay_ms(50);
  AIC32_InitSet();
  SetHeadPhoneVolume(60); // 设置音量
       
  I2S_Init();
  delay_ms(5);
  usb_init(); // USB初始化
        delay_ms(5);
  EA = 1;

  while (DeviceState != DEVSTATE_CONFIGURED)
  {
  }; // 等待USB完成配置
  delay_ms(1000);
  


  
  memset(UsbOutBuffer, 0, 64);
  while (1)
  {
    audio_play_run();
    if (bUsbOutReady)
    {
      printf("%s\n", UsbOutBuffer);
      if (strncmp(UsbOutBuffer, "test", 4) == 0)
      {
        if (!file_sys_init(FATFS_SD_PATH))
        {
          printf("fs初始化失败\n");
        }
        else
        {
          fatFsTest(FATFS_SD_PATH);
        }
      }
      else if (strncmp(UsbOutBuffer, "ls", 2) == 0)
      {
        if (!file_sys_init(FATFS_SD_PATH))
        {
          printf("文件系统初始化失败\n");
        }
        else
        {
          list_files(FATFS_SD_PATH);
        }
      }
      else if (strncmp(UsbOutBuffer, "play", 4) == 0)
      {
        play();
      }
                        else if (strncmp(UsbOutBuffer, "stat", 4) == 0)
      {
        print_status();
      }
      else if (strncmp(UsbOutBuffer, "stop", 4) == 0)
      {
        aInfo.isPlay = 0;
        f_close(&audio_file);
        printf("播放已停止\n");
      }
      else
      {
        printf("USB OUT DONE\r\n");
      }
      memset(UsbOutBuffer, 0, 64);
      usb_OUT_done(); // 接收应答(固定格式)
    }
  }
}
extern  u16 mp3_data_offset;
extern u16 mp3_data_sum;
extern volatile u8 pcm_run_flag;
extern u16 i2s_buffer_len;
extern u16 i2s_buffer_index;
void print_status(){
        printf("status:\n");
        printf("pcm_run_flag:%u\n",pcm_run_flag);
        printf("mp3_data_sum:%u\n",mp3_data_sum);
        printf("mp3_data_offset:%u\n",mp3_data_offset);
        printf("i2s_buffer_len:%u\n",i2s_buffer_len);
        printf("i2s_buffer_index:%u\n",i2s_buffer_index);
};

void sys_init()
{
    EnableAccessXFR();                  //使能访问扩展XFR
    AccessCodeFastest();                //设置最快速度访问程序代码
    AccessIXramFastest();               //设置最快速度访问内部XDATA
    IAP_SetTimeBase();                  //设置IAP等待参数,产生1us时基


  P0M1 = 0x00;
  P0M0 = 0x00;
  P1M1 = 0x00;
  P1M0 = 0x00;
  P2M1 = 0x00;
  P2M0 = 0x00;
  P3M1 = 0x00;
  P3M0 = 0x00;
  P4M1 = 0x00;
  P4M0 = 0x00;
  P5M1 = 0x00;
  P5M0 = 0x00;
  P6M1 = 0x00;
  P6M0 = 0x00;
  P7M1 = 0x00;
  P7M0 = 0x00;
  P1SR = 0;
  P2SR = 0;
  P7SR = 0; //        设置为高速模式

                //TFT SPI1
    // P2M0 = 0x7c; P2M1 = 0x00;  //P22~P25 推挽
    // //P2PU = 0xFF; //使能所有的QSPI口的内部10K上拉电阻
    // P2SR = 0xc3;
    // P2DR = 0xc3;
                //I2S AIC23_Init中定义

  // FLASH USART4_ SPI 3
  P7M0 = 0x0b;
  P7M1 = 0x00; // 70 71 73 推挽
  P7PU = 0xFF; // 使能所有的QSPI口的内部10K上拉电阻

  // // TFT\SD SPI1
  P2M0 = 0x6c;
  P2M1 = 0x93; // P22\P23\P25\P26 推挽
  P2PU = 0xFF;

  P2SR = 0x93;
  P2DR = 0x93;
  // // P92 SD CS_PIN 推挽
  P9M0 = 0x04;
  P9M1 = 0xfb;
  P9PU = 0x04;

  // uart
            P3M0 = 0x80; P3M1 = 0x7f;

}


////////////////////////////////////////
// 时钟初始化函数
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void CLK_Init(void)
{
    CLK_I2S1CLK_Divider(2);             //设置I2S1时钟预分频系数
    CLK_I2S2CLK_Divider(1);             //设置I2S2时钟预分频系数
    CLK_SPI1CLK_Divider(5);             //设置SPI1时钟预分频系数
    CLK_SPI2CLK_Divider(1);             //设置SPI2时钟预分频系数
    CLK_SPI3CLK_Divider(1);             //设置SPI3时钟预分频系数
    CLK_PWMACLK_Divider(1);             //设置PWMA时钟预分频系数
    CLK_PWMBCLK_Divider(1);             //设置PWMB时钟预分频系数
    CLK_PWMCCLK_Divider(1);             //设置PWMC时钟预分频系数
    CLK_PWMDCLK_Divider(1);             //设置PWMD时钟预分频系数
    CLK_PWMECLK_Divider(1);             //设置PWME时钟预分频系数
    CLK_PWMFCLK_Divider(1);             //设置PWMF时钟预分频系数
    CLK_TFPUCLK_Divider(1);             //设置TFPU时钟预分频系数

    CLK_SYSCLK_Divider(10);             //切换主时钟前先将系统时钟降频

    HIRC_48M();                         //选择内部预置的频率

    CLK_MCLK_HIRC();                    //选择内部高精度HIRC作为主时钟

    CLK_HPLL1_BASECLK();                //选择内部基本时钟BASECLK作为HPLL1输入时钟
    CLK_HPLL1_PreDivider(8);            //设置HPLL1的输入时钟预分频系数(分频后的频率必须为6MHz左右)
    CLK_HPLL1_Lock408MHz();             //选择HPLL1的锁频目标频率
    CLK_HPLL1_Enable();                 //启动HPLL1
    delay_ms(1);                        //等待PLL锁频

    CLK_MCLK2_HPLL1D2();                //选择HPLL1的输出2分频时钟作为主时钟

    CLK_SYSCLK_Divider(2);              //设置系统时钟分频系数

    CLK_HSI2SCK_HPLL1D2();              //选择HPLL1的输出2分频时钟作为高速I2S时钟源
    CLK_HSIOCK_HPLL1D2();               //选择HPLL1的输出2分频时钟作为高速外设时钟源

    //<<AICUBE_USER_CLOCK_INITIAL_BEGIN>>
    // 在此添加用户初始化代码  
    //<<AICUBE_USER_CLOCK_INITIAL_END>>
}

void delay_ms(WORD ms)
{
  WORD i;

  do
  {
    i = MAIN_Fosc / 6000;
    while (--i)
      ;
  } while (--ms);
}
void delay_us(WORD ms)
{
  WORD i;

  do
  {
    i = MAIN_Fosc / 6000000UL;
    while (--i)
      ;
  } while (--ms);
}

void QSPI_DMA_Isr() interrupt DMA_QSPI_VECTOR
{
  DMA_QSPI_STA = 0x00;
  //                //DMA_P2P1_CR1 = 0; // 关闭P2P
  //                DMA_P2P1_SRC = 0;
  //                DMA_P2P1_DEST = 0;
  //                SPSTAT = 0x80 + 0x40; // 清0 SPIF和WCOL标志
  //                HSSPI_DisableFIFO();  // 使用SPI查询或中断方式时,要禁止FIFO
  //                lcd_cs_pin = 1;
  //                qspiDmaFlag = 1;
  printf("DMA END\n");
}
void play()
{
  char *cmd_param = UsbOutBuffer + 5;
  u16 file_index = atoi(cmd_param);
  file_index--;
  if (aInfo.isPlay)
  {
    printf("请先停止当前播放\n");
    return;
  }
  if (!file_sys_init(FATFS_SD_PATH))
  {
    printf("文件系统初始化失败\n");
  }
  else
  {
    // 如果文件列表为空,先获取文件列表
    if (file_list_count == 0)
    {
      list_files(FATFS_SD_PATH);
    }

    // 获取指定索引的文件路径
    memset(aInfo.file_name, 0, sizeof(aInfo.file_name));
    if (get_file_by_index(file_index, aInfo.file_name))
    {
      FRESULT res;
      printf("play: %s\n", aInfo.file_name);
      // 这里将调用audio.c中的函数来播放音频
      // 首先需要打开文件,获取文件大小

      res = f_open(&audio_file, aInfo.file_name, FA_READ);
      if (res == FR_OK)
      {
        DWORD file_size = f_size(&audio_file);

        // 初始化音频播放
        aInfo.audio_size = file_size;
        aInfo.audio_index = 0;
        aInfo.isPlay = 1;
        audio_play_init();
      }
      else
      {
        memset(aInfo.file_name, 0, sizeof(aInfo.file_name));
        printf("open file %s fail: %u\n", aInfo.file_name, res);
      }
    }
  }
}


84-MP3播放器.zip (14.91 MB, 下载次数: 51)
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-11-8 01:46 , Processed in 0.065813 second(s), 41 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表