<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > s3c2440的IIS應用——放音與錄音

s3c2440的IIS應用——放音與錄音

作者: 時(shí)間:2016-11-19 來(lái)源:網(wǎng)絡(luò ) 收藏
IIS(Inter-IC Sound)由飛利浦公司開(kāi)發(fā),是一種常用的音頻設備接口,主要用于CD、MD、MP3等設備。

s3c2440一共有5個(gè)引腳用于IIS:IISDO、IISDI、IISSCLK、IISLRCK和CDCLK。前兩個(gè)引腳用于數字音頻信號的輸出和輸入,另外三個(gè)引腳都與音頻信號的頻率有關(guān),可見(jiàn)要用好IIS,就要把信號頻率設置正確。IISSCLK為串行時(shí)鐘,每一個(gè)時(shí)鐘信號傳送一位音頻信號,因此IISSCLK的頻率=聲道數×采樣頻率×采樣位數,如采樣頻率fs為44.1kHz,采樣的位數為16位,聲道數2個(gè)(左、右兩個(gè)聲道),則IISSCLK的頻率=32fs=1411.2kHz。IISLRCK為幀時(shí)鐘,用于切換左、右聲道,如IISLRCK為高電平表示正在傳輸的是左聲道數據,為低電平表示正在傳輸的是右聲道數據,因此IISLRCK的頻率應該正好等于采樣頻率。由于IIS只負責數字音頻信號的傳輸,而要真正實(shí)現音頻信號的放、錄,還需要額外的處理芯片(在這里,我們使用的是UDA1341),CDCLK為該芯片提供系統同步時(shí)鐘,即編解碼時(shí)鐘,主要用于音頻的A/D、D/A采樣時(shí)的采樣時(shí)鐘,一般CDCLK為256fs或384fs。

通過(guò)以上分析可以發(fā)現,采樣頻率fs對頻率的設置至關(guān)重要。而fs不是任意設置的,一般基于不同的應用場(chǎng)合和聽(tīng)覺(jué)效果,而設置不同的幾個(gè)固定的值,如8kHz、16kHz、22.05kHz、44.1kHz、48kHz、96kHz等。為了使系統得到以fs為基數的各類(lèi)時(shí)鐘信號,就要重新調整系統時(shí)鐘。s3c2440用于IIS的時(shí)鐘源有PCLK和MPLLin,我們這里選擇PCLK作為IIS的時(shí)鐘源。PCLK經(jīng)過(guò)兩個(gè)預分頻器處理后分別得到IISSCLK、IISLRCK和CDCLK(預分頻器A得到IISSCLK、IISLRCK,預分頻器B得到CDCLK)。寄存器IISPSR是IIS預分頻器寄存器,5~9位是預分頻器A,0~4位是預分頻器B,一般來(lái)說(shuō),這兩個(gè)預分頻器的值N相等,即只要知道一個(gè),另一個(gè)也就知道,而這里我們是通過(guò)CDCLK來(lái)計算預分頻器B的值N的,即CDCLK=PCLK / (N+1)。PCLK與FCLK有一定的比例關(guān)系,而FCLK又是由輸入頻率Fin得到。在這里,我們?yōu)榱撕?jiǎn)化計算,不改變PCLK與FCLK的比例關(guān)系(即維持在啟動(dòng)代碼中定義的1:8的關(guān)系),那么由Fin而得到CDCLK一共涉及到四個(gè)參數:MDIV、PDIV、SDIV和前面公式中的N,涉及到的寄存器有MPLLCON和IISPSR。因此要得到這四個(gè)參數值,就需要一點(diǎn)耐心地計算,原則是誤差最小,其中需要注意的是,計算的結果(包括中間過(guò)程的結果)不要溢出,即不要超過(guò)32位。例如Fin為12MHz,我們設置采樣頻率fs=44.1kHz,而CDCLK=384fs=16.9344MHz,那么經(jīng)過(guò)計算,最終得到N=3,MDIV=150,PDIV=5,SDIV=0,即IISPSR = (3<<5) | 3;,MPLLCON = (150<<12) | (5<<4) | 0;。

s3c2440有關(guān)IIS的寄存器除了IISPSR外,還包括IIS控制寄存器IISCON,主要用于控制數據傳輸的方式、預分頻器和IIS接口是否開(kāi)啟;IIS模式寄存器IISMOD,主要用于設置IIS的時(shí)鐘源、主從方式、接收發(fā)送方式、串行接口方式、每個(gè)聲道串行數據位數和各種頻率值;IIS的FIFO接口寄存器IISFCON用于設置和判斷數據傳輸的FIFO狀態(tài);而寄存器IISFIFO則用于音頻數據的傳輸。

