FL2440无操作系统应用程序编写测试011——IIS_AUDIO

Subject:FL2440无操作系统应用程序编写测试011——IIS_AUDIO

Date:   5-Dec-2011

By:        [email protected]

 

1.数字音频基础

◆声音(Sound):声音是由材料振动产生的一种物理现像,通过空气等介质的传播,引起人的耳膜振动,并为人耳所感知。自然界的声音信号本质是一种机械振动,是一种在空气中随时间变化的压力信号,主要用振幅和频率来刻画。当一个物体振动时,会引起周围空气质点的振动,由于空气的可压缩性,在质点的相互作用下,周围空气会产生交替的压缩和膨胀过程,并向外传播;

◆声波(Sound wave):从物理学的角度来讲,声音实际上是通过空气等介质传播的一种连续的波,音速c≈340m/s,声音在真空中无法传播;

FL2440无操作系统应用程序编写测试011——IIS_AUDIO_第1张图片

◆声音信号:由许多不同频率的分量信号组成的复合信号,声音信号是典型的连续信号,不仅在时间上是连续的,在幅度上也是连续的;

◆频宽:复合信号的频率范围;

◆音频信号(Audio):频宽为20Hz-20Khz的信号,可被人的耳朵感知,高于20Khz的声音称为超声;

◆数字音频:声音信号在计算机中用一系列的二进制数字表示方法,为了实现数字化,必须对信号在时间轴进行采样,在幅度轴上进行量化;

◆采样(Sampling):将声音信号在时间轴上离散化,即每隔一段时间抽取一个信号样本;

◆采样频率(FS):将模拟声音波形转换成数字音频时,每秒钟对声音波形进行采样的次数,采样频率越高所能描述的声波频率就越高,保真度也越高,但占用的信息数据量也就越大。常用的采样频率有8Khz,11.025Khz,22.05Khz,16Khz,37.8Khz,44.1Khz,48Khz;

FL2440无操作系统应用程序编写测试011——IIS_AUDIO_第2张图片

◆量化(Quantization):将连续的信号幅度离散化,如果幅度的划分是等间隔的,称为线性量化,否则为非线性量化。量化过程是一个A/D转换过程,其中量化位数,不仅决定着声音数据经数字化后的失真度,更决定着声音数据数据量的大小;

FL2440无操作系统应用程序编写测试011——IIS_AUDIO_第3张图片 

◆量化误差/噪声:某个采样时间点的模拟值和最近的量化值之间的差;

FL2440无操作系统应用程序编写测试011——IIS_AUDIO_第4张图片

◆奈奎斯特理论(Nyquist Theroem):采样频率大于或等于声音信号最高频率的两倍就能把以数字表达的声音还原成原来的声音,人耳的听觉频宽为20Hz-20Khz,所以采样频率高于40Khz时,可保证声音信号不失真;

◆声道数:指所使用的声音通道的个数,表明声音记录产生一个波形还是两个波形,也就是单声道或双声道。双声道也称立体声,比单声道听起来更为丰满,但它占用的存储空间是单声道的两倍;

◆数据速率:采样频率*量化位数*声道数,如采样频率为44.1Khz,量化位数为16bit,声道数为2,则数据速率为32fs,1411.2Khz

 

2.IIS总线

IIS(Inter-IC Sound bus)又称I2S,是Philps公司提出的串行数字音频总线协议。IIS是一种常用的音频设备接口,主要用于CD/MD/MP3等设备。IIS总线只处理声音数据,其他信号(如控制信号)必须单独传输。为了使芯片的引出管脚尽可能少,IIS只使用了三根串行总线,分别是:提供分时复用功能的数据线,字段(声道)选择线,时钟信号线。

S3C2440A IIS总线格式:

S3C2440A的IIS总线接口用来实现对外部8/16位立体音频数字信号编解码器电路的接口功能。支持IIS总线格式及MSB-Justified格式。FL2440无操作系统应用程序编写测试011——IIS_AUDIO_第5张图片

 

S3C2440A IIS接口工作方式:

◆正常传输方式:使用IISCON寄存器对FIFO进行控制,CPU通过轮询方式访问FIFO寄存器,以完成对FIFO缓存传输或接收的处理。当FIFO准备好发送数据,如果发送FIFO中不为空,FIFO准备好标志将被置为1。如果发送FIFO为空,FIFO准备好标志将置0。当接收FIFO装满,接收FIFO准备好标志位被置0。这些标志可以决定CPU读写FIFO的时机。本文IIS工作在此种方式下。

◆DMA模式:在该模式下,FIFO寄存器组的控制权掌握在DMA控制器上,当FIFO满时,由DMA控制器对FIFO中的数据进行处理。

◆传输/接收模式:IIS数据线将通过双通道DMA同时接收和发送音频数据。

 

