当前位置:首页 > 单片机 > 单片机
[导读]在消费电子产品中,往往都会用到音频系统来播放音乐、进行通话等多媒体应用,此外,对于一些需语音提示的产品,音频部分都是不可或缺的功能。笔者此处就s3c2416的音频驱动实现作一个简单的介绍。1. IIS音频总线s3c24

在消费电子产品中,往往都会用到音频系统来播放音乐、进行通话等多媒体应用,此外,对于一些需语音提示的产品,音频部分都是不可或缺的功能。笔者此处就s3c2416的音频驱动实现作一个简单的介绍。

1. IIS音频总线

s3c2416支持IIS、PCM、AC97这三种音频接口,此处只分析IIS音频接口。IIS接口(Inter-IC Sound)在20世纪80年代首先被飞利浦公司用于消费音频,为数字音频设备之间的音频数据传输而制定的一种总线标准。IIS有以下三个主要的信号:

1) 串行时钟SCLK,也叫做位时钟(BCLK)。数字音频的每一位均需对应一个SCLK脉冲,因此位时钟频率应大于等于2*采样频率*采样位数。乘以2表示每个采样会产生左声道和右声道的数据。

2) 帧时钟LRCK,也叫做左右声道切换时钟(WS)。LRCK为1时表示传输的是右声道的数据,为0时表示传输的是左声道的数据,因此IIS是非常适合于立体声系统的。LRCK是一个占空比约50%的方波,这个频率是需要尽可能与采样频率一致的,不然无法体现原来的音频本质。

3) 串行数据SDATA,用二进制补码表示音频数据。在串行时钟SCLK脉冲下,数据一位一位出现在SDATA线上。对于具体的IIS主机或设备,为支持全双工(例如通话时需同时支持放音与录音),串行数据线分串行输入SDI和串行输出SDO这两根。SDI用来传输采样设备数字化后的录音数据,SDO用来传输需播放的音频数据。

有时为了IIS主控制与IIS设备能够更好的同步,还需要传输一路时钟信号MCLK,也叫做主时钟。主要用于IIS设备A/D、D/A采样时的采样时钟,一般是采样频率的256倍、384倍、512倍、768倍。在满足要求的条件下,应尽可能选用较低的主时钟。

2. WM8960音频编解码器

WM8960是欧胜微电子推出的一款低功耗、高质量的立体编码解码器。该芯片内置有麦克风接口、立体声耳机驱动器以及D类立体声扬声器驱动,24比特模数转换器(ADC)和数模转换器(DAC)。

WM8960具有三对左右声道的模拟输入,其中INPUT1专用于Mic输入,支持单端或差分的Mic信号接入。这个输入具有一个程控放大器(PGA),并且可用自动电平控制(ALC)对Mic信号进行增益放大。其它的INPUT2、3可做为Mic差分接入的同相输入或线输入。

WM8960具有一对左右声道的耳机输出,16欧负载时,输出40mW。一对D类左右声道扬声器输出,每声道8欧负载,在1W输出功率时,具有87%的效率。一路左右声道混合输出。

3. WM8960驱动编写

声音是模拟信号,cpu是不能处理模拟信号的,并且认为模拟信号也是不具有传输性的。因此音频编解码器至少具有三个主要功能部分:模数转换器(ADC)、数模转换器(DAC)、程控放大器(PGA)。ADC用来采样外部的模拟声音信号(如Mic录音),进行离散化后,转换成数字音频,通过音频总线(如IIS)传输给cpu,cpu再对数字音频进行处理,如调频、混合、存储等。DAC用来把从cpu过来的数字音频信号还原成原来的模拟声音信号,DAC转换后的离散化PCM调制信号再通过滤波器真实还原出原来的模拟声音。PGA可在各个阶段对音频信号进行可编程的增益放大,例如音量的控制(可参考WM8960_HeadphoneVolume()函数),Mic灵敏度的调节(可参考WM8960_RecorderVolume()函数)等。

