s3c2440IIS应用.docx
- 文档编号:28195419
- 上传时间:2023-07-09
- 格式:DOCX
- 页数:13
- 大小:20.44KB
s3c2440IIS应用.docx
《s3c2440IIS应用.docx》由会员分享,可在线阅读,更多相关《s3c2440IIS应用.docx(13页珍藏版)》请在冰豆网上搜索。
s3c2440IIS应用
放音与录音
NoComments
知识点,bylyping.|Tags:
I2C
IIS(Inter-ICSound)由飞利浦公司开发,是一种常用的音频设备接口,主要用于CD、MD、MP3等设备。
s3c2440一共有5个引脚用于IIS:
IISDO、IISDI、IISSCLK、IISLRCK和CDCLK。
前两个引脚用于数字音频信号的输出和输入,另外三个引脚都与音频信号的频率有关,可见要用好IIS,就要把信号频率设置正确。
IISSCLK为串行时钟,每一个时钟信号传送一位音频信号,因此IISSCLK的频率=声道数×采样频率×采样位数,如采样频率fs为44.1kHz,采样的位数为16位,声道数2个(左、右两个声道),则IISSCLK的频率=32fs=1411.2kHz。
IISLRCK为帧时钟,用于切换左、右声道,如IISLRCK为高电平表示正在传输的是左声道数据,为低电平表示正在传输的是右声道数据,因此IISLRCK的频率应该正好等于采样频率。
由于IIS只负责数字音频信号的传输,而要真正实现音频信号的放、录,还需要额外的处理芯片(在这里,我们使用的是UDA1341),CDCLK为该芯片提供系统同步时钟,即编解码时钟,主要用于音频的A/D、D/A采样时的采样时钟,一般CDCLK为256fs或384fs。
通过以上分析可以发现,采样频率fs对频率的设置至关重要。
而fs不是任意设置的,一般基于不同的应用场合和听觉效果,而设置不同的几个固定的值,如8kHz、16kHz、22.05kHz、44.1kHz、48kHz、96kHz等。
为了使系统得到以fs为基数的各类时钟信号,就要重新调整系统时钟。
s3c2440用于IIS的时钟源有PCLK和MPLLin,我们这里选择PCLK作为IIS的时钟源。
PCLK经过两个预分频器处理后分别得到IISSCLK、IISLRCK和CDCLK(预分频器A得到IISSCLK、IISLRCK,预分频器B得到CDCLK)。
寄存器IISPSR是IIS预分频器寄存器,5~9位是预分频器A,0~4位是预分频器B,一般来说,这两个预分频器的值N相等,即只要知道一个,另一个也就知道,而这里我们是通过CDCLK来计算预分频器B的值N的,即CDCLK=PCLK/(N+1)。
PCLK与FCLK有一定的比例关系,而FCLK又是由输入频率Fin得到。
在这里,我们为了简化计算,不改变PCLK与FCLK的比例关系(即维持在启动代码中定义的1:
8的关系),那么由Fin而得到CDCLK一共涉及到四个参数:
MDIV、PDIV、SDIV和前面公式中的N,涉及到的寄存器有MPLLCON和IISPSR。
因此要得到这四个参数值,就需要一点耐心地计算,原则是误差最小,其中需要注意的是,计算的结果(包括中间过程的结果)不要溢出,即不要超过32位。
例如Fin为12MHz,我们设置采样频率fs=44.1kHz,而CDCLK=384fs=16.9344MHz,那么经过计算,最终得到N=3,MDIV=150,PDIV=5,SDIV=0,即IISPSR=(3<<5)|3;,MPLLCON=(150<<12)|(5<<4)|0;。
s3c2440有关IIS的寄存器除了IISPSR外,还包括IIS控制寄存器IISCON,主要用于控制数据传输的方式、预分频器和IIS接口是否开启;IIS模式寄存器IISMOD,主要用于设置IIS的时钟源、主从方式、接收发送方式、串行接口方式、每个声道串行数据位数和各种频率值;IIS的FIFO接口寄存器IISFCON用于设置和判断数据传输的FIFO状态;而寄存器IISFIFO则用于音频数据的传输。
由于s3c2440要实现IIS的录、放音,还需要UDA1341芯片,因此我们再简要介绍一下这个芯片的使用。
s3c2440与UDA1341之间除了我们前面介绍过的IIS接口相连接外,还有一个称之为L3总线的连接,用于s3c2440配置UDA1341内部的寄存器。
由于s3c2440不具备L3总线接口,因此我们是用三个通用IO口来模拟L3,从而实现L3总线的传输。
UDA1341有两种模式:
地址模式和数据传输模式。
地址模式表示传输的是地址信息,它的高6位永远是000101,低两位表示的是传输的模式,是状态模式、数据0模式还是数据1模式,其中状态模式主要用于配置UDA1341的各类初始状态,数据模式主要用于改善音频输入、输出的效果。
下面我们就给出具体的程序,在这里我们使用的是正常模式来实现数据的输入和输出的,即不使用DMA模式。
首先是实现s3c2440对某一音频信号数据的输出,即放音。
我们事先已知道该音频信号的各类特性,如采样频率、声道数、采样信号的位数等。
…………
//L3接口
#defineL3C(1<<4)//GPB4=L3CLOCK
#defineL3D(1<<3)//GPB3=L3DATA
#defineL3M(1<<2)//GPB2=L3MODE
//纯音频信号数据数组
unsignedcharmusic[]={
0xB8,0xFF,0xBA,0xFF,0xBF,0xFF,0xC0,0xFF,0xD4,0xFF,0xD3,0xFF,0xF2,0xFF,0xED,0xFF,
0x0E,0×00,0×05,0×00,0x1C,0×00,0x0F,0×00,0×15,0×00,0×06,0×00,0xFC,0xFF,0xEC,0xFF,
…………
}
//L3总线接口的写函数
//输入参数data为要写入的数据
//输入参数address,为1表示地址模式,为0表示数据传输模式
staticvoidWriteL3(U8data,U8address)
{
inti,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++)
;//等待一段时间
//并行数据转串行数据输出,以低位在前、高位在后的顺序
for(i=0;i<8;i++)
{
if(data&0×1)//H
{
rGPBDAT&=~L3C;//L3C=L
rGPBDAT|=L3D;//L3D=H
for(j=0;j<5;j++)
;//等待一段时间
rGPBDAT|=L3C;//L3C=H
rGPBDAT|=L3D;//L3D=H
for(j=0;j<5;j++)
;//等待一段时间
}
else//L
{
rGPBDAT&=~L3C;//L3C=L
rGPBDAT&=~L3D;//L3D=L
for(j=0;j<5;j++)
;//等待一段时间
rGPBDAT|=L3C;//L3C=H使CLOCK为1;
rGPBDAT&=~L3D;//L3D=L
for(j=0;j<5;j++)
;//等待一段时间
}
data>>=1;
}
rGPBDAT=rGPBDAT&~(L3D|L3M|L3C)|(L3C|L3M);//L3M=H,L3C=H
}
//放音
voidplaysound(unsignedchar*buffer,intlength)
{
intcount,i;
charflag;
rGPBDAT=rGPBDAT&~(L3M|L3C|L3D)|(L3M|L3C);//L3开始传输:
L3M=H,L3C=H
//配置UDA1341
WriteL3(0×14+2,1);//状态模式(000101xx+10)
WriteL3(0×60,0);//0,1,10,000,0:
状态0,复位
WriteL3(0×14+2,1);//状态模式(000101xx+10)
WriteL3(0×10,0);//0,0,01,000,0:
状态0,384fs,IIS,noDC-filtering
WriteL3(0×14+2,1);//状态模式(000101xx+10)
WriteL3(0xc1,0);//1,0,0,0,0,0,01:
状态1,
//GainofDAC6dB,GainofADC0dB,ADCnon-inverting,
//DACnon-inverting,Singlespeedplayback,ADC-OffDAC-On
//配置s3c2440的IIS寄存器
//预分频器为3,所以CDCLK=PCLK/(3+1)=16.928kHz
rIISPSR=3<<5|3;
//无效DMA,输入空闲,预分频器有效
rIISCON=(0<<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=(0<<15)|(1<<13);//输出FIFO正常模式,输出FIFO使能
flag=1;
count=0;
//开启IIS
rIISCON|=0×1;
while(flag)
{
if((rIISCON&(1<<7))==0)//检查输出FIFO是否为空
{
//FIFO中的数据为16位,深度为32
//当输出FIFO为空时,一次性向FIFO写入32个16位数据
for(i=0;i<32;i++)
{
rIISFIFO=(buffer[2*i+count])+(buffer[2*i+1+count]<<8);
//每一次写两个字节,64字节,须写32次;
}
count+=64;
if(count>length)
flag=0;//音频数据传输完,则退出
}
}
rIISCON=0×0;//关闭IIS
}
voidMain(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接口总线,GPB2:
L3MODE,GPB3:
L3DATA,GPB4:
L3CLOCK
rGPBCON=0×015550;//输出
rGPBUP=0x7ff;//上拉无效
rGPBDAT=0x1e4;
//配置IIS接口
rGPEUP=rGPEUP&~(0x1f)|0x1f;//上拉无效,GPE[4:
0]11111
rGPECON=rGPECON&~(0x3ff)|0x2aa;
playsound(music,sizeof(music));
while
(1)
{
;
}
}
上面的程序可以实现简单的播放内存中固有音频数据的功能,下面的程序实现了录制一段音频数据,然后再播出的功能。
我们用UART来控制录、放音:
当s3c2440接收到0×51时录音,接收到0×55时停止录音,接收到0×66时放音。
…………
#defineL3C(1<<4)//GPB4=L3CLOCK
#defineL3D(1<<3)//GPB3=L3DATA
#defineL3M(1<<2)//GPB2=L3MODE
unsignedcharrecord_buffer[1000000];//用于存放录制的音频数据
charstop,cmd;
//UART中断
void__irquartISR(void)
{
charch;
rSUBSRCPND|=0×1;
rSRCPND|=0×1<<28;
rINTPND|=0×1<<28;
ch=rURXH0;
switch(ch)
{
case0×51:
//开始录音
cmd=0×01;
break;
case0×55:
//停止录音
stop=1;//置退出录音标志
break;
case0×66:
//放音
cmd=0×03;
break;
}
rUTXH0=ch;
}
…………
//录音
//输入参数为数组,输出参数为所录制数据的字节长度
intrecord(unsignedchar*buffer)
{
intcount,i;
unsignedshorttemp;
rGPBDAT=rGPBDAT&~(L3M|L3C|L3D)|(L3M|L3C);//L3开始传输:
L3M=H,L3C=H
//配置UDA1341
WriteL3(0×14+2,1);//状态模式(000101xx+10)
WriteL3(0×60,0);//0,1,10,000,0:
状态0,复位
WriteL3(0×14+2,1);//状态模式(000101xx+10)
WriteL3(0×10,0);//0,0,01,000,0:
状态0,384fs,IIS,noDC-filtering
WriteL3(0×14+2,1);//状态模式(000101xx+10)
WriteL3(0xa2,0);//1,0,1,0,0,0,10状态1
//GainofDAC0dB,GainofADC6dB,ADCnon-inverting,
//DACnon-inverting,Singlespeedplayback,ADC-OnDAC-Off
WriteL3(0×14+0,1);//DATA0(000101xx+00)
WriteL3(0x7b,0);//01,1110,11:
Data0,BassBoost18~24dB,Treble6dB
WriteL3(0xc4,0);//11000,100:
Extendedaddr(3bits),100
WriteL3(0xf0,0);//111,100,00:
DATA0,EnableAGC,00,inputamplifiergainchannel2(2bits)
WriteL3(0xc0,0);//11000,000:
Extendedaddr(3bits),000
WriteL3(0xe0,0);//111,00000:
MA=0dB
WriteL3(0xc1,0);//11000,001:
Extendedaddr(3bits),001
WriteL3(0xe0,0);//111,00000:
MB=0dB
WriteL3(0xc2,0);//11000,010:
Extendedaddr(3bits),010
WriteL3(0xf9,0);//111,110,11:
DATA0,MICAmplifierGain27dB,input1XMA+input2XMB
//配置s3c2440的IIS寄存器
//预分频器为3,所以CDCLK=PCLK/(3+1)=16.928kHz
rIISPSR=3<<5|3;
//无效DMA,输出空闲,预分频器有效
rIISCON=(0<<5)|(0<<4)|(1<<3)|(0<<2)|(1<<1);
//PCLK为时钟源,输入模式,IIS模式,每个声道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;
//开启IIS
rIISCON|=0×1;
while(stop==0)
{
if((rIISCON&(1<<6))==0)//检查输入FIFO是否为满
{
//FIFO中的数据为16位,深度为32
//当输入FIFO为满时,一次性读取FIFO中的32个16位数据
for(i=0;i<32;i++)
{
temp=rIISFIFO;
record_buffer[count+2*i]=(unsignedchar)temp;
record_buffer[count+2*i+1]=(unsignedchar)(temp>>8);
}
count+=64;
if(count>1000000)
stop=1;//当录制的数据超过数组长度时,退出
}
}
rIISCON=0;//关闭IIS
returncount;//返回录制数据长度
}
voidMain(void)
{
charplay;
intbufferlength;
…………
//由于改变了PCLK,所以需要重新计算UART波特率因子
rUBRDIV0=36;
…………
stop=0;
cmd=0;
play=0;
while
(1)
{
switch(cmd)
{
case0×01:
//录音
bufferlength=record(record_buffer);
play=1;//置录音标志
cmd=0;
break;
case0×03:
//放音
if(play)
playsound(record_buffer,bufferlength);
else//还没有录制音频数据
{
while(!
(rUTRSTAT0&0×2));
rUTXH0=0xff;
}
cmd=0;
break;
}
}
}
本文来自CSDN博客,转载请标明出处:
I2C总线协议详解(附PDF)SVN使用方法和名词解释
Responsesto“s3c2440的IIS应用——放音与录音”
Comments(0)Trackbacks(0)LeaveacommentTrackback
1Nocommentsyet.
LeaveaReply
窗体顶端
Name(required)
Mail(willnotbepublished)(required)
Website
BackTop
窗体底端
Copyright©2009-2010Lyping.AllRightsReserved
鄂ICP备09015783号
站长统计
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- s3c2440IIS 应用