发新帖我要提问
12
返回列表
打印
[应用相关]

STM32 读取 WAV音频格式 播放出来

[复制链接]
楼主: hanzhen654
手机看帖
扫描二维码
随时随地手机跟帖
21
hanzhen654|  楼主 | 2019-7-31 14:24 | 只看该作者 回帖奖励 |倒序浏览
定时器初始化:

void Timerx_Init(u16 arr,u16 psc)

{

       NVIC_InitTypeDef NVIC_InitStructure;

      

       RCC->APB1ENR|=1<<1;//TIM3时钟使能  

      TIM3->ARR=arr;  //设定计数器自动重装值   

       TIM3->SC=psc;  //预分频器7200,得到10KHz的计数时钟

       TIM3->DIER|=1<<0;   //允许更新中断         

       TIM3->DIER|=1<<6;   //允许触发中断

                                                                  

       TIM3->CR1|=0x01;    //使能定时器3

      

       //优先级设置

      NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

       NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

       NVIC_Init(&NVIC_InitStructure);

}

使用特权

评论回复
22
hanzhen654|  楼主 | 2019-7-31 14:24 | 只看该作者
DAC初始化:

#include "dac.h"



extern u16 digital;



void MyDAC_Init(void)//DAC channel1 Configuration

{

    unsigned int tmpreg1=0,tmpreg2=0;

      RCC->APB2ENR|=1<<2;//使能PORTA时钟

       RCC->APB1ENR|=RCC_APB1Periph_DAC;//使能DAC时钟

      GPIOA->CRL&=0XFFF0FFFF;

       GPIOA->CRL|=0X00040000;//PA4浮空输入   



    tmpreg1=DAC->CR;//Get the DAC CR value

    tmpreg1&=~(CR_CLEAR_Mask<<DAC_Channel_1);

  tmpreg2=(DAC_Trigger_Software|DAC_WaveGeneration_None|DAC_LFSRUnmask_Bits8_0|DAC_OutputBuffer_Enable);

    tmpreg1|=tmpreg2<<DAC_Channel_1;

    DAC->CR=tmpreg1;//Write to DAC CR

     DAC->CR|=CR_EN_Set<<DAC_Channel_1;//DAC通道1使能,PA4自动连接到DAC

       DAC1_SetData(0x000);



       #if 0

    tmpreg1=DAC->CR;//Get the DAC CR value

    tmpreg1&=~(CR_CLEAR_Mask<<DAC_Channel_2);  tmpreg2=(DAC_Trigger_Software|DAC_WaveGeneration_None|DAC_LFSRUnmask_Bits8_0|DAC_OutputBuffer_Enable);

tmpreg1|=tmpreg2<<DAC_Channel_2;

DAC->CR=tmpreg1;

       DAC->CR|=CR_EN_Set<<DAC_Channel_2;

       DAC2_SetData(0x000);

       #endif

}

void DAC1_SetData(u16 data)

{

       DAC->DHR12R1=data;//通道1的12位右对齐数据

       DAC->SWTRIGR|=0x01;//软件启动转换

}

void DAC2_SetData(u16 data)

{

       DAC->DHR12R2=data;//通道2的12位右对齐数据

       DAC->SWTRIGR|=0x02;//软件启动转换

}

使用特权

评论回复
23
hanzhen654|  楼主 | 2019-7-31 14:24 | 只看该作者
定时器中断服务程序:

void TIM3_IRQHandler(void)

{                                                      

       u16 temp;

       if(TIM3->SR&0X0001)//溢出中断

       {

              if(CHanalnum==1)//单声道

              {

                     if(Bitnum==8)//8位精度

                     {

                            DAC->DHR12R1=wav_buf[DApc]*10/volume;

                            DAC->DHR12R2=wav_buf[DApc]*10/volume;

                            DAC->SWTRIGR |=0x01;                        

DApc++;

                     }

                     else if(Bitnum==16)                    

{

               temp=(((u8)(wav_buf[DApc+1]-0x80)<<4)|(wav_buf[DApc]>>4))*10/volume;

                        DAC->DHR12L1=temp;

                        DAC->DHR12L2=temp;

                        DAC->SWTRIGR|=0x01;

                        DApc+=2;                     

                     }

              }

              else if(CHanalnum==2)

              {

                     if(Bitnum==8)

                     {

                            DAC->DHR12R1=wav_buf[DApc]*10/volume;

                            DApc++;

                            DAC->DHR12R2=wav_buf[DApc]*10/volume;

                            DApc++;

                            DAC->SWTRIGR|=0x01;                  

}

                     else if(Bitnum==16)

                     {            DAC->DHR12L1=(((u8)(wav_buf[DApc+1]-0x80)<<4)|(wav_buf[DApc]>>4))*10/volume;                       DApc+=2;             DAC->DHR12L2=(((u8)(wav_buf[DApc+1]-0x80)<<4)|(wav_buf[DApc]>>4))*10/volume;

                            DApc+=2;                  

DAC->SWTRIGR|=0x01;           

                     }

              }           

              if(DApc==16384)

        {

        DApc=0;

        DACdone=1;

    }                                                                                                        

       }                           

       TIM3->SR&=~(1<<0);  

}

使用特权

评论回复
24
hanzhen654|  楼主 | 2019-7-31 14:26 | 只看该作者
WAV初始化:

u8 WAV_Init(u8* wav_buf)

{

       if(Check_Ifo(wav_buf,"RIFF"))

              return 1;

       wav1.wavlen=Get_num(wav_buf+4,4);

       printf("\n\rwav1.wavlen = %ld\n\r",wav1.wavlen);

//if(Check_Ifo(wav_buf+8,"WAVE"))return 2;//WAVE错误标志

//if(Check_Ifo(wav_buf+12,"fmt "))return 3;//fmt错误标志

       wav1.formart=Get_num(wav_buf+20,2);//格式类别

       printf("\n\rwav1.formart = %d\n\r",wav1.formart);

      

       wav1.CHnum=Get_num(wav_buf+22,2);//通道数

       printf("\n\rwav1.CHnum = %d\n\r",wav1.CHnum);

       CHanalnum=wav1.CHnum;

      

       wav1.SampleRate=Get_num(wav_buf+24,4);//采样率

       printf("\n\rwav1.SampleRate = %ld\n\r",wav1.SampleRate);

      

       wav1.speed=Get_num(wav_buf+28,4);//音频转换数率

       printf("\n\rwav1.speed = %ld\n\r",wav1.speed);

      

       wav1.ajust=Get_num(wav_buf+32,2);//数据块调速数

       printf("\n\rwav1.ajust = %d\n\r",wav1.ajust);

      

       wav1.SampleBits=Get_num(wav_buf+34,2);//样本数据位数

       printf("\n\rwav1.SampleBits = %d\n\r",wav1.SampleBits);

       Bitnum=wav1.SampleBits;

      

//if(Check_Ifo(wav_buf+36,"data"))return 4;//数据标志错误

      

       wav1.DATAlen=Get_num(wav_buf+40,4);//数据长度

       printf("\n\rwav1.DATAlen = %d\n\r",wav1.DATAlen);

      

       if(wav1.wavlen<0x100000)

       {

              printf("\n\rwav1.wavlen = %dkb\n\r",(wav1.wavlen)>>10);

       }

       else

       {

              printf("\n\rwav1.wavlen = %dMb\n\r",(wav1.wavlen)>>20);

       }

       if(wav1.formart==1)

              printf("\n\rWAV PCM\n\r");

       if(wav1.CHnum==1)

              printf("\n\rsingle\n\r");

       else

              printf("\n\rstereo\n\r");

       printf("\n\rwav1.SampleRate = %dkHz\n\r",(wav1.SampleRate)/1000);

       printf("\n\rwav1.speed = %dbps\n\r",(wav1.speed)/1000);

       printf("\n\rwav1.SampleBits = %dbit\n\r",wav1.SampleBits);

      

       return 0;

}

u8 Check_Ifo(u8* pbuf1,u8* pbuf2)

{

       u8 i;

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

              if(pbuf1!=pbuf2)

                     return 1;

       return 0;

}



u32 Get_num(u8* pbuf,u8 len)

{

  u32 num;

       if(len==2)num=(pbuf[1]<<8)|pbuf[0];

       else if(len==4)num=(pbuf[3]<<24)|(pbuf[2]<<16)|(pbuf[1]<<8)|pbuf[0];

       return num;

}

使用特权

评论回复
25
hanzhen654|  楼主 | 2019-7-31 14:26 | 只看该作者
WAV播放:

u8 Playwav(char *file)

{

       FIL fwav;

       FRESULT Res;

       UINT BR;

       unsigned char i;

       unsigned int times;

       Res = f_open(&fwav, file, FA_OPEN_EXISTING | FA_READ);

       if(Res != FR_OK)

  {

              printf("\n\ropen file error : %d\n\r",Res);

       }

       else

  {

         Res = f_read(&fwav, wav_buf, sizeof(wav_buf), &BR);     /* Read a chunk of src file */

    if(Res==FR_OK)

    {

                     WAV_Init(wav_buf);

                     DACdone=0;

                     DApc=44; //跳过头信息            

                     Timerx_Init(1000000/wav1.SampleRate,72); //定时器初始化

                     times=(wav1.DATAlen>>10)-1; //计算数据大小              

                    

                     for(i=0;i<times/32;i++)//循环一次转换32KB数据

                     {   

                            while(!DACdone);//等待前面16384字节转换完成                                                   DACdone=0;

                            Res = f_read(&fwav, wav_buf, 16384, &BR);

                            while(!DACdone);// 等待前面16384字节转换完成

                            DACdone=0;

                            Res = f_read(&fwav, wav_buf, 16384, &BR);//读取数据

                     }

              }

              else

              {

                     printf("\n\rread file error : %d\n\r",Res);

              }

              f_close(&fwav);

       }

       return 0;

}

使用特权

评论回复
26
hanzhen654|  楼主 | 2019-7-31 14:27 | 只看该作者
原帖出至:基于STM32的WAV音频格式播放器
http://www.openedv.com/forum.php?mod=viewthread&tid=32875&fromuid=45262
(出处: OpenEdv-开源电子网)

使用特权

评论回复
27
adg4510| | 2019-8-10 10:55 | 只看该作者
楼主你好,你定时器中断设置的溢出时间是多少啊

使用特权

评论回复
28
labasi| | 2019-8-15 11:05 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
29
paotangsan| | 2019-8-15 11:07 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
30
renzheshengui| | 2019-8-15 11:15 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则