由于s3c2440要實(shí)現IIS的錄、放音,還需要UDA1341芯片,因此我們再簡(jiǎn)要介紹一下這個(gè)芯片的使用。s3c2440與UDA1341之間除了我們前面介紹過(guò)的IIS接口相連接外,還有一個(gè)稱(chēng)之為L(cháng)3總線(xiàn)的連接,用于s3c2440配置UDA1341內部的寄存器。由于s3c2440不具備L3總線(xiàn)接口,因此我們是用三個(gè)通用IO口來(lái)模擬L3,從而實(shí)現L3總線(xiàn)的傳輸。UDA1341有兩種模式:地址模式和數據傳輸模式。地址模式表示傳輸的是地址信息,它的高6位永遠是000101,低兩位表示的是傳輸的模式,是狀態(tài)模式、數據0模式還是數據1模式,其中狀態(tài)模式主要用于配置UDA1341的各類(lèi)初始狀態(tài),數據模式主要用于改善音頻輸入、輸出的效果。

下面我們就給出具體的程序,在這里我們使用的是正常模式來(lái)實(shí)現數據的輸入和輸出的,即不使用DMA模式。首先是實(shí)現s3c2440對某一音頻信號數據的輸出,即放音。我們事先已知道該音頻信號的各類(lèi)特性,如采樣頻率、聲道數、采樣信號的位數等。

…………
//L3接口
#define L3C (1<<4)//GPB4 = L3CLOCK
#define L3D (1<<3)//GPB3 = L3DATA
#define L3M (1<<2)//GPB2 = L3MODE

//純音頻信號數據數組
unsigned char music[ ] = {
0xB8, 0xFF, 0xBA, 0xFF, 0xBF, 0xFF, 0xC0, 0xFF, 0xD4, 0xFF, 0xD3, 0xFF, 0xF2, 0xFF, 0xED, 0xFF,
0x0E, 0x00, 0x05, 0x00, 0x1C, 0x00, 0x0F, 0x00, 0x15, 0x00, 0x06, 0x00, 0xFC, 0xFF, 0xEC, 0xFF,
…………
}

//L3總線(xiàn)接口的寫(xiě)函數
//輸入參數data為要寫(xiě)入的數據
//輸入參數address,為1表示地址模式,為0表示數據傳輸模式
static void WriteL3(U8 data,U8 address)
{
int i,j;
if(address == 1)
rGPBDAT = rGPBDAT & ~(L3D | L3M | L3C) | L3C;//L3D=L, L3M=L(地址模式), L3C=H
else
rGPBDAT = rGPBDAT & ~(L3D | L3M | L3C) | (L3C | L3M);//L3M=H(數據傳輸模式)
for(i=0;i<10;i++)
;//等待一段時(shí)間

//并行數據轉串行數據輸出,以低位在前、高位在后的順序
for(i=0;i<8;i++)
{
if(data & 0x1)// H
{
rGPBDAT &= ~L3C;//L3C=L
rGPBDAT |= L3D;//L3D=H
for(j=0;j<5;j++)
;//等待一段時(shí)間
rGPBDAT |= L3C;//L3C=H
rGPBDAT |= L3D;//L3D=H
for(j=0;j<5;j++)
;//等待一段時(shí)間
}
else// L
{
rGPBDAT &= ~L3C;//L3C=L
rGPBDAT &= ~L3D;//L3D=L
for(j=0;j<5;j++)
;//等待一段時(shí)間
rGPBDAT |= L3C;//L3C=H
rGPBDAT &= ~L3D;//L3D=L
for(j=0;j<5;j++)
;//等待一段時(shí)間
}
data >>= 1;
}
rGPBDAT = rGPBDAT & ~(L3D | L3M | L3C) | (L3C | L3M);//L3M=H,L3C=H
}

