单片机
返回首页

LPC1768 MP3录音和循环播放源码

2019-11-30 来源:51hei

LPC1768  

2个程序,一个实现录音 一个实现循环播放

** 实验名:MP3

** KEIL MDK-ARM Standard Version:4.6

** 使用外设: 3.2寸LCD

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

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

测试说明:

    此程序为MP3测试例程将MP3文件拷入到2G内存卡后,插上3.2寸液晶屏,插入耳机,下载程

    序上电,开始播放歌曲并且在液晶屏上显示MP3文件名称(这里并不支持中文显示),调节

    滑动变阻器可以改变播放声音

***********************************

单片机源程序如下:


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

  * Company: Wang Electronic Technology Co., Ltd.

  ******************************************************************************

  * 文件名称:main.c

  * 功能说明:mp3播放

  * 版    本:V1.1

        * 作    者:jeansonm        

  * 日    期:2014-4-22

********************************************************************************

  * 文件名称:

  * 功能说明:

  * 版    本:

        * 更新作者:        

  * 日    期:

        * 更新原因:

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

#include                                            

#include 'LCD.h'

#include 'string.h'

#include 'sys.h'

#include 'lcd.h'

#include 'ff.h'

#include 'config.h'

#include 'vs1003.h'

#include 'mp3.h'

#include 'MMC_SD.h'

#include 'delay.h'

#include 'ssp0.h'

#include 'adc.h'


u8 MusicNumber;

u8 temp;

u8 count=0;


u32 datasize=0;           


FATFS fs;            // Work area (file system object) for logical drive

FIL fsrc, fdst,fap,file;      // file objects

FRESULT res,re;         // FatFs function common result code

UINT br, bw,bt;;         // File R/W count

FILINFO finfo,fno;

DIR dirs;


u8 buffer[1024]; // file copy buffer

u8 flag=0;


void ReFresh(u8 *p)

{

        LCD_Clear(Black);                        //清屏

        LCD_DisplayString(60,30,'www#openmcu#com');

        LCD_DisplayString(60,50,'bbs.openmcu.com');

        LCD_DisplayString(60,70,'MP3 Test');

        LCD_DisplayString(60,90,'Play:');

        LCD_DisplayString(100,90,p);

}

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

**   Main Function  main()

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

int main (void)                       

