⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 music.c

📁 基于华邦W90P710 arm开发板的AC97模块测试程序
💻 C
字号:
#include"710defs.h"
#include"AC97.h"
#include"HB_it.h"
/*播放缓冲区的首地址*/
#define base_addres  0x100000
/*播放数据*/
UINT8 PlayData[] = {
                    #include "8k.dat"
                   };
UINT32 PCM_QUEUE_LEN = (512*1024);
UINT _uPlayVol = 0x1f1f;
UINT16 sPlayVolume = 0;
BOOL PlayLastBlock;
volatile UINT _uPcmQHead;


/*延时函数*/
static void Delay(int nCnt)
{
    volatile int  loop;
    for (loop=0; loop<nCnt; loop++);
}


/*播放函数*/
INT PlayCallback(UINT8 *pucBuff, UINT32 uDataLen)
{
    UINT nLen;
    nLen = PCM_QUEUE_LEN - _uPcmQHead;
    
    /*将数据从PCM队列中取出放到DMA缓存区*/
    if (nLen >= uDataLen)
    {
        memcpy(pucBuff, &PlayData[_uPcmQHead], uDataLen);
        _uPcmQHead = (_uPcmQHead + uDataLen) % PCM_QUEUE_LEN;
    }
    else
    {
        memcpy(pucBuff, &PlayData[_uPcmQHead], nLen);
        memcpy(&pucBuff[nLen], PlayData, uDataLen - nLen);
        _uPcmQHead = uDataLen - nLen;

    }
    return 0;
}



/* 读AC97寄存器*/
static UINT16 ac97_read_register(INT nIdx)
{
    UINT volatile nWait;
    
    /* 置起R_WB位并写入寄存器地址 */
    REG_ACTL_ACOS1 = (0x80 | nIdx);
    
    /* 设置帧是否有效和有效的时隙 */
    REG_ACTL_ACOS0 = 0x11;
    Delay(100);
    
    /* 检查AC_ACTL_ACCON的AC_R_FINISH位是否被置高,若被置高,说明读数据缓存区已经准备好给CPU读取 */
    for (nWait = 0; nWait < 0x10000; nWait++)
    {
        if (REG_ACTL_ACCON & AC_R_FINISH)
            break;
    }


    REG_ACTL_ACOS0 = 0;
    Delay(100);        
    return (REG_ACTL_ACIS2 & 0xFFFF);
}



/* 写AC97寄存器*/
static INT ac97_write_register(INT nIdx, UINT16 sValue)
{
    volatile UINT    nWait;
    /* 清R_WB位并写入寄存器地址*/
    REG_ACTL_ACOS1 = nIdx;
    
    /* 写入AC97寄存器的值*/
    REG_ACTL_ACOS2 = sValue;
    
    /* 设置帧的有效位和有效的时隙*/
    REG_ACTL_ACOS0 = 0x13;
    
    Delay(100);
    
    /* 检查AC_ACTL_ACCON的AC_W_FINISH位,若被清零,说明AC-LINK控制数据输出缓存已经被CPU移到编解码器*/
    for (nWait = 0; nWait < 0x10000; nWait++)
    {
        if (!(REG_ACTL_ACCON & AC_W_FINISH))
            break;
    }
   
    /*若读回的值和写入的值相同,则说明写入成功*/ 
   if (ac97_read_register(nIdx) != sValue)
   {while(1)
     ;
   }
    
    REG_ACTL_ACOS0 = 0;

    return 0;
}