WM8960在使用前必须进行初始化,即需配置音频接口IIS的参数(可参考WM8960_Init()的实现),若进行录音,需配置录音路径的上电、接通,并进行增益的设定(具体见WM8960_RecorderStart()函数的实现)。若进行放音,需配置是耳机、扬声器等的话音路径,进行增益设定(可参考WM8960_HeadphoneStart()函数的实现)。IIS是音频接口,只能传输音频信号,因此WM8960还需另外的IIC接口,通过IIC总线写寄存器对这些配置进行设定。IIC驱动编写在前面的章节有详细的介绍,此处不再细说,WM8960模块驱动WM8960.c如下:

#include "IIC.h"

#include "WM8960.h"

#define VolumeLevel 7

static int RecorderVolume;

static int HeadphoneVolume;

// WM8960寄存器不能通过IIC读,开辟缓存记录寄存器的变化

static unsigned short WM8960_Reg[56] = {

0x0097, 0x0097, 0x0000, 0x0000,

0x0000, 0x0008, 0x0000, 0x000a,

0x01c0, 0x0000, 0x00ff, 0x00ff,

0x0000, 0x0000, 0x0000, 0x0000,

0x0000, 0x007b, 0x0100, 0x0032,

0x0000, 0x00c3, 0x00c3, 0x01c0,

0x0000, 0x0000, 0x0000, 0x0000,

0x0000, 0x0000, 0x0000, 0x0000,

0x0100, 0x0100, 0x0050, 0x0050,

0x0050, 0x0050, 0x0000, 0x0000,

0x0000, 0x0000, 0x0040, 0x0000,

0x0000, 0x0050, 0x0050, 0x0000,

0x0002, 0x0037, 0x004d, 0x0080,

0x0008, 0x0031, 0x0026, 0x00e9,

};

static void WM8960_WriteReg(unsigned char RegAddr, unsigned short Value)

{

unsigned char Data;

unsigned char Addr;

// WM8960只有7位的寄存器地址,外加寄存器值第8位,构成8位数据

Addr = (RegAddr<<1) |((Value>>8) & 0x1);

// WM8960有9位的寄存器值,最高位与寄存器地址一齐发送

Data = (unsigned char)Value; // 低8位寄存器值

IIC_WriteBytes(WM8960_SlaveAddr,Addr, &Data, 1);

WM8960_Reg[RegAddr] = Value; // 写成功后更新寄存器的值

}

static unsigned short WM8960_ReadReg(unsigned char RegAddr)

{

return WM8960_Reg[RegAddr]; // 返换缓存的WM8960寄存器的值(9位)

}

unsigned char WM8960_HeadphoneVolume(unsigned char Control)

{

// -10db ~ 6db (0x6f ~ 0x7f)

unsigned char Level;

if (Control == VolumeDown) { // 耳机音量减

if ((0x7f-0x6f)/VolumeLevel ==0) {

HeadphoneVolume--;

} else {

HeadphoneVolume -=(0x7f-0x6f)/VolumeLevel;

}

if (HeadphoneVolume < 0) {

HeadphoneVolume = 0;

}

} else {// 耳机音量加

if ((0x7f-0x6f)/VolumeLevel ==0) {

HeadphoneVolume++;

} else {

HeadphoneVolume +=(0x7f-0x6f)/VolumeLevel;

}

if (HeadphoneVolume >VolumeLevel) {

HeadphoneVolume =VolumeLevel;

}

}

if (HeadphoneVolume == 0) {

Level = 0; // 静音

} else {

Level =((0x7f-0x6f)*HeadphoneVolume)/VolumeLevel + 0x6f;

}

// Headphone Volume Updata

WM8960_WriteReg(0x02,(1<<8)|Level);

WM8960_WriteReg(0x03,(1<<8)|Level);

return ((HeadphoneVolume*100)/VolumeLevel);// 返回音量百分比

}

void WM8960_HeadphoneStop()

{

unsigned short RegValue;

RegValue = WM8960_ReadReg(0x1a);

RegValue =~((1<<8)|(1<<7)|(1<<6)|(1<<5));

WM8960_WriteReg(0x1a, RegValue);

}

void WM8960_HeadphoneStart()