{                  

        u8 i;

        u16 AD_value,AD_Old_value;

        SystemInit();

        Vs1003_Init();                                //vs1003引脚初始化

        Vs1003SoftReset();                //vs1003软件复位

        LCD_Init();                                                //LCD初始化

        LCD_SetTextColor(Red);//设置字体为红色

        LCD_SetBackColor(Black);        //设置背景色为黑色        

        ReFresh('');                                        //刷新屏幕

        USER_ADC_Init();

                     

        SD_Init();                                                 //初始化SD卡

        f_mount(0,&fs);                                //挂载文件系统 

  temp= FindMusic();                //音乐查找

        MusicNumber=temp;

        bw = f_open(&fsrc,filename[0],FA_OPEN_EXISTING | FA_READ);                //打开第一个文件

        ReFresh((u8 *)(filename[0]));


//        VsSineTest(); //正弦波测试  ,会听到滴答声 ,说明VS1003 初始化通过

  while(1)

  {         

                if(datasize>=fsrc.fsize)                //到达文件尾播放完成

                        flag=1;

                if(count++==10)

                {

                         count=0;

                         AD_value=USER_ADC_Get();        //获取AD转换值

                        if(abs(AD_value-AD_Old_value)>30) {

                                        AD_Old_value = AD_value;

                                        AD_value=((AD_value*255)/4096);

                                        AD_value<<=8;                

                                        AD_value+=((AD_Old_value*255)/4096);          

                                        Vs1003_CMD_Write(SPI_VOL,AD_value); //设音量 高八位为左声道 第八位为右声道,这里相同

                        }

                 }

                 if(flag==1)  //文件播放完了

                {

                        flag=0;

                        if(MusicNumber--)         //下一个文件

                        {

                                if(MusicNumber==0)                 //所有文件播放完了

                                {

                                        MusicNumber=temp;                        //从头开始播放

                                }

                                bw = f_open(&fsrc,filename[temp-MusicNumber],FA_OPEN_EXISTING | FA_READ);

                                ReFresh((u8 *)filename[temp-MusicNumber]);        //更新显示

……………………


** 实验名:MP3录音

** KEIL MDK-ARM Standard Version:

** 使用外设: 3.2寸LCD mic头 耳机

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

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

测试说明:

    此程序为VS1003 MP3播放录音测试例程,将1.mp3文件拷入到2G SD卡根目录下面,将SD卡

    插在开发板上面,插上3.2寸彩屏模块,下载程序到开发板,彩屏显示按键功能信息,

    SD卡初始化成功后彩屏显示对应信息,按下INT0键开始录音,按下Key1键结束录音并播放录音

    文件,按下Key2键播放1.mp3文件

    

    注意:这里录音使用外接麦克风,开发板默认没有配置该麦克风,需要用户另行购买焊接。


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

  * Company: Wang Electronic Technology Co., Ltd.

  ******************************************************************************

  * 文件名称:main.c

  * 功能说明:mp3播放录音

  * 版    本:V1.1

        * 作    者:jeansonm        

  * 日    期:2014-4-26

********************************************************************************

  * 文件名称:

  * 功能说明:

  * 版    本:

        * 更新作者:        

  * 日    期:

        * 更新原因:

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

#include                                            

#include 'LCD.h'

#include 'string.h'

#include 'sys.h'

#include 'lcd.h'

#include 'ff.h'

#include 'config.h'

#include 'vs1003.h'

#include 'mp3.h'

#include 'MMC_SD.h'

#include 'delay.h'

#include 'ssp0.h'

#include 'adc.h'


u8 MusicNumber;

u8 temp;

u8 count=0;


u32 datasize=0;           


FATFS fs;            // Work area (file system object) for logical drive

FIL fsrc, fdst,fap,file;      // file objects

FRESULT res,re;         // FatFs function common result code

UINT br, bw,bt;;         // File R/W count

FILINFO finfo,fno;

DIR dirs;


u8 buffer[1024]; // file copy buffer

u8 flag=0;


uint8_t wav_dat[512]={0};

static u8 status=0;

/** first part of RIFF Header, insert 444 zeroes after this */ 

unsigned char RIFFHeader0[52] = {'R' , 'I' , 'F' , 'F' , //资源交换文件标志(RIFF)

                                      0x70, 0x70, 0x70, 0x70, //从下一个地址开始到文件尾总字节数 (calculate after rec!)

                                      'W' , 'A' , 'V' , 'E' , //wav文件格式

                                      'f' , 'm' , 't' , ' ' , //波形格式标志(fmt )

                                      0x14, 0x00, 0x00, 0x00, //量化结果 (0x14 = 20 bytes)

                                      0x11, 0x00,             // 有无压缩编码 (IMA ADPCM)

                                      0x01, 0x00,             // 通道数 单声道 (1)

                                      0x40, 0x1f, 0x00, 0x00, //采样频率, 0x1f40 = 8.0kHz

                                      0xd7, 0x0f, 0x00, 0x00, //比特率

                                      0x00, 0x01,             //块数据大小(256 bytes) 

                                      0x04, 0x00,             //样本数据位数(4 bits)

                                      0x02, 0x00,             // Extra data (2 bytes)

                                      0xf9, 0x01,             // Samples per Block (505 samples)

                                      'f' , 'a' , 'c' , 't' , // Chunk ID (fact)

                                      0xc8, 0x01, 0x00, 0x00, // Chunk payload size (456 bytes (zeropad!))

                                      0xff, 0xff, 0xff, 0xff  // Number of Samples (calculate after rec!)

                                     };                       // Insert 448 zeroes here!


                                     //add 452 zeros after


unsigned char RIFFHeader504[8] = {'d' , 'a' , 't' , 'a' , // Chunk ID (data)

                                       0x70, 0x70, 0x70, 0x70  // Chunk payload size (calculate after rec!)

                                      };

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

** Function name:       ReFresh

** Descriptions:        屏幕更新

** input parameters:    p 显示信息字符串

** output parameters:   无

** Returned value:      无

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

void ReFresh(u8 *p)

{

        LCD_Clear(Black);                        //清屏

        LCD_DisplayString(60,30,'WB-Beemer Record');

        LCD_DisplayString(60,50,'INT0:Start Record');

        LCD_DisplayString(60,70,'Key1:Save & Paly');

        LCD_DisplayString(60,90,'Key2:Paly 1.mp3');

        LCD_DisplayString(60,110,p);

}

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

** Function name:       BUTTON_init

** Descriptions:        按键初始化

** input parameters:    无

** output parameters:   无

** Returned value:      无

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

void BUTTON_init(void) 

{

  LPC_GPIO2->FIODIR      &= ~(1 << 10);    //初始化端口P2.10为输入

  LPC_GPIOINT->IO2IntEnF |=  (1 << 10);    //使能下降沿中断

        

        LPC_GPIO2->FIODIR      &= ~(1 << 11);    //初始化端口P2.10为输入

  LPC_GPIOINT->IO2IntEnF |=  (1 << 11);    //使能下降沿中断

        

        LPC_GPIO2->FIODIR      &= ~(1 << 12);    //初始化端口P2.10为输入

  LPC_GPIOINT->IO2IntEnF |=  (1 << 12);    //使能下降沿中断


  NVIC_EnableIRQ(EINT3_IRQn);              //利用IO口来做中断,这种与EINT3通道相同

}

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

** Function name:       EINT3_IRQHandler

** Descriptions:        外部中断函数

** input parameters:    无

** output parameters:   无

** Returned value:      无

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

void EINT3_IRQHandler()                                          

{

        u32 Int_status=0;

        Int_status=LPC_GPIOINT->IO2IntStatF;

        if(Int_status & (1<<10))

        {

                LPC_GPIOINT->IO2IntClr |= (1 << 10);     //清除中断标志位         

                status=1;

        }

        else if(Int_status & (1<<11))

        {

                LPC_GPIOINT->IO2IntClr |= (1 << 11);     //清除中断标志位   

                status=2;

        }

        else if(Int_status & (1<<12))

        {

                LPC_GPIOINT->IO2IntClr |= (1 << 12);     //清除中断标志位   

                status=3;

        }

}

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

** Function name:       recoder_enter_rec_mode

** Descriptions:        进入录音模式

** input parameters:    agc 增益

** output parameters:   无

** Returned value:      无

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

void recoder_enter_rec_mode(u16 agc)

{                

                Vs1003_CMD_Write(SPI_AICTRL0,0x0012);        //设置采样率,设置为8Khz

                Vs1003_CMD_Write(SPI_AICTRL1,agc);                //设置增益,0,自动增益.1024相当于1倍,512相当于0.5倍,最大值65535=64倍                

                Vs1003_CMD_Write(SPI_MODE,0x3804);                //MIC,录音激活

                Vs1003_CMD_Write(SPI_BASS,0x0000);

                Vs1003_CMD_Write(SPI_CLOCKF,0X9800);

                delay_ms(200);        

}

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

** Function name:       recoder_play

** Descriptions:        开始录音

** input parameters:    无

** output parameters:   无

** Returned value:      无

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

u8 recbuf[512]={0};        

void recoder_play(void)

{

                u8 res;

                u8 key;

                u32 sectorsize=0,CAL=0;

                u32 sectorCount=1;

                int i=0;

                 

                u16 w;

                u16 idx=0;            

                recoder_enter_rec_mode(0x1000);

                while(Vs1003_REG_Read(SPI_HDAT1)>>8);                                


                res=f_open(&fsrc,'test.wav', FA_CREATE_ALWAYS | FA_WRITE); 

                f_write(&fsrc,(const void*)wav_dat,sizeof(wav_dat),&bw);//写入头数据


                ReFresh('Recode');

                while(status == 1)

                {         

                                idx=Vs1003_REG_Read(SPI_HDAT1);

                                if((idx>=256)&&(idx<896))

                                {                

                                        idx=0;                                        

                                        while(idx<512)         //一次读取512字节

                                        {         

                                                w=Vs1003_REG_Read(SPI_HDAT0);                                               

                                                recbuf[idx++]=w>>8;

                                                recbuf[idx++]=w&0xFF;

                                        }                        

                                        res=f_write(&fsrc,recbuf,512,&bw);//写入文件

                                        if(res)

                                        {                                

                                                ReFresh('write error');                                        

                                        }                

                                        sectorsize++;

                                }

                }

                Vs1003SoftReset();

                for(i=0;i<56;i++)

                { 

                        wav_dat[i]=RIFFHeader0[i];

                }


                for(i=52;i<504;i++)

                {

                        wav_dat[i]=0;

                }


                for(i=504;i<512;i++)

                {

                        wav_dat[i]=RIFFHeader504[i-504];

                }

                

                CAL=(sectorsize-1)*1010;                 

                wav_dat[48]=(CAL&0xff); 

                wav_dat[49]=((CAL>>8)&0xff); 

                wav_dat[50]=((CAL>>16)&0xff); 

                wav_dat[51]=((CAL>>24)&0xff); 


                CAL=(sectorsize*512)-8;   //总长度,RIFF块后(整个wav文件大小-8) 

                wav_dat[4]=(CAL&0xff); 

                wav_dat[5]=((CAL>>8)&0xff); 

                wav_dat[6]=((CAL>>16)&0xff); 

                wav_dat[7]=((CAL>>24)&0xff); 


                CAL = (sectorsize-1)*512; //真实录音数据大小,Data块后

                wav_dat[508]=(CAL&0xff); 

                wav_dat[509]=((CAL>>8)&0xff); 

                wav_dat[510]=((CAL>>16)&0xff); 

                wav_dat[511]=((CAL>>24)&0xff);

                f_lseek(&fsrc,0);                                                        //偏移到文件头.

                f_write(&fsrc,(const void*)wav_dat,sizeof(wav_dat),&bw);//写入头数据

                f_close(&fsrc);

                sectorsize=0;


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

** Function name:       Fatfs_test

** Descriptions:        文件系统写测试

** input parameters:    无

** output parameters:   无

** Returned value:      无

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

void Fatfs_test(void)

{

                u16 i;

                for(i=0;i<=512;i++)

                        recbuf[i]=i;

                res=f_open(&fsrc,'321.txt', FA_OPEN_ALWAYS | FA_WRITE ); 

                if(res)

                {                                

                        ReFresh('open error');        

                        f_close(&fsrc);                                

                        while(1);

                }

                for(i=0;i<512;i++)

                {

                        res=f_write(&fsrc,recbuf,512,&bw);//写入文件

                        if(res)

                        {                                

                                ReFresh('test error');                

                                f_close(&fsrc);                                

                                while(1);

                        }

                }

                f_close(&fsrc);

                ReFresh('test ok');

}

        

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

**   Main Function  main()

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

int main (void)                       

{                  

        u8 i;

        u16 AD_value,AD_Old_value;

        SystemInit();

        LCD_Init();                                                //LCD初始化

        LCD_SetTextColor(Red);//设置字体为红色

        LCD_SetBackColor(Black);        //设置背景色为黑色        

        Vs1003_Init();                                //vs1003引脚初始化

        Vs1003SoftReset();                //vs1003软件复位

        

        ReFresh('');                                        //刷新屏幕

        USER_ADC_Init();

        BUTTON_init();

                     

        res=SD_Init();                                                 //初始化SD卡

        if(res==0)

                ReFresh('SD Init OK!!');

        f_mount(0,&fs);                                //挂载文件系统 

        res=f_opendir(&dirs, '/');


//        VsSineTest(); //正弦波测试  ,会听到滴答声 ,说明VS1003 初始化通过


//        Fatfs_test();        //文件系统读写测试

  while(1)

  {                         

                if(status == 1)

                {

                                recoder_play();                        

                }

                else if(status == 2)

                {

                                ReFresh('Save and Play');        

                                bw = f_open(&fsrc,'test.wav',FA_OPEN_EXISTING | FA_READ);

                                datasize=0;

                                while(status == 2)

                                {

                                        if(datasize>=fsrc.fsize)                //到达文件尾播放完成

                                                break;

                                        if(count++==10)

                                        {

                                                count=0;

                                                AD_value=USER_ADC_Get();        //获取AD转换值

                                                if(abs(AD_value-AD_Old_value)>30) 

                                                {

                                                                AD_Old_value = AD_value;

                                                                AD_value=((AD_value*255)/4096);

                                                                AD_value<<=8;                

                                                                AD_value+=((AD_Old_value*255)/4096);          

                                                                Vs1003_CMD_Write(SPI_VOL,AD_value); //设音量 高八位为左声道 第八位为右声道,这里相同

                                                }

                                        }

                                        datasize+=512;                                                                         //要放到上面

                                        bw = f_read(&fsrc,buffer,512,&br);                //读取512字节

                                        for(i=0;i<16;i++)

                                        {         

                                                while(!(LPC_GPIO0->FIOPIN&MP3_DREQ)); 

                                                Vs1003_DATA_Write(buffer+i*32);

                                        }                

                                }

……………………


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • PIC单片机控制的遥控防盗报警器电路

  • RS-485基础知识:处理空闲总线条件的两种常见方法

  • 带有短路保护系统的5V直流稳压电源电路图

  • 如何构建一个触摸传感器电路

  • 如何调制IC555振荡器

  • 基于ICL296的大电流开关稳压器电源电路

    相关电子头条文章