//放音
void playsound(unsigned char *buffer, int length)
{
int count,i;
char flag;

rGPBDAT = rGPBDAT & ~(L3M|L3C|L3D) |(L3M|L3C); //L3開(kāi)始傳輸:L3M=H, L3C=H

//配置UDA1341
WriteL3(0x14 + 2,1);//狀態(tài)模式(000101xx+10)
WriteL3(0x60,0);//0,1,10, 000,0 :狀態(tài)0,復位

WriteL3(0x14 + 2,1);//狀態(tài)模式(000101xx+10)
WriteL3(0x10,0);//0,0,01, 000,0 :狀態(tài)0, 384fs,IIS,no DC-filtering

WriteL3(0x14 + 2,1);//狀態(tài)模式(000101xx+10)
WriteL3(0xc1,0);//1,1,0,0, 0,0,01:狀態(tài)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寄存器
//預分頻器為3,所以CDCLK=PCLK/(3+1)=16.928kHz
rIISPSR = 3<<5|3;
//無(wú)效DMA,輸入空閑,預分頻器有效
rIISCON= (0<<5)|(0<<4)|(0<<3)|(1<<2)|(1<<1);
//PCLK為時(shí)鐘源,輸出模式,IIS模式,每個(gè)聲道16位,CODECLK=384fs,SCLK=32fs
rIISMOD= (0<<9)|(0<<8)|(2<<6)|(0<<5)|(0<<4)|(1<<3)|(1<<2)|(1<<0);
rIISFCON = (0<<15)|(1<<13);//輸出FIFO正常模式,輸出FIFO使能

flag=1;
count=0;
//開(kāi)啟IIS
rIISCON |= 0x1;
while(flag)
{

if((rIISCON & (1<<7))==0)//檢查輸出FIFO是否為空
{
//FIFO中的數據為16位,深度為32
//當輸出FIFO為空時(shí),一次性向FIFO寫(xiě)入32個(gè)16位數據
for(i=0;i<32;i++)
{
rIISFIFO=(buffer[2*i+count])+(buffer[2*i+1+count]<<8);
}
count+=64;
if(count>length)
flag=0;//音頻數據傳輸完,則退出
}
}
rIISCON = 0x0;//關(guān)閉IIS
}

void Main(void)
{

//配置MPLL
//fs=44.1kHz,CODECLK=384fs=16.9344MHz
//不改變CLKDIVN,所以PCLK=FCLK/8
//MPLLCON:MDIV=150,PDIV=5,SDIV=0,所以FCLK=541.7143MHz,PCLK=67.714MHz
rMPLLCON = (150<<12) | (5<<4) | 0;

//配置L3接口總線(xiàn),GPB2:L3MODE, GPB3:L3DATA, GPB4:L3CLOCK
rGPBCON = 0x015550;//輸出
rGPBUP= 0x7ff;//上拉無(wú)效
rGPBDAT = 0x1e4;

//配置IIS接口
rGPEUP = rGPEUP & ~(0x1f) | 0x1f;//上拉無(wú)效,GPE[4:0] 1 1111
rGPECON = rGPECON & ~(0x3ff) | 0x2aa;

playsound(music,sizeof(music));

while(1)
{
;
}
}


上面的程序可以實(shí)現簡(jiǎn)單的播放內存中固有音頻數據的功能,下面的程序實(shí)現了錄制一段音頻數據,然后再播出的功能。我們用UART來(lái)控制錄、放音:當s3c2440接收到0x51時(shí)錄音,接收到0x55時(shí)停止錄音,接收到0x66時(shí)放音。

…………
#define L3C (1<<4)//GPB4 = L3CLOCK
#define L3D (1<<3)//GPB3 = L3DATA
#define L3M (1<<2)//GPB2 = L3MODE

unsigned char record_buffer[1000000];//用于存放錄制的音頻數據
char stop,cmd;

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

switch(ch)
{
case 0x51://開(kāi)始錄音
cmd=0x01;
break;
case 0x55://停止錄音
stop=1;//置退出錄音標志
break;
case 0x66://放音
cmd=0x03;
break;
}
rUTXH0=ch;
}

…………

