本帖最后由 xuhany 于 2014-7-10 17:53 编辑
HELPER2416-RAWOS音频驱动
一、理论知识
1.声音的基本概念,声音是通过一定介质传播的连续的波,它的属性有如下:
a.声音的强弱叫音调,也叫频率,单位赫兹Hz,人能听到的范围为 20Hz-20KHz,>20KHz叫超声波,<20Hz叫微波.
b.声音的响度叫音量,也叫振幅,单位分贝dB,人能感受到1-130dB
c.声音的数字化,声音模拟信号->采样->量化->编码->wav文件
采样频率:单位时间抽取的样品数量,频率越高,音质越好,常见 8KHz,11.025KHz,22.05KHz,44.1KHz
量化:每个采样点数据的表示位数,精度越大,音质越好,常见8bit,16bit
声道:多个声道同时采样,能表现出立体环绕等,0左声道1右声道2立体声
d.声音的还原,wav文件->解码->DAC还原为声音
wav文件有4中编码方式,PCM,ADPCM,A/mu-Law,ACM
其中PCM无损无压缩, ADPCM为1:4有损压缩
2.I2S控制器,IC内置音频总线
I2S是philips公司为数字音频设备之间的音频数据传输而定制的一种总线.
其他还有PCM标准,AC97标准
3.CODEC编解码芯片
4.wav文件格式 主要分为4个chunk,分别是RIFF,FMT,Fact,Data
解码时候需要用到的是FMT中采样频率,采样精度,声道,预备缓存区共4个参数 Data中的数据长度,和数据内容共2个参数 第一次接触这个格式,可能比较难理解,帖子幅度有限,不能详细概括,谅解
二、I2S工作过程
1.I2S总线规范
SCK串行时钟,随数据一起,SCK的频率=2*采样频率*采样位数
WS声道选择,高左声道,低右声道,WS频率=采样频率
SD串行数据 时序如下,由SDF指定:
2.s3c2416用到的引脚有I2SLRCK\I2SSCLK\I2SSDO\I2SMCLK
I2SSCLK对应CLK,I2SLRCK对应WS,I2SSDO对应SD
I2SMCLK系统时钟
三、WM8731L工作过程
1.wm8731是一款集成耳机驱动器的低功耗、高质量音频编码解码器,为MP3,录音机设计,具有24位ad/da
2.s3c2416用到的引脚有I2C_SCL\I2C_SDA
整个工作过程就是AC -> Filters -> DAC -> VOL -> Stereo Headphone Output
四、I2S驱动实现 s3c2416支持两种操作I2S的方式
1.IO方式,此方法效率较低,mcu占用率高
2.DMA方式,此方法较好
3.IO方式具体实现如下,其中关键参数有IMS,SDF,BFS,BLC,LRP
GPBPU_REG = (GPBPU_REG & (~(3<<0))) | (0<<0);
GPBPU_REG = (GPBPU_REG & (~(3<<2))) | (0<<2);
GPBPU_REG = (GPBPU_REG & (~(3<<4))) | (0<<4);
GPBPU_REG = (GPBPU_REG & (~(3<<6))) | (0<<6);
GPBPU_REG = (GPBPU_REG & (~(3<<8))) | (0<<8);
GPECON_REG = (GPECON_REG & (~(3<<0))) | (2<<0);
GPECON_REG = (GPECON_REG & (~(3<<2))) | (2<<2);
GPECON_REG = (GPECON_REG & (~(3<<4))) | (2<<4);
GPECON_REG = (GPECON_REG & (~(3<<6))) | (2<<6);
GPECON_REG = (GPECON_REG & (~(3<<8))) | (2<<8);
IISPSR_REG = (3<<8)|(1<<15);
IISCON_REG = 0;
IISMOD_REG = (0<<1)|(3<<3)|(0<<10)|(0<<13);
IISFIC_REG = 0x08000;
IISFIC_REG &= ~(1<<15);
4.DMA方式实现
IISCON_REG = 0x0;
DISRC0_REG = (uint32_t)TxBuffer;
DIDST0_REG = IISTXD;
DIDSTC0_REG = (0<<2) | (1<<1) | (1<<0);
DCON0_REG = (4096) | (2<<20) | (1<<22) | (1<<24) | 0xe0000000;
DMAREQSEL0_REG = (1<<0) | (4<<1);
register_irq(17, dma_0_ISRService);
INTMOD_REG &= ~(1 << 17);
INTSUBMSK_REG &= ~(1 << 18);
INTMSK_REG &= ~(1 << 17);
IISFIC_REG |= (1<<15);
IISFIC_REG &= ~(1<<15);
IISMOD_REG = (0<<1)|(2<<3);
if(bitlen == 8)
IISMOD_REG = (IISMOD_REG & (~(3<<13))) | (1<<13);
else if(bitlen == 16)
IISMOD_REG = (IISMOD_REG & (~(3<<13))) | (0<<13);
else if(bitlen == 24)
IISMOD_REG = (IISMOD_REG & (~(3<<13))) | (2<<13);
prescale = 96000000/(384*fs);
IISPSR_REG = (prescale<<8) | (1<<15);
五、WM8731L驱动实现
IIC_init(2000);
IIC_open( );
wm8731_write(0x10,0x18);
wm8731_write(0x0E,0x02);
wm8731_write(0x12,0x01);
wm8731_write(0x08,0x3b);
wm8731_write(0x0a,0x00);
wm8731_write(0x0c,0x47);
IIC_close();
结束语,感谢各位的耐心阅读,帖子先写到这,意犹未尽,希望后面还能多写几篇。
然后大家有更多的疑问,可以继续通过论坛讨论交流,为后来网友以作借鉴。
最后,感谢helper2416的老板,为大家提供这样一个共同的学习环境,希望大家能多多利用,这样一个活动确实很难得。
论坛ID:xuhany
提交时间:2014/07/10 17:50