wm8976的初始化函数、写寄存器函数和音量控制函数分析

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,输出音量才会更新




版权声明:本文为qingkongyeyue原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。