在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            s3c2440的DMA應(yīng)用

            作者: 時(shí)間:2016-11-19 來源:網(wǎng)絡(luò) 收藏
            DMA(Direct Memory Access,直接內(nèi)存訪問)是一種不經(jīng)過CPU而直接從內(nèi)存存取數(shù)據(jù)的數(shù)據(jù)交換模式。在需要進(jìn)行大量數(shù)據(jù)交換的場合,用好DMA,可以大大提高系統(tǒng)的性能,因?yàn)镈MA操作幾乎不占用CPU資源。

            s3c2440提供了4個(gè)通道的DMA,它們不僅可以實(shí)現(xiàn)內(nèi)存之間的數(shù)據(jù)交換,還可以實(shí)現(xiàn)內(nèi)存與外設(shè),以及外設(shè)與外設(shè)之間的數(shù)據(jù)交換。要用好s3c2440的DMA,關(guān)鍵是配置好它的源、目的寄存器,和必要的控制寄存器。寄存器DISRCn是初始DMA源寄存器,它是用于設(shè)置DMA數(shù)據(jù)傳輸?shù)脑椿?,而寄存器DIDSTn是初始DMA目的寄存器,它是用于設(shè)置DMA數(shù)據(jù)傳輸?shù)哪康幕?。初始DMA源控制寄存器DISRCCn的第1位用于選擇源的總線(系統(tǒng)總線AHB還是外設(shè)總線APB),第0位用于設(shè)置源基址在數(shù)據(jù)傳輸過程中是遞增還是固定不變。初始DMA目的控制寄存器DIDSTCn的低兩位與寄存器DISRCCn相識,但它是用來設(shè)置目的基址,而第2位用于設(shè)置是在傳輸完數(shù)據(jù)之后中斷還是在自動重載后中斷。DMA控制寄存器DCONn用于控制數(shù)據(jù)的DMA傳輸,第31位用于設(shè)置傳輸協(xié)議是需求模式還是握手模式,第30位用于選擇同步時(shí)鐘是PCLK還是HCLK,第29位用于設(shè)置DMA中斷是否發(fā)生,第28位用于選擇傳輸大小是單元傳輸還是突發(fā)傳輸,第27位用于選擇服務(wù)模式是單步模式還是完全模式,第24位到第26位用于設(shè)置DMA的請求源,第23位用于設(shè)置DMA的源是軟件還是硬件,第22位用于設(shè)置是否需要重載傳輸?shù)哪康暮驮椿?,?0位和第21位用于設(shè)置數(shù)據(jù)傳輸?shù)臄?shù)據(jù)大小(字節(jié)、半字還是字),低20位用于初始化傳輸數(shù)據(jù)的個(gè)數(shù)。而通過讀取DMA狀態(tài)寄存器DSTATn的低20位可以獲知當(dāng)前的傳輸?shù)挠?jì)數(shù)。DMA掩碼觸發(fā)寄存器DMASKTRIGn的第2位可以終止當(dāng)前DMA操作,第1位可以用于開啟DMA通道,第0位則表示在軟件請求模式下觸發(fā)DMA通道。

            下面我們就用DMA的方式來實(shí)現(xiàn)音頻的播放。由于是用DMA的方式,因此在播放的過程中不占用系統(tǒng)資源,我們可以很容易的實(shí)現(xiàn)聲音的各種操作而絲毫不影響播放的效果,如音量的提高和降低、靜音、暫停等。在這里,還需要強(qiáng)調(diào)一點(diǎn),利用DMA傳輸數(shù)據(jù),一次最多可以傳輸?shù)淖止?jié)大小為:DSZ×TSZ×TC,DSZ表示的是數(shù)據(jù)大小(字節(jié)、半字還是字,即是1、2還是4),TSZ表示的是傳輸大?。▎卧獋鬏斶€是突發(fā)傳輸,即1還是4),TC表示傳輸計(jì)數(shù)值(即寄存器DCONn的低20位存放的數(shù)據(jù)),因此如果需要傳輸?shù)淖止?jié)大小超出了這三個(gè)參數(shù)乘積的大小,則還要進(jìn)一步處理,在我們給出的程序中,我們就考慮了這方面的問題。下面就是具體的程序,其中我們是利用UART來實(shí)現(xiàn)音頻信號的播出、停止、暫停、靜音、音量的提高和降低的。


            …………
            //一段純音頻數(shù)據(jù)數(shù)組
            unsigned char music[] = {
            0xF9, 0xFF, 0xF5, 0xFF, 0xF8, 0xFF, 0xF8, 0xFF, 0xF6, 0xFF, 0xFF, 0xFF, 0xF5, 0xFF, 0xF9, 0xFF,
            0xF6, 0xFF, 0xF6, 0xFF, 0xFA, 0xFF, 0xFD, 0xFF, 0xFA, 0xFF, 0xFA, 0xFF, 0xF7, 0xFF, 0xF6, 0xFF,
            …………
            };

            int result;
            int remainder;
            char flag;
            char cmd;
            char play_state;

            void __irq uartISR(void)
            {
            char ch;
            rSUBSRCPND |= 0x1;
            rSRCPND |= 0x1<<28;
            rINTPND |= 0x1<<28;
            ch=rURXH0;

            switch(ch)
            {
            case 0x55://播放
            cmd = 1;
            break;
            case 0x1://靜音
            cmd = 0x11;
            break;
            case 0x2://音量提高
            cmd = 0x12;
            break;
            case 0x3://音量降低
            cmd = 0x13;
            break;
            case 0x66://停止
            cmd = 0x2;
            break;
            case 0x77://暫停
            cmd = 0x3;
            break;
            }
            rUTXH0=ch;
            }

            //放音子程序
            void playsound(unsigned char *buffer,int length)
            {
            //用于計(jì)算音頻數(shù)據(jù)的長度是否超過DMA所能傳輸?shù)淖止?jié)數(shù)范圍
            //這里音頻數(shù)據(jù)的通道位數(shù)為16位,因此需要length除以2
            remainder = (length>>1) & 0xfffff;//余數(shù)
            result = (length>>1) / 0x100000;//商

            play_state = 1;//置播放標(biāo)志

            rGPBDAT = rGPBDAT & ~(L3M|L3C|L3D) |(L3M|L3C);

            //配置1341,詳細(xì)講解請看上一篇文章
            WriteL3(0x14 + 2,1);
            WriteL3(0x60,0);

            WriteL3(0x14 + 2,1);
            WriteL3(0x10,0);

            WriteL3(0x14 + 2,1);
            WriteL3(0xc1,0);

            //配置IIS
            rIISPSR= 3<<5|3;
            rIISCON= (1<<5)|(0<<4)|(0<<3)|(1<<2)|(1<<1);//發(fā)送IIS的DMA使能
            rIISMOD= (0<<9)|(0<<8)|(2<<6)|(0<<5)|(0<<4)|(1<<3)|(1<<2)|(1<<0);
            rIISFCON = (1<<15)|(1<<13); //發(fā)送FIFO為DMA

            //配置DMA
            rDISRC2 = (U32)buffer;//DMA的源基址為音頻數(shù)據(jù)數(shù)組的首地址
            rDISRCC2 = (0<<1)|(0<<0);//AHB,源地址遞增
            rDIDST2 = (U32)IISFIFO;//DMA的目的基址為IIS的FIFO
            rDIDSTC2 = (0<<2)| (1<<1)|(1<<0);//當(dāng)傳輸計(jì)數(shù)值為0時(shí)中斷,APB,目的地址不變
            if (result == 0)//所傳輸?shù)淖止?jié)數(shù)沒有超出DMA的最大傳輸范圍
            {
            flag = 0;//清標(biāo)志,表示沒有超出范圍,進(jìn)入DMA中斷后結(jié)束DMA操作
            //握手模式,PCLK同步,傳輸計(jì)數(shù)中斷,單元傳輸,單步服務(wù)模式,IISSDO,
            //硬件請求模式,非自動重載,半字,
            rDCON2 = (1<<31) | (0<<30) | (1<<29) | (0<<28) | (0<<27) | (0<<24) | (1<<23) | (1<<22) | (1<<20) | (remainder);

            }
            else//所傳輸?shù)淖止?jié)數(shù)超出了DMA的最大傳輸范圍
            {
            flag = 1;//置標(biāo)志,表示超出范圍
            rDCON2 = (1<<31) | (0<<30) | (1<<29) | (0<<28) | (0<<27) | (0<<24) | (1<<23) | (1<<22) | (1<<20) | (0xfffff);
            }
            rDMASKTRIG2=(0<<2)|(1<<1)|0;//不停止DMA,DMA通道開啟,非軟件觸發(fā)

            //啟動IIS
            rIISCON |= 0x1;
            }


            void __irq DMA_end(void)
            {
            rSRCPND |= 0x1<<19;
            rINTPND |= 0x1<<19;

            if (flag == 0)//DMA傳輸完畢
            {
            rIISCON = 0x0;//關(guān)閉IIS
            rIISFCON = 0x0;//清IIS的FIFO
            rDMASKTRIG2=1<<2;//停止DMA
            play_state = 0;//清播放標(biāo)志
            }
            else//DMA沒有傳輸完畢,繼續(xù)傳輸
            {
            result --;//商遞減
            rDISRC2 += 0x200000;//DMA源基址遞增。因?yàn)閭鬏數(shù)臄?shù)據(jù)是半字,所以這里遞增0x200000
            if (result == 0 )//只剩下余數(shù)部分需要傳輸
            {
            rDCON2=(rDCON2&(~0xfffff))|(remainder);//需要重新設(shè)置傳輸計(jì)數(shù)值
            flag=0;//清標(biāo)志
            }
            rDMASKTRIG2=(0<<2)|(1<<1)|0;//需要重新設(shè)置DMA通道的開啟
            }
            }

            void Main(void)
            {

            char mute;
            char volume;

            …………

            rSRCPND = (0x1<<19)|(0x1<<28);
            rSUBSRCPND = 0x1;
            rINTPND = (0x1<<19)|(0x1<<28);
            rINTSUBMSK = ~(0x1);
            rINTMSK = ~((0x1<<19)|(0x1<<28));//開啟DMA2中斷屏蔽
            pISR_UART0 = (U32)uartISR;
            pISR_DMA2=(U32)DMA_end;

            result=0;
            remainder=0;
            flag=0;
            cmd=0;
            play_state =0;

            while(1)
            {
            switch(cmd)
            {
            case 0x1://播放
            if (play_state==0)
            {
            volume = 0;//音量清零
            mute=0xa0;//初始化靜音
            playsound(music,sizeof(music));
            }
            else
            {
            while(!(rUTRSTAT0 & 0x2))
            ;
            rUTXH0=0xff;
            }
            cmd = 0;
            break;
            case 0x2://停止
            if (play_state==1)
            {
            rIISCON = 0x0;//停止IIS
            rIISFCON = 0x0;//清IIS的FIFO
            rDMASKTRIG2=1<<2;//終止DMA2
            flag = 0;
            play_state = 0;
            }
            else
            {
            while(!(rUTRSTAT0 & 0x2))
            ;
            rUTXH0=0xff;
            }
            cmd = 0;
            break;
            case 0x3://暫停,
            if(play_state == 1)
            {
            rIISCON ^= 0x1;//異或
            }
            else
            {
            while(!(rUTRSTAT0 & 0x2))
            ;
            rUTXH0=0xff;
            }
            cmd = 0;
            break;
            case 0x11://靜音
            if (play_state==1)
            {
            mute ^= 0x4;
            WriteL3(0x14 + 0,1);//DATA0 (000101xx+00)
            WriteL3(mute,0);//10,1,00,x,00:x,靜音
            }
            else
            {
            while(!(rUTRSTAT0 & 0x2))
            ;
            rUTXH0=0xff;
            }
            cmd = 0;
            break;
            case 0x12://音量遞增
            if (play_state==1)
            {
            if(volume>0)
            {
            volume --;
            WriteL3(0x14 + 0,1);//DATA0 (000101xx+00)
            WriteL3(volume,0);//音量提高
            }
            }
            else
            {
            while(!(rUTRSTAT0 & 0x2))
            ;
            rUTXH0=0xff;
            }
            cmd = 0;
            break;
            case 0x13://音量遞減
            if (play_state==1)
            {
            if(volume<61)
            {
            volume++;
            WriteL3(0x14 + 0,1);//DATA0 (000101xx+00)
            WriteL3(volume,0);//音量降低
            }
            }
            else
            {
            while(!(rUTRSTAT0 & 0x2))
            ;
            rUTXH0=0xff;
            }
            cmd = 0;
            break;
            }
            }
            }


            關(guān)鍵詞: s3c2440DMA應(yīng)

            評論


            技術(shù)專區(qū)

            關(guān)閉