/*初始化AC97*/
UINT8 Initac97()
{
 
    /*使能音频控制器和AC-LINK接口*/
    REG_ACTL_CON = REG_ACTL_CON | IIS_AC_PIN_SEL | AUDIO_EN | ACLINK_EN | PFIFO_EN | RFIFO_EN | T_DMA_IRQ | R_DMA_IRQ | DMA_EN;
    Delay(1000);
    /*stereo模式*/
    REG_ACTL_RESET = REG_ACTL_RESET | 0x3000;

       

    /* 重启音频控制器 */
    REG_ACTL_RESET = REG_ACTL_RESET | ACTL_RESET_BIT;
    Delay(1000);
    REG_ACTL_RESET = REG_ACTL_RESET & ~ACTL_RESET_BIT;
    Delay(1000);


    
    /* 重启AC97接口 */
    REG_ACTL_RESET = REG_ACTL_RESET | AC_RESET;
    Delay(1000);

    REG_ACTL_RESET = REG_ACTL_RESET & ~AC_RESET;
    Delay(1000);


    /* 冷启动AC97 */
    REG_ACTL_ACCON = REG_ACTL_ACCON | AC_C_RES;
    Delay(1000);
    REG_ACTL_ACCON = REG_ACTL_ACCON & ~AC_C_RES;
    Delay(1000);
    
    /* 检查AC97的ACTL_ACIS0的CODEC_READY位,若置起则说明AC97准备好了 */
    if (!(REG_ACTL_ACIS0 & 0x10))
    {
        while(1);

    }

    Delay(100);

    /*选择麦克 1;3D控制 关;looback 关*/
    ac97_write_register(AC97_GENERAL_PURPOSE, 0);
    
    return 0;    
}






UINT8 StartPlay(INT nSamplingRate)
{
       
    /* 使能VRA(variable rate audio)并设置播放采样率*/
    ac97_write_register(AC97_EXT_AUDIO_CTRL, ac97_read_register(AC97_EXT_AUDIO_CTRL)|0x1);
    ac97_write_register(AC97_FRONT_DAC_RATE, nSamplingRate);
    
     /*设置DMA基地址和目的地址长度*/
    REG_ACTL_PDSTB = base_addres; 
    REG_ACTL_PDST_LENGTH = 0x1000; 
    
    PlayLastBlock = 0;
    
    /* 开始播放 */
    REG_ACTL_ACOS0 = 0x1c; //设置数据传输时隙有效
    REG_ACTL_PSR = 0x3;
    REG_ACTL_RESET = REG_ACTL_RESET | AC_PLAY;
    return 0;
}


  /* 设置音量 */
INT SetPlayVolume(UINT8 ucLeftVol, UINT8 ucRightVol) 
{
    INT    nLData, nRData;

    if (ucLeftVol == 0)
        nLData = 0x80;
    else
        nLData = 31 - (ucLeftVol & 0x1f);
        
    if (ucRightVol == 0)
        nRData = 0x80;
    else
        nRData = 31 - (ucRightVol & 0x1f);

    sPlayVolume = (nLData << 8) | nRData;
        
    if (ucLeftVol == 0)
        nLData = 0x80;
    else
        nLData = 62 - ucLeftVol*2;
        
    if (ucRightVol == 0)
        nRData = 0x80;
    else
        nRData = 62 - ucRightVol*2;
    
    _uPlayVol = (nLData << 8) | nRData;
    
    /* 设置音量 */
    ac97_write_register(AC97_PCM_OUT_VOLUME, sPlayVolume ); //PCM数据输出音量
    ac97_write_register(AC97_AUX_OUT_VOLUME, _uPlayVol); //耳机音量设置
    ac97_write_register(AC97_MASTER_VOLUME, _uPlayVol); //全局音量设置

    return 0;


}



UINT8 StopPlay()
{
    
    /* 停止播放 */
    REG_ACTL_RESET = REG_ACTL_RESET & ~AC_PLAY;
    REG_ACTL_ACOS0 = 0;
    
    /*关闭音频播放中断 */
    REG_AIC_MDCR = REG_AIC_MDCR | 0x40;

    
    return 0;
}





int main(void)
{
 PCM_QUEUE_LEN = sizeof (PlayData);
 _uPcmQHead = 0;
 
  /* 设置I/O连接到音频 */
 REG_GPIO_CFG0 = 0x155; 
  /*// GPIO4,1:输入      GPIO0,2,3:输出 */                         
 REG_GPIO_DIR0 = 0xd;
                         
  /*使能音频时钟 */
 REG_CLKSEL = REG_CLKSEL|0x10000;                

 Initac97();
 
  /* 使能AC97播放中断 */
 REG_AIC_SCR6 = 0x41;                       
 REG_AIC_MECR = 0x40;                       

 SetPlayVolume(30,30);
 
 StartPlay(8000);
 
  /* 检查是否播放完成 */
 while(1)
 {
  if (_uPcmQHead >= (PCM_QUEUE_LEN-4096))
  break;
  }
 StopPlay();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -