我是靠谱客的博主 甜甜绿茶,最近开发中收集的这篇文章主要介绍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 }

 

转载于:https://www.cnblogs.com/zpehome/archive/2013/05/05/2957860.html

最后

以上就是甜甜绿茶为你收集整理的TQ2440之DMA+IIS的全部内容,希望文章能够帮你解决TQ2440之DMA+IIS所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部