• TQ2440之DMA+IIS


    DMA(Direct Memory Access,直接内存访问)是一种不经过CPU而直接从内存存取数据的数据交换模式。在需要进行大量数据交换的场合,用好DMA,可以大大提高系统的性能,因为DMA操作几乎不占用CPU资源。

    由于是用DMA的方式,因此在播放的过程中不占用系统资源,我们可以很容易的实现声音的各种操作而丝毫不影响播放的效果,如音量的提高和降低、静音、暂停等。

    定义变量:

    static int remainder;
    static char mute;
    static char volume;

    中断函数,当DMA传送完成时打印Success。

    static void __irq PlayDMA2Done(void)
    {
        ClearPending(BIT_DMA2);            
    Uart_Printf(
    "Success"); }

    放音:

    void playsound(unsigned char *buffer, int length)
    {
    //用于计算音频数据的长度是否超过DMA所能传输的字节数范围
     //这里音频数据的通道位数为16位,因此需要length除以2
     remainder = (length>>1) & 0xfffff; 
     rGPBDAT = rGPBDAT & ~(L3M|L3C|L3D) |(L3M|L3C); //L3开始传输:L3M=H, L3C=H
     
     //配置UDA1341
     WriteL3(0x14 + 2,1);            //状态模式(000101xx+10)
     WriteL3(0x60,0);          //0,1,10, 000,0 : 状态0,复位
     
     WriteL3(0x14 + 2,1);            //状态模式 (000101xx+10)
     WriteL3(0x10,0);          //0,0,01, 000,0 : 状态0, 384fs,IIS,no DC-filtering
     
     WriteL3(0x14 + 2,1);     //状态模式 (000101xx+10)
     WriteL3(0xc1,0);           //1,0,0,0, 0,0,01:状态1,
     //Gain of DAC 6 dB,Gain of ADC 0dB,ADC non-inverting,
     //DAC non-inverting,Single speed playback,ADC-Off DAC-On
     
     //配置s3c2440的IIS寄存器
    //fs=22.05kHz,CODECLK=384fs=8.4672MHz
    //预分频器为3,所以CDCLK=PCLK/(3+1)
    rIISPSR = 3<<5|3; //发送DMA使能,输入空闲,预分频器有效 rIISCON = (1<<5)|(0<<4)|(0<<3)|(1<<2)|(1<<1); //PCLK为时钟源,输出模式,IIS模式,每个声道16位,CODECLK=384fs,SCLK=32fs rIISMOD =(0<<9)|(0<<8)|(2<<6)|(0<<5)|(0<<4)|(1<<3)|(1<<2)|(1<<0); rIISFCON = (1<<15)|(1<<13); //输出FIFODMA模式,输出FIFO使能 //配置DMA rDISRC2 = (U32)buffer; //DMA的源基址为音频数据数组的首地址 rDISRCC2 = (0<<1)|(0<<0); //AHB,源地址递增 rDIDST2 = (U32)IISFIFO; //DMA的目的基址为IIS的FIFO rDIDSTC2 = (0<<2)| (1<<1)|(1<<0);//当传输计数值为0时中断,APB,目的地址不变 //握手模式,PCLK同步,传输计数中断,单元传输,单步服务模式,IISSDO, //硬件请求模式,自动重载,半字, rDCON2 = (1<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(0<<24)|(1<<23)|(0<<22)|(1<<20)|(remainder); rDMASKTRIG2=(0<<2)|(1<<1)|0; //不停止DMA,DMA通道开启,非软件触发 pISR_DMA2 = (U32)PlayDMA2Done; EnableIrq(BIT_DMA2); //启动IIS rIISCON |= 0x1; }

    开始播放:

    void PlayMusicTest(void)
    {
        //配置MPLL
        //fs=22.05
        rMPLLCON = (150<<12) | (5<<4) | 1;
        
        //配置L3接口总线,GPB2:L3MODE, GPB3:L3DATA, GPB4:L3CLOCK
        rGPBCON = 0x015550;               //输出
        rGPBUP  = 0x7ff;               //上拉无效
        rGPBDAT = 0x1e4;
    
        
        //配置IIS接口
        rGPEUP = rGPEUP & ~(0x1f) | 0x1f;         //上拉无效,GPE[4:0] 1 1111
        rGPECON = rGPECON & ~(0x3ff) | 0x2aa;
    
        rSRCPND = (0x1<<19);
        rSUBSRCPND = 0x1;
        rINTPND = (0x1<<19);
        rINTSUBMSK = ~(0x1);
        rINTMSK = ~(0x1<<19);//开启DMA2中断屏蔽
        Uart_Init(33857000,115200);//根据PCLK设置波特率
        Uart_Printf("nNOW PLAY THE WindowsXP");
        Uart_Printf("nsample=%d",*(U32 *)(WindowsXP_Wav+0x18));//输出采样频率
        playsound(WindowsXP_Wav+44,sizeof(WindowsXP_Wav)-44);//在数据开始处开始播放
    
        while(1)
        {
            U8 key = Uart_Getch();
            if(key == ESC_KEY)
                break;    
            if(key == 'p')  //暂停        
         { rIISCON
    ^= 0x1; } if(key == 'm') { mute ^= 0x4;
           mute |= 0x80; WriteL3(
    0x14 + 0,1); //DATA0 (000101xx+00) WriteL3(mute,0); //10,1,00,x,00:x,静音 } if(key == '+') { if(volume>0) { volume --; WriteL3(0x14 + 0,1); //DATA0 (000101xx+00) WriteL3(volume,0); //音量提高 } } if(key == '-') { if(volume<61) { volume++; WriteL3(0x14 + 0,1); //DATA0 (000101xx+00) WriteL3(volume,0); //音量降低 } } } rIISCON = 0x0; //停止IIS rIISFCON = 0x0; //清IIS的FIFO rDMASKTRIG2=1<<2; //终止DMA2 }
  • 相关阅读:
    「消息队列」看过来!
    stl中map的四种插入方法总结
    4.shell编程-文本处理三剑客之sed
    3.shell编程-文件查找之find命令
    2.shell编程-函数的高级用法
    1.shell编程-变量的高级用法
    Django打造大型企业官网(八)
    Django打造大型企业官网(七)
    Django打造大型企业官网(六)
    Django打造大型企业官网(五)
  • 原文地址:https://www.cnblogs.com/zpehome/p/2957860.html
Copyright © 2020-2023  润新知