1、wm8976的写寄存器函数
(1.1)时序图
(1.2)函数
static void wm8976_write_reg(unsigned char reg, unsigned int data)
{
int i;
//对于wm8976来说,传输的是16位数据,这16位数据里面,高七位表示寄存器地址,低9位表示寄存器的值
unsigned short val = (reg << 9) | (data & 0x1ff);
//先说明一下: 查看原理图可知wm8976引脚csb,dat,clk分别对应2440芯片的GPB2,3,4引脚
//根据时序图分析
//三个引脚先设置为高电平
set_csb(1);
set_dat(1);
set_clk(1);
//把val值写入wm8976,共16位,先传输最高位。假如某位是1,数据线上输出1,先让时钟变为低电平,然后时钟变为高电平,一个周期传输一位。
for (i = 0; i < 16; i++){
if (val & (1<<15))
{
set_clk(0);
set_dat(1);
delay();
set_clk(1);
}
else
{
set_clk(0);
set_dat(0);
delay();
set_clk(1);
}
//处理好最高位,移动次高位到最高位处
val = val << 1;
}
//传输16位完成后,让csb信号产生低脉冲,写入wm8976
set_csb(0);
delay();
//引脚恢复到高电平状态
set_csb(1);
set_dat(1);
set_clk(1);
}
2、wm8976的初始化函数
(1)需要写哪些寄存器
(2)程序
/* 通过控制接口(GPB2,3,4)读写寄存器进行初始化 */
void wm8976_init(void)
{
/* software reset */
wm8976_write_reg(0, 0);
/* OUT2的左/右声道打开
* 左/右通道输出混音打开
* 左/右DAC打开
*/
wm8976_write_reg(0x3, 0x6f);
wm8976_write_reg(0x1, 0x1f);//biasen,BUFIOEN.VMIDSEL=11b
wm8976_write_reg(0x2, 0x185);//ROUT1EN LOUT1EN, inpu PGA enable ,ADC enable
wm8976_write_reg(0x6, 0x0);//SYSCLK=MCLK
wm8976_write_reg(0x4, 0x10);//16bit
wm8976_write_reg(0x2B,0x10);//BTL OUTPUT
wm8976_write_reg(0x9, 0x50);//Jack detect enable
wm8976_write_reg(0xD, 0x21);//Jack detect
wm8976_write_reg(0x7, 0x01);//Jack detect
}
3、音量控制函数
/*
* volume : 0~100, 0表示最小音量
*/
void wm8976_set_volume(int volume)
{
/* ioctl: val越大表示音量越大, 0-最小, 100-最大
* WM8976: 地址为52,53的寄存器bit[5:0]表示音量, 值越大音量越大, 0-63
*/
/*这里(1<<8)|val的理解:假若输入最大音量,也就是说volume为100,根据val = volume * 63 / 100可得val为63,转化成8位二进制也就是0001 1111
int val = volume * 63 / 100;
wm8976_write_reg(52, (1<<8)|val);
wm8976_write_reg(53, (1<<8)|val);
}
4、wm8976_write_reg(53, (1<<8)|val)中(1<<8)|val的理解
从下面两个表可以看出地址为52和53的寄存器里的bit8必须为1,输出音量才会更新