//錄音
//輸入參數為數組,輸出參數為所錄制數據的字節長(cháng)度
int record(unsigned char * buffer)
{
int count,i;
unsigned short temp;

rGPBDAT = rGPBDAT & ~(L3M|L3C|L3D) |(L3M|L3C); //L3開(kāi)始傳輸: L3M=H, L3C=H

//配置UDA1341
WriteL3(0x14 + 2,1);//狀態(tài)模式(000101xx+10)
WriteL3(0x60,0);//0,1,10, 000,0 :狀態(tài)0,復位

WriteL3(0x14 + 2,1);//狀態(tài)模式(000101xx+10)
WriteL3(0x10,0);//0,0,01, 000,0 :狀態(tài)0, 384fs,IIS,no DC-filtering

WriteL3(0x14 + 2,1);//狀態(tài)模式(000101xx+10)
WriteL3(0xa2,0);//1,0,1,0, 0,0,10狀態(tài)1
//Gain of DAC 0 dB,Gain of ADC 6dB,ADC non-inverting,
//DAC non-inverting,Single speed playback,ADC-On DAC-Off

WriteL3(0x14 + 0,1);//DATA0 (000101xx+00)
WriteL3(0x7b,0);//01,11 10,11 : Data0, Bass Boost 18~24dB, Treble 6dB

WriteL3(0xc4,0);//1100 0,100: Extended addr(3bits), 100
WriteL3(0xf0,0);//111,1 00,00 : DATA0, Enable AGC, 00, input amplifier gain channel 2 (2bits)

WriteL3(0xc0,0);//1100 0,000: Extended addr(3bits), 000
WriteL3(0xe0,0);//111, 00000: MA = 0dB
WriteL3(0xc1,0);//1100 0,001: Extended addr(3bits), 001
WriteL3(0xe0,0);//111, 00000: MB = 0dB

WriteL3(0xc2,0);//1100 0,010: Extended addr(3bits), 010
WriteL3(0xf9,0);//111,1 10,11 : DATA0, MIC Amplifier Gain 27dB, input 1 X MA + input 2 X MB

//配置s3c2440的IIS寄存器
//預分頻器為3,所以CDCLK=PCLK/(3+1)=16.928kHz
rIISPSR = 3<<5|3;
//無(wú)效DMA,輸出空閑,預分頻器有效
rIISCON= (0<<5)|(0<<4)|(1<<3)|(0<<2)|(1<<1);
//PCLK為時(shí)鐘源,輸入模式,IIS模式,每個(gè)聲道16位,CODECLK=384fs,SCLK=32fs
rIISMOD = (0<<9)|(0<<8)|(1<<6)|(0<<5)|(0<<4)|(1<<3)|(1<<2)|(1<<0);
rIISFCON = (0<<14)|(1<<12);//輸入FIFO正常模式,輸入FIFO使能

count=0;

//開(kāi)啟IIS
rIISCON |= 0x1;
while(stop==0)
{

if((rIISCON & (1<<6))==0)//檢查輸入FIFO是否為滿(mǎn)
{
//FIFO中的數據為16位,深度為32
//當輸入FIFO為滿(mǎn)時(shí),一次性讀取FIFO中的32個(gè)16位數據
for(i=0;i<32;i++)
{
temp=rIISFIFO;
record_buffer[count+2*i]=(unsigned char)temp;
record_buffer[count+2*i+1]=(unsigned char)(temp>>8);
}
count+=64;
if(count>1000000)
stop=1;//當錄制的數據超過(guò)數組長(cháng)度時(shí),退出
}
}

rIISCON=0;//關(guān)閉IIS

return count;//返回錄制數據長(cháng)度
}

void Main(void)
{

char play;
int bufferlength;

…………

//由于改變了PCLK,所以需要重新計算UART波特率因子
rUBRDIV0 = 36;

…………

stop=0;
cmd=0;
play=0;

while(1)
{
switch(cmd)
{
case 0x01://錄音
bufferlength=record(record_buffer);
play=1;//置錄音標志
cmd=0;
break;
case 0x03://放音
if(play)
playsound(record_buffer,bufferlength);
else//還沒(méi)有錄制音頻數據
{
while(!(rUTRSTAT0 & 0x2));
rUTXH0 = 0xff;
}
cmd=0;
break;
}
}
}





補充:

應大家的要求,我把UDA1341的L3通信協(xié)議詳細介紹一下。

顧名思義,L3就是line 3(3條線(xiàn))的意思,它只有L3DATA(數據線(xiàn):用于傳輸數據)、L3MODE(模式線(xiàn):用于選擇模式)、L3CLOCK(時(shí)鐘線(xiàn):用于傳輸時(shí)鐘)。L3一共有兩個(gè)模式:地址模式和數據傳輸模式,先傳輸地址模式數據,再傳輸數據模式數據。L3MODE為低時(shí)是地址模式,L3MODE為高時(shí)是數據傳輸模式。L3DATA和L3CLOCK相互作用,完成8位數據的傳輸,傳輸的順序是先低位數據,再高位數據。

地址模式是用于選擇設備和定義目標寄存器,在這種模式下,8位數據的含義是:高6位是設備地址(UDA1341的地址為000101),低兩位是后面數據模式下寄存器的類(lèi)型(00:DATA0,01:DATA1,10:STATUS)。只要沒(méi)有再改變地址模式下的數據,則數據模式下的數據始終是傳輸到上一個(gè)地址模式所定義的寄存器內。

在傳輸數據模式下,STATUS是用于設置復位,系統時(shí)鐘頻率、數據輸入模式、DC濾波等內容。DATA0分為直接尋址模式和擴展尋址模式,直接尋址模式是直接進(jìn)行模式的控制,包括音量、靜音等等,而擴展尋址模式是在直接尋址模式下先設置3位擴展地址,再在直接尋址模式下設置5位擴展數據。在DATA1下,可以讀取到被檢測峰值。至于具體的DATA0、DATA1、STATUS下,每一位數據具體的含義,還請自己查閱手冊。


關(guān)鍵詞: s3c2440IIS應用放音與錄

評論


技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>