3.控制框图

FL2440无操作系统应用程序编写测试011——IIS_AUDIO_第6张图片

IISDO/IISDI:数字音频信号的输出/输入;

IISSCLK:   串行时钟,每一个时钟信号传送一位音频信号,因此,IISCLK频率=采样频率*量化位数*声道数

IISLRCK:  帧时钟,用于切换左右声道,因此,IISLCRK频率=采样频率

CDCLK:    IIS只负责数字音频信号的传输,真正实现音频信号的播放、录音,需处理芯片(如UDA1341)支持,CDCLK为该芯片提供系统同步时钟,即编解码时钟,作为音频信号的ADC采样时钟,可选的CDCLK频率如下:

FL2440无操作系统应用程序编写测试011——IIS_AUDIO_第7张图片

 

4.UDA1341TS介绍

UDA1341TS是Philips公司生产的音频数字信号编译码器,可将立体声模拟信号转化为数字信号,同样也能将数字信号转化成模拟信号,并可用PGA和AGC对模拟信号进行处理。对于数字信号,该芯片提供了DSP功能。控制框图如下:

FL2440无操作系统应用程序编写测试011——IIS_AUDIO_第8张图片 

UDA1341TS提供2组音频信号输入线,1组音频信号输出线,1组IIS总线接口信号线及1组L3总线。IIS总线接口信号线包括:

BCK:                   位输入时钟

WS:                     字选择输入时钟

DATAO/DATAI:数据输出/输入

SYSCLK:           音频系统时钟

 

UDA1341TS有一微控制器模式,在该模式下,微控制器通过L3总线对它的数字音频处理参数和系统控制参数进行配置。L3总线接口信号线包括:

L3DATA:   微控制器接口数据

L3MODE: 微控制器接口模式

L3CLOCK:微控制器接口时钟

 

微控制器接口模式有两种:地址模式和数据传输模式

◆地址模式的高6位永远是000101,低两位表示传输模式(状态模式/数据0模式/数据1模式),其中状态模式用于选择UDA1341TS的工作状态:

FL2440无操作系统应用程序编写测试011——IIS_AUDIO_第9张图片

 

地址模式的时序:

FL2440无操作系统应用程序编写测试011——IIS_AUDIO_第10张图片 

 

数据传输模式:用于某确定的地址模式下的数据传送,其时序如下,

 FL2440无操作系统应用程序编写测试011——IIS_AUDIO_第11张图片

 

FL2440无操作系统应用程序编写测试011——IIS_AUDIO_第12张图片

 

注:S3c2440A没有L3总线接口,因此用三个通用IO来实现L3总线的传输。

 

5.硬件原理图

FL2440无操作系统应用程序编写测试011——IIS_AUDIO_第13张图片

由上图可以看出各信号的对应接线方式:

S3C2440A       UDA1341TS

IISSCLK  —— BCK

IISLRCK  —— WS

IISSDO    —— DATAI

IISSDI      —— DATAO

CDCLK   —— SYSCLK

GPB2      —— L3MODE

GPB3      —— L3DATA

GPB4      —— L3CLOCK

 

6.音频WindowsXP_Wav.h文件头(44字节)分析

   

   偏移地址       字节数    数据类型       内容                     备注

   00H               4            char               "RIFF"          

   04H               4            long int           03 b7 58H           文件总长-8=243544

   08H               8            char               "WAVEfmt "   

   10H               4            long int          10 00 00 00H       线性PCM编码

   14H               2            int                   01 00H                  int fmttag=0x01

   16H               2            int                   00 02H                  声道数=2

   18H               4            long int           56 22H                  采样率=22050Hz

   1CH              4            long int          01 58 88H             每秒播放字节数=88200Bytes

   20H               2            int                  00 04H                   采样一次占字节数=4

   22H               2            int                  00 10H                   量化数=16

   24H               4            char              "data"

   28H               4            long int          03 b7 34H            采样数据字节数=文长-44=243508

   2CH              到文尾   char                                              采样数据

 

   注:每秒播放字节数    =声道数*采样率*量化数/8

           采样一次占字节数=声道数*量化数/8

 

参考:http://www.cnblogs.com/pumax/archive/2010/10/01/1839760.html

 

7.UDA1341TS L3总线端口初始化及L3总线写函数

 

#define L3MODE   (1<<2) //GPB2 

#define L3DATA     (1<<3) //GPB3 

#define L3CLOCK (1<<4) //GPB4

 

//UDA131TS L3总线接口写入函数

//address为0地址模式,否则为数据传输模式

//data为传输数据

static void WriteL3(U8 address,U8 data){    

    int i, j;  

    if(!address){    //地址模式

        //L3CLOCK=High,L3MODE=Low

        rGPBDAT = rGPBDAT & ~(L3MODE|L3DATA|L3CLOCK )|L3CLOCK;  

    }else{             //数据传输模式

        //L3CLOCK=High,L3MODE=High

        rGPBDAT=rGPBDAT & ~(L3MODE|L3DATA|L3CLOCK)|(L3CLOCK|L3MODE);          }  

   

    for(j = 0; j < 5; j++);       //delay

   

    //将字节数据按串行格式发送,低位在前,高位在后

    for(i = 0; i < 8; i++){  

        if(data & 0x1){              //Bit[i]=1

            rGPBDAT &= ~L3CLOCK;  //L3CLOCK=Low

            rGPBDAT |= L3DATA;         //L3DATA =High

            for(j = 0; j < 5; j++);    

            rGPBDAT |= L3CLOCK;      //L3CLOCK=High

            rGPBDAT |= L3DATA;         //L3DATA =High

            for(j = 0; j < 5; j++);  

        }else{                    //Bit[i]=0

            rGPBDAT &= ~L3CLOCK;  //L3CLOCK=Low

            rGPBDAT &= ~L3DATA;     //L3DATA =High

            for(j = 0; j < 5; j++);  

            rGPBDAT |= L3CLOCK;      //L3CLOCK=High

            rGPBDAT &= ~L3DATA;     //L3DATA =Low

            for(j = 0; j < 5; j++);

        } 

        data >>= 1;                                //Next bit

    }  

 

//UDA1341TS L3 controller Initialize

static void UDA1341TS_L3_Init(void){

   

    //Set GPB[4:2] as output and Disable pull-up function 

    rGPBCON = rGPBCON & ~(0x3f<<4) | (0x15<<4);   

    rGPBUP  = rGPBUP  & ~(0x7<<2) | (0x7<<2);  

    //配置UDA1341TS L3

    //状态模式

    FL2440无操作系统应用程序编写测试011——IIS_AUDIO_第14张图片

    WriteL3(0,0x14+2);   

    WriteL3(1,0x40);  //0100_0000 Reset

   

 

    WriteL3(0,0x14+2);     

    WriteL3(1,0x10);    //0001_0000 System Clock 384fs,No DC filter,I2S-bus

    FL2440无操作系统应用程序编写测试011——IIS_AUDIO_第15张图片

   

    FL2440无操作系统应用程序编写测试011——IIS_AUDIO_第16张图片

 

    WriteL3(0,0x14+2);  

    WriteL3(1,0xc1);    //1100_0001 DAC Output gain 6dB,ADC off,DAT on

   

    FL2440无操作系统应用程序编写测试011——IIS_AUDIO_第17张图片

}

 

8.IIS寄存器设置

//IIS Port Initialize

static void IIS_Port_Init(void){

     //Set GPE[4:0] as IIS Port and Disable pull-up function

     rGPECON = rGPECON & ~(0x3ff) | 0x2aa;  

     rGPEUP  = rGPEUP  & ~(0x1f)  | 0x1f;      

    FL2440无操作系统应用程序编写测试011——IIS_AUDIO_第18张图片

 

    //DMA禁止,在接受空闲状态,不产生IISLRCK信号,IIS预分频使能   

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

    FL2440无操作系统应用程序编写测试011——IIS_AUDIO_第19张图片

 

    //主设备时钟PCLK,主设备模式,发送模式,IIS总线格式

    //串行数据(量化位数)16位,主时钟是384fs,串行位时钟32fs

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

    FL2440无操作系统应用程序编写测试011——IIS_AUDIO_第20张图片

 

    //fs=22.050Khz,CODECLK=384fs=8.4672Mhz

    //预分频N=PCLK/CODECLK-1)=33.8571/8.4672-1=2.9986,取N=3    

    rIISPSR = (3<<5)|3;

   FL2440无操作系统应用程序编写测试011——IIS_AUDIO_第21张图片

 

    //发送FIFO正常,发送FIFO使能

    rIISFCON = (0<<15)|(1<<13);

    FL2440无操作系统应用程序编写测试011——IIS_AUDIO_第22张图片

    }

 

9.源代码分析 IIS.c

#define L3MODE   (1<<2) //GPB2 

#define L3DATA     (1<<3) //GPB3 

#define L3CLOCK (1<<4) //GPB4

 

//UDA131TS L3总线接口写入函数

//address为0地址模式,否则为数据传输模式

//data为传输数据

static void WriteL3(U8 address,U8 data){    

    int i, j;  

    if(!address){    //地址模式

        //L3CLOCK=High,L3MODE=Low

        rGPBDAT = rGPBDAT & ~(L3MODE|L3DATA|L3CLOCK )|L3CLOCK;  

    }else{             //数据传输模式

        //L3CLOCK=High,L3MODE=High

        rGPBDAT=rGPBDAT & ~(L3MODE|L3DATA|L3CLOCK)|(L3CLOCK|L3MODE);          }  

   

    for(j = 0; j < 5; j++);       //delay

   

    //将字节数据按串行格式发送,低位在前,高位在后

    for(i = 0; i < 8; i++){  

        if(data & 0x1){              //Bit[i]=1

            rGPBDAT &= ~L3CLOCK;  //L3CLOCK=Low

            rGPBDAT |= L3DATA;         //L3DATA =High

            for(j = 0; j < 5; j++);    

            rGPBDAT |= L3CLOCK;      //L3CLOCK=High

            rGPBDAT |= L3DATA;         //L3DATA =High

            for(j = 0; j < 5; j++);  

        }else{                    //Bit[i]=0

            rGPBDAT &= ~L3CLOCK;  //L3CLOCK=Low

            rGPBDAT &= ~L3DATA;     //L3DATA =High

            for(j = 0; j < 5; j++);  

            rGPBDAT |= L3CLOCK;      //L3CLOCK=High

            rGPBDAT &= ~L3DATA;     //L3DATA =Low

            for(j = 0; j < 5; j++);

        }

          

        data >>= 1;                                //Next bit

    }  

 

//UDA1341TS L3 controller Initialize

static void UDA1341TS_L3_Init(void){

    //Set GPB[4:2] as output and Disable pull-up function 

    rGPBCON = rGPBCON & ~(0x3f<<4) | (0x15<<4);   

    rGPBUP  = rGPBUP  & ~(0x7<<2) | (0x7<<2);  

    //配置UDA1341TS L3

    //状态模式

    WriteL3(0,0x14+2);   

    WriteL3(1,0x40);  //0100_0000 Reset

   

    WriteL3(0,0x14+2);     

    WriteL3(1,0x10);     //0001_0000 System Clock 384fs,No DC filter,I2S-bus

   

    WriteL3(0,0x14+2);  

    WriteL3(1,0xc1);     //1100_0001 DAC Output gain 6dB,ADC off,DAT on

}

 

//IIS Port Initialize

static void IIS_Port_Init(void){

       //Set GPE[4:0] as IIS Port and Disable pull-up function

       rGPECON = rGPECON & ~(0x3ff) | 0x2aa;  

       rGPEUP  = rGPEUP  & ~(0x1f)  | 0x1f;     

       

       //DMA禁止,在接受空闲状态,不产生IISLRCK信号,IIS预分频使能   

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

   

       //主设备时钟PCLK,主设备模式,发送模式,IIS总线格式

       //串行数据(量化位数)16位,主时钟是384fs,串行位时钟32fs   

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

   

        //fs=22.050Khz,CODECLK=384fs=8.4672Mhz

        //预分频N=PCLK/CODECLK-1)=33.8571/8.4672-1=2.9986,N=3    

        rIISPSR = (3<<5)|3;  

   

        //发送FIFO正常,发送FIFO使能   

        rIISFCON = (0<<15)|(1<<13);   

}

 

//PlayWave

static void PlayWave(U8 buffer[], U32 length){  

    int i, count;    

    //IIS start   

    rIISCON |= 0x1;       

    for(count = 0; count <= length; count += 64){  

        while(rIISCON &(1<<7)); //wait until Transmit FIFO emtpy 

        //64 Bytes Transmit FIFO,16-width and 32-depth form

        for(i = 0; i < 32; i++){  

            rIISFIFO = (buffer[i*2+count]) + (buffer[i*2+1+count]<<8); 

        }

    }  

    //IIS close   

    rIISCON = 0x0;     

 

void IIS_PlayMusic_Test(void){  

       U32 Save_rMPLLCON = rMPLLCON;        //PCLK=50Mhz     

       UDA1341TS_L3_Init();                                  //UDA1341TS L3 controller Initialize

       IIS_Port_Init();                                                 //IIS Port Initialize

       rMPLLCON = (150<<12)|(5<<4)|(1<<0);    //PCLK= 33.8571Mhz

       PlayWave(WindowsXP_Wav, 243552);  

       rMPLLCON= Save_rMPLLCON;                 //PCLK=50Mhz

}

 

10.测试程序及结果

#include "UART.h"

#include "IIS.h"

int Main(void)

{

       UART0_Port_Init(115200);           //UART端口初始化

       UART0_Printf("Play Music...\n");

       IIS_PlayMusic_Test();                 //播放音频文件

       UART0_Printf("End\n");

       while(1){

              ;            

       }

       return 0;

}

 

1)测试正常,耳机可听到声音输出。

2)将预分频N改为1(开始以为该音频文件采样频率为44.1Khz)声音较为尖锐

FL2440无操作系统应用程序编写测试011——IIS_AUDIO_第23张图片

 

 

你可能感兴趣的:(function,测试,buffer,IIS,audio,output)