s3c2440的IIS应用——放音与录音
时间:11-19
来源:互联网
点击:
uartISR(void)
{
char ch;
rSUBSRCPND |= 0x1;
rSRCPND |= 0x1<28;
rINTPND |= 0x1<28;
ch=rURXH0;
switch(ch)
{
case 0x51://开始录音
cmd=0x01;
break;
case 0x55://停止录音
stop=1;//置退出录音标志
break;
case 0x66://放音
cmd=0x03;
break;
}
rUTXH0=ch;
}
…………
//录音
//输入参数为数组,输出参数为所录制数据的字节长度
int record(unsigned char * buffer)
{
int count,i;
unsigned short temp;
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(0xa2,0);//1,0,1,0, 0,0,10状态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;
//无效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 |= 0x1;
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]=(unsigned char)temp;
record_buffer[count+2*i+1]=(unsigned char)(temp>>8);
}
count+=64;
if(count>1000000)
stop=1;//当录制的数据超过数组长度时,退出
}
}
rIISCON=0;//关闭IIS
return count;//返回录制数据长度
}
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//还没有录制音频数据
{
while(!(rUTRSTAT0 & 0x2));
rUTXH0 = 0xff;
}
cmd=0;
break;
}
}
}
补充:
应大家的要求,我把UDA1341的L3通信协议详细介绍一下。
顾名思义,L3就是line 3(3条线)的意思,它只有L3DATA(数据线:用于传输数据)、L3MODE(模式线:用于选择模式)、L3CLOCK(时钟线:用于传输时钟)。L3一共有两个模式:地址模式和数据传输模式,先传输地址模式数据,再传输数据模式数据。L3MODE为低时是地址模式,L3MODE为高时是数据传输模式。L3DATA和L3CLOCK相互作用,完成8位数据的传输,传输的顺序是先低位数据,再高位数据。
地址模式是用于选择设备和定义目标寄存器,在这种模式下,8位数据的含义是:高6位是设备地址(UDA1341的地址为000101),低两位是后面数据模式下寄存器的类型(00:DATA0,01:DATA1,10:STATUS)。只要没有再改变地址模式下的数据,则数据模式下的数据始终是传输到上一个地址模式所定义的寄存器内。
在传输数据模式下,STATUS是用于设置复位,系统时钟频率、数据输入模式、DC滤波等内容。DATA0分为直接寻址模式和扩展寻址模式,直接寻址模式是直接进行模式的控制,包括音量、静音等等,而扩展寻址模式是在直接寻址模式下先设置3位扩展地址,再在直接寻址模式下设置5位扩展数据。在DATA1下,可以读取到被检测峰值。至于具体的DATA0、DATA1、STATUS下,每一位数据具体的含义,还请自己查阅手册。
{
char ch;
rSUBSRCPND |= 0x1;
rSRCPND |= 0x1<28;
rINTPND |= 0x1<28;
ch=rURXH0;
switch(ch)
{
case 0x51://开始录音
cmd=0x01;
break;
case 0x55://停止录音
stop=1;//置退出录音标志
break;
case 0x66://放音
cmd=0x03;
break;
}
rUTXH0=ch;
}
…………
//录音
//输入参数为数组,输出参数为所录制数据的字节长度
int record(unsigned char * buffer)
{
int count,i;
unsigned short temp;
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(0xa2,0);//1,0,1,0, 0,0,10状态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;
//无效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 |= 0x1;
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]=(unsigned char)temp;
record_buffer[count+2*i+1]=(unsigned char)(temp>>8);
}
count+=64;
if(count>1000000)
stop=1;//当录制的数据超过数组长度时,退出
}
}
rIISCON=0;//关闭IIS
return count;//返回录制数据长度
}
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//还没有录制音频数据
{
while(!(rUTRSTAT0 & 0x2));
rUTXH0 = 0xff;
}
cmd=0;
break;
}
}
}
补充:
应大家的要求,我把UDA1341的L3通信协议详细介绍一下。
顾名思义,L3就是line 3(3条线)的意思,它只有L3DATA(数据线:用于传输数据)、L3MODE(模式线:用于选择模式)、L3CLOCK(时钟线:用于传输时钟)。L3一共有两个模式:地址模式和数据传输模式,先传输地址模式数据,再传输数据模式数据。L3MODE为低时是地址模式,L3MODE为高时是数据传输模式。L3DATA和L3CLOCK相互作用,完成8位数据的传输,传输的顺序是先低位数据,再高位数据。
地址模式是用于选择设备和定义目标寄存器,在这种模式下,8位数据的含义是:高6位是设备地址(UDA1341的地址为000101),低两位是后面数据模式下寄存器的类型(00:DATA0,01:DATA1,10:STATUS)。只要没有再改变地址模式下的数据,则数据模式下的数据始终是传输到上一个地址模式所定义的寄存器内。
在传输数据模式下,STATUS是用于设置复位,系统时钟频率、数据输入模式、DC滤波等内容。DATA0分为直接寻址模式和扩展寻址模式,直接寻址模式是直接进行模式的控制,包括音量、静音等等,而扩展寻址模式是在直接寻址模式下先设置3位扩展地址,再在直接寻址模式下设置5位扩展数据。在DATA1下,可以读取到被检测峰值。至于具体的DATA0、DATA1、STATUS下,每一位数据具体的含义,还请自己查阅手册。
s3c2440IIS应用放音与录 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)