{

unsigned short RegValue;

// DAC Left/Right,LOUT1/ROUT1Output Buffer Power up

WM8960_WriteReg(0x1a, 0x01e0);

// Left DAC Digital Volume -28db

WM8960_WriteReg(0x0a, 0x01c5);

// Right DAC Digital Volume -28db

WM8960_WriteReg(0x0b, 0x01c5);

// DAC Digital No mute

WM8960_WriteReg(0x05, 0x0000);

// Left DAC to Left Output Mixer

WM8960_WriteReg(0x22, 0x0100);

// Right DAC to Left Output Mixer

WM8960_WriteReg(0x25, 0x0100);

// Left/Right Output Mixer Enable

RegValue = WM8960_ReadReg(0x2f);

RegValue |= (1<<2) |(1<<3);

WM8960_WriteReg(0x2f, RegValue);

}

unsigned char WM8960_RecorderVolume(unsigned char Control)

{

// -10db ~ 10db (0xaf ~ 0xd7)

unsigned char Level;

if (Control == VolumeDown) { //Mic灵敏度调低

if ((0xd7-0xaf)/VolumeLevel ==0) {

RecorderVolume--;

} else {

RecorderVolume -=(0xd7-0xaf)/VolumeLevel;

}

if (RecorderVolume < 0) {

RecorderVolume = 0;

}

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

IIC是Philips推出的芯片间串行传输总线,它以二根连线实现完善的全双工同步数据传送,可以极方便地构成多机系统和外围器件扩展系统。由于其接口简单灵活,很多外围器件均提供了IIC接口,如手机、平板常用的重力传感器

关键字: s3c2416 裸机开发 iic驱动

现在主要讲解一下在GCC移植UCGUI,Makefile工程如何加入目录,加入源码,c标准库,编译选项的设置。笔者的Makefile模板提取自uboot,工程中加入目录,加入源码都是很简单的,详细的介绍请参考前面章节”...

关键字: gcc s3c2416 ucgui 移植 裸机开发

jpeg格式是一种针对相片影像而广泛使用的一种失真压缩标准,其压缩技术十分先进,用有损压缩方式去除冗余的图像数据,在获得极高压缩率的同时,能展现十分丰富生动的图像,能用最少的磁盘空间得到较好的图像品质。由

关键字: s3c2416 移植 裸机开发 libjpeg

S3C2416裸机开发系列十八_音频驱动实现(2)标签:WM8960IIS音频驱动s3c2416裸机开发2014-06-10 09:50853人阅读评论(0)收藏举报分类:s3c2416裸机开发(24)版权声明:本文为博...

关键字: s3c2416 裸机开发 音频驱动

很多的嵌入式系统都需要人机交互,对于输出设备,LCD以其显示质量高、画面效果好等优点得到了极其广泛的应用。s3c2416包含了一个LCD控制器,笔者此处就s3c2416的LCD应用作一个简单的介绍。1、LCD控制器概述1...

关键字: s3c2416 裸机开发 rgb屏 驱动显示

/*** 有待学习 *****/ Linux 下的IIS 音频驱动程序主要都在/kernel/drivers/sound/s3c2410-uda1341.c 文件中。 在音频驱动程序中有2个比较重要的结构体:typede...

关键字: iis s3c2410 音频驱动

在嵌入式设计中,由于Nand Flash具有大容量,擦写次数高,接口简单等优点,常用作固化存储器。S3C2416支持Nand启动,因此Nand存储器可以直接保存固化代码以及其它的数据。笔者在此简单的介绍Nand flas...

关键字: nand驱动 s3c2416 裸机开发 nand启动

笔者前面章节简单介绍了s3c2416启动代码的实现过程,启动代码就是用来处理cpu体系结构中一些底层内容,一个功能强大的启动代码是可以当作bootloader(如uboot)来用的。有了启动代码,用户就可以专注于用c来作...

关键字: mdk s3c2416 启动代码 裸机开发

启动代码是处理器上电复位后最先运行的一段代码。主要是用来把处理器初始化到一个确定的状态,为c运行环境作好准备。如设置异常向量表,初始化系统时钟,初始化外部内存,把用户代码拷贝到外部内存,初始化栈,清0全

关键字: s3c2416 启动代码 流水灯 裸机开发

S3C2416裸机开发系列十九_Fatfs下播放录音wav音频文件标签:wavfatfs音频播放s3c2416sd驱动2014-06-11 09:551938人阅读评论(0)收藏举报分类:s3c2416裸机开发(24)版...

关键字: s3c2416 裸机开发 播放录音 音频文件
关闭
关闭