基于S3C2410的Linux下的I2S接口实现嵌入式语音的录

来源:期刊VIP网所属分类:机械发布时间:2012-07-12浏览:

  摘要:IIS接口即集成音频接口,如果设计音频应用产品,I2S总线接口是必需的。而S3C2410芯片内部集成有I2S接口控制部件,以便实现一个用于迷你型、可移动的多媒体数字音频信号编解码器。本文在介绍I2S总线的基础上,分析并实现了在Linux下放音和录音的初始化驱动及录放音的过程。

  关键字: S3C2410 I2S总线 嵌入式Linux UDA1341

  1 I2S总线概述

  音响数据的采集、处理和传输是多媒体技术的重要组成部分。众多的数字音频系统已经进入消费市场,例如数字音频录音带、数字声音处理器。I2S(Inter—IC Sound)总线是飞利浦公司为数字音频设备之间的音频数据传输而制定的一种总线标准,该总线专责于音频设备之间的数据传输,广泛应用于各种多媒体系统。它采用了沿独立的导线传输时钟与数据信号的设计,通过将数据和时钟信号分离,避免了因时差诱发的失真,为用户节省了购买抵抗音频抖动的专业设备的费用。

  2 I2S总线规范

  在飞利浦公司的I2S标准中,既规定了硬件接口规范,也规定了数字音频数据的格式。

  2.1 I2S有3个主要信号:

  1)串行时钟SCLK,也叫位时钟(BCLK),即对应数字音频的每一位数据,SCLK都有1个脉冲。SCLK的频率=2×采样频率×采样位数。

  2) 帧时钟LRCK,(也称WS),用于切换左右声道的数据。LRCK为“1”表示正在传输的是左声道的数据,为“0”则表示正在传输的是右声道的数据。LRCK的频率等于采样频率。

  3)串行数据SDATA,就是用二进制补码表示的音频数据。

  有时为了使系统间能够更好地同步,还需要另外传输一个信号MCLK,称为主时钟,也叫系统时钟(Sys Clock),是采样频率的256倍或384倍。

  2.2 串行数据(SD)

  I2S格式的信号无论有多少位有效数据,数据的最高位总是出现在LRCK变化(也就是一帧开始)后的第2个SCLK脉冲处。如果接收端能处理的有效位数多于发送端,可以自行补足剩余的位。这种同步机制使得数字音频设备的互连更加方便,而且不会造成数据错位。

  I2S格式的信号无论有多少位有效数据,数据位的最高位(MSB)总是被最先传输,1次能够发送的数据决定于I2S格式的有效位数。

  随着技术的发展,在统一的I2S接口下出现了多种不同的数据格式。根据SD信号相对于SCK和WS位置的不同,分为左对齐和右对齐2种格式,如图2和图3所示。

  2.3 字段(声道)选择(WS)

  命令选择线表明了正在被传输的声道。

  WS=1,表示正在传输的是左声道的数据。

  WS=0,表示正在传输的是右声道的数据。

  WS可以在串行时钟的上升沿或者下降沿发生改变,并且WS信号不需要一定是对称的。在从属装置端,WS在时钟信号的上升沿发生改变。在图2、图3两种数据传输格式中,当WS为“1”时传输的是左声道的数据,当WS为“0”时传输的是右声道的数据。为了保证数字音频信号的正确传输,发送端和接收端应该采用相同的数据格式和长度。当然,对I2S格式来说数据长度可以不同。

  2.4电气规范:

  输出电压:

  VL <0.4V

  VH>2.4V

  输入电压

  VIL=0.8V

  VIH=2.0V

  注:目前使用的TTL电平标准,随着其他IC(LSI)的流行,其他电平也会支持。

  3 I2S工作时序

  在I2S总线中,任何设备都可以通过提供必需的时钟信号成为系统的主导装置,而从属装置通过外部时钟信号来得到它的内部时钟信号,这就意味着必须重视主导装置和数据以及命令选择信号之间的传播延迟,总的延迟主要由两部分组成:

  1)外部时钟和从属装置的内部时钟之间的延迟

  2)内部时钟和数据信号以及命令选择信号之间的延迟

  对于数据和命令信号的输入,外部时钟和内部时钟的延迟不占据主导地位,它只是延长了有效的建立时间(set—up time)。延迟的主要部分是发送端的传输延迟和设置接收端所需的时间。

  T是时钟周期,Tr是最小允许时钟周期,T>Tr这样发送端和接收端才能满足数据传输速率的要求。

  对于所有的数据速率,发送端和接收端均发出一个具有固定的传号空号比(mark—space ratio)的时钟信号,所以t LC和tHC是由T所定义的。 t LC和tHC必须大于0.35T,这样信号在从属装置端就可以被检测到。

  延迟(tdtr)和最快的传输速度(由Ttr定义)是相关的,快的发送端信号在慢的时钟上升沿可能导致tdtr不能超过tRC而使thtr为零或者负。只有tRC不大于tRCmax的时候(tRCmax>:0.15T),发送端才能保证thtr大于等于0。

  数据建立时间(set-up time)和保持时间(hold time)不能小于指定接收端的建立时间和保持时间。

  4 I2S总线结构配置

  S3C2410数字音频接口模块由I2S(Inter-IC Sound)音频总线接口和UDA1341音频编码器(CODEC)组成。S3C2410内置一个I2S总线控制器,该控制器实现了到一个外部8/16位立体声音频CODEC IC的接口。支持I2S总线数据格式和MSB-justified数据格式。此控制器包含FIFO,支持DMA传输模式。I2S总线控制器结构如图4所示。

  UDA1341是Philips公司的一款经济型音频CODEC,用于实现模拟音频信号的采集(音频AD)和数字音频信号的模拟输出(DA),并通过I2S数字音频接口,实现音频信号的数字化处理。

  5 S3C2410下的放音代码

  I2S放音代码如下所示:

  void Play_Iis(void)

  {

  unsigned int save_G, save_E, save_PG, save_PE;

  Uart_TxEmpty(0);

  由于I2S时钟从系统进钟分频得到,为了得到合适的I2S时钟,必须对系统时钟进行适当的降频处理,降频后必须对串口重新进行初始化。然后将用到的端口保存起来,并进行端口初始化。

  I2S可以采用DMA方式进行语音录音和播放,因此需进行DMA中断的注册。

  pISR_DMA2 = (unsigned)DMA2_Done;

  然后获取语音数据及其大小以及采样频率。

  下来初始化UDA1341,设置为放音模式。

  Init1341(PLAY);

  接着进行DMA初始化。

  //DMA2 Initialize

  rDISRC2 = (int)(Buf + 0x2c);

  rDISRCC2 = (0<<1) + (0<<0);

  rDIDST2 = ((U32)IISFIFO);

  rDIDSTC2 = (1<<1) + (1<<0);

  rDCON2 = (1<<31)+(0<<30)+(1<<29)+(0<<28)+(0<<27)+(0<<24)+(1<<23)+(0<<22)+(1<<20)+(size/4);

  rDMASKTRIG2 = (0<<2) + (1<<1) + (0<<0);

  I2S的初始化并启动I2S功能。

  if(fs==44100)

  rIISPSR = (2<<5) + 2;

  else

  rIISPSR = (5<<5) + 5;

  rIISCON = (1<<5) + (1<<2) + (1<<1);

  rIISMOD = (0<<8) + (2<<6) + (0<<5) + (0<<4) + (1<<3) + (0<<2) + (1<<0);

  rIISFCON = (1<<15) + (1<<13);

  //IIS Tx Start

  rIISCON |= 0x1;

  rINTMSK &= ~(/*BIT_EINT0 | BIT_UART0 |*/ BIT_DMA2);

  ClearPending(BIT_DMA2);

  I2S启动后,将采用DMA方式播放语音数据,播放完毕后将引发DMA2中断,在其中断处理函数中将dma2_done设置为非零,因此,在主程序中可以通过判断dma2_done是否为0决定播放是否结束。语音播放结束,通知I2S,并恢复寄存器设置。

  最后将关闭中断并将系统时钟恢复。

  rINTMSK |= (BIT_DMA2);

  ChangeMPllValue(0xa1,0x3,0x1); // FCLK=202.8MHz

  Uart_Init(0,115200);

  mute = 1;

  PRINTF("------放音测试结束------\n\n");

  6 S3C2410下的录音代码

  录音程序在初始化等动作上与放音类似,代码如下:

  void Record_Iis(void)

  {

  unsigned int save_G, save_E, save_PG, save_PE;

  Uart_TxEmpty(0);

  ChangeClockDivider(1,1);

  ChangeMPllValue(0x96,0x5,0x1);

  Uart_Init(33857142,115200);

  PRINTF("--------录音测试--------\n");

  PRINTF("[1] 请接上耳机和麦克风\n");

  save_G = rGPGCON;

  save_E = rGPECON;

  save_PG = rGPGUP;

  save_PE = rGPEUP;

  IIS_PortSetting();

  录制的声音数据保存在rec_buf中,录制长度为REC——LEN:

  rec_buf = (unsigned short *)0x31000000;

  pISR_DMA2 = (unsigned)DMA2_Rec_Done;

  pISR_EINT0 = (unsigned)Muting;

  rINTMSK &= ~(BIT_DMA2);

  Init1341(RECORD);

  rDISRCC2 = (1<<1) + (1<<0);

  rDISRC2 = ((U32)IISFIFO);

  rDIDSTC2 = (0<<1) + (0<<0);

  rDIDST2 = (int)rec_buf;

  rDCON2 = (1<<31)+(0<<30)+(1<<29)+(0<<28)+(0<<27)+(1<<24)+(1<<23)+(1<<22)+(1<<20)+REC_LEN;

  rDMASKTRIG2 = (0<<2) + (1<<1) + 0;

  rIISMOD = (0<<8) + (1<<6) + (0<<5) + (0<<4) + (1<<3) + (0<<2) + (1<<0);

  rIISPSR = (2<<5) + 2;

  rIISCON = (0<<5) + (1<<4) + (1<<3) + (0<<2) + (1<<1);

  rIISFCON = (1<<14) + (1<<12);

  开始录音:

  rIISCON |= 0x1;

  while(!Rec_Done) Delay(1);

  rINTMSK |= BIT_DMA2;

  Rec_Done = 0;

  PRINTF(" 录音完毕\n");

  7结束语

  I2S总线是近年出现的一种面向多媒体计算机器Multimedia PC)的音频总线,该总线专门用于音频设备之间的数据传输。文中基于S3C2410和Linux平台,设计共实现基于该平台的I2S录音放音。

期刊VIP网,您身边的高端学术顾问

文章名称: 基于S3C2410的Linux下的I2S接口实现嵌入式语音的录

文章地址: http://www.qikanvip.com/jixie/3029.html