微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 七 ARM9(S3C2440)的IIS-理论知识及程序实例

七 ARM9(S3C2440)的IIS-理论知识及程序实例

时间:11-27 来源:互联网 点击:

Data Chunk是真正保存wav数据的地方,以data作为该Chunk的标示。然后是
数据的大小。紧接着就是wav数据。根据Format Chunk中的声道数以及采样bit数,
wav数据的bit位置可以分成以下几种形式:
|单声道|取样1|取样2|取样3|取样4|8bit量化 |声道0|声道0|声道0|声道0

|双声道|取样1|取样2

|8bit量化 |声道0(左)|声道1(右) |声道0(左) |声道1(右)

取样1|取样2|
|单声道|

| 16bit量化 |声道0|声道0|声道0|声道0|(低位字节)|(高位字节)|(低位字节)|(高位字节)

取样1

|双声道|------------------------------------------------
| 16bit量化 |声道0(左)|声道0(左) |声道1(右)|声道1(右)
|(低位字节)| (高位字节)| (低位字节)| (高位字节)
图6 wav数据bit位置安排方式

Data Chunk头结构定义如下:
struct DATA_BLOCK
{
charszDataID[4];// d,a,t,a
DWORDdwDataSize;
};

看完上面这些我们应该要清楚在文件的开始地址偏移0x18(24)处是文件的采样频率,0x16(22)处是声道,0x2c(44)处才是真正的wave数据,也就是我们要播放的数据。

下面是UDA1314通过IIS接口的放音程序

#include"2440addr.h"
#include"WindowsXP_Wav.h"
#include"What_are_words.h"
#include"def.h"
//L3接口

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

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

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

//L3总线接口的写函数

//输入参数data为要写入的数据

//输入参数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++)

;//等待一段时间

//并行数据转串行数据输出,以低位在前、高位在后的顺序

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

{

if(data & 0x1)// 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

rGPBDAT &= ~L3D;//L3D=L

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

;//等待一段时间

}

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开始传输: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(0xc1,0);//1,0,0,0, 0,0,01:状态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;

//无效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 |= 0x1;

while(flag)

{

if((rIISCON & (1<7))==0)//检查输出FIFO是否为空

{

//FIFO中的数据为16位,深度为32

//当输出FIFO为空时,一次性向FIFO写入32个16位数据

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

{

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

}

count+=64;

if(count>length)

flag=0;//音频数据传输完,则退出

}

}

rIISCON = 0x0;//关闭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//上面的解释是fs=44.1时,而我的文件fs=22.05,所以令Sdiv=1

rMPLLCON = (150<12) | (5<4) | 1;

//配置L3接口总线,GPB2:L3MODE, GPB3:L3DATA, GPB4:L3CLOCK

rGPBCON = 0x015550;//输出

rGPBUP= 0x7ff;//上拉无效

rGPBDAT = 0x1e4;

//配置IIS接口

rGPEUP = rGPEUP & ~(0x1f) | 0x1f;//上拉无效,GPE[4:0] 1 1111

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

Uart_Init(33857000,115200);//根据PCLK设置波特率
Uart_Printf("nNOW PLAY THE WindowsXP");
Uart_Printf("nsample=%d",*(U32 *)(WindowsXP_Wav+0x18));//输出采样频率
playsound(WindowsXP_Wav+44,sizeof(WindowsXP_Wav)-44);//在数据开始处开始播放
rMPLLCON = (150<12) | (5<4) | 0;//为下面播放44.1KHZ文件设置
Uart_Init(33857000*2,115200);//PCLK设置波特率
Uart_Printf("nNOW PLAY THE What_are_words");
Uart_Printf("nsample=%d",*(U32 *)(What_are_words+0x18));

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top