M62429L音量控制IC驱动

前言

        最近项目开发中,要控制AV端的音量,由于主控端的AV音量控制gpio被复用为其它功能口了,不得已增加一个ic去控制音量的输出,这里使用的是M62429L音量控制IC。

1.M62429音量ic概述

        M62429L是一款串行数据控制的双声道电子音量控制器芯片,允许每个声道独立控制,音量为0dB~ -83dB,每级可控1dB。

1.1  ic引脚及其功能

硬件引脚图如下:

 引脚功能定义如下:

 讲音量信号输入到VIN1或者VIN2经过内部电路处理后,从VOUT1或者VOUT2输出;

1.2 控制数据格式

一帧控制数据为10bit,bit0选择需要控制的声道,bit1选择控制几个声道,bit2-bit8为控制音量的数据,bit9-bit10默认为高电平1。

 1.2.1  音量控制数据bit2-bit8

音量控制数据分为两部分,可以这样去理解,D2-D6控制大的步伐,可以从表中看出每组数据间隔4dB,D7-D8控制小的步伐,0~3dB。

举个例子,假如你设置音量为-7dB,那么此时D2-D6就应该设置为-4dB(00101),D7-D8配置为-3dB(00),依次类推,最小音量可以设置为-83dB,最大音量为0dB。

 1.3 控制信号时序图

说完数据格式,接下来就是要去了解clock,data的时序了,CLOCK和DATA引脚通常是从主控端引出两个gpio脚,根据这两个gpio去模拟时序进行数据发送,模拟clock时序的时候需要注意它的最小时钟周期为4us;从下图中可以知道,bit0-bit10发送的数据都是在时钟上升沿的时候ic会去读取,需要注意的是在上升沿读取完位数据后,要下下降沿前把位数据拉为低电平0,因为在时钟为下降沿的时候ic会读取触发信号,如果下降沿读取的信号为高电平1表示一帧数据(D0-D10)发送完成,所以在D10数据读取完成后,data线维持为高电平表示数据发送完成。

 2.软件驱动控制ic

软件驱动上还是比较简单的,可以将D2-D6、D7-D8控制数据用数组的形式列举出来,然后根据设置的真实音量整合成一帧数据发送即可。

M62429L_data函数中参数track_set:为D0位声道选择,ctrl_set:为控制声道数,vol:为设置音量(0~100),函数中先将vol转换为0-87区间的数,然后再去索引对应两数组的哪个值,最后,将其移位整合为一组数据。

M62429L_send_data函数为发送的数据、clock和data时序。

#define DATA_D0_0 0x0         //track1
#define DATA_D0_1 0x1         //track2
#define DATA_D1_0 (0x0 <<1)   //all ctrl
#define DATA_D1_1 (0x1 <<1)   //one ctrl
#define DATA_D9_D10 (0x11 <<9)

int8_t data_d6_d2[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,
                            0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15};   //-& ~ 0db
int8_t data_d8_d7[] = {0x0,0x1,0x2,0x3};   //-3db ~ 0db

void M62429L_gpio_init()
{
    gpio_configure(PINPAD_T14, GPIO_DIR_OUTPUT); //clk
    gpio_configure(PINPAD_T19, GPIO_DIR_OUTPUT); //data
    gpio_set_output(PINPAD_T14,0);
    gpio_set_output(PINPAD_T19,0);
}

void M62429L_set_clk(bool value)
{
    gpio_set_output(PINPAD_T14,value);
}

void M62429L_set_data(bool value)
{
    gpio_set_output(PINPAD_T19,value);
}

int16_t M62429L_data(bool track_set,bool ctrl_set,int8_t vol)
{
    int16_t vol_data = 0x00;
    int8_t data8_2[2]={0};

    if(track_set){
        vol_data |= DATA_D0_1;
    }
    if(ctrl_set){
        vol_data |= DATA_D1_1;
    }
    vol = vol * 87 / 100;
    data8_2[0] = vol /4;
    data8_2[1] = vol %4;
    vol_data = vol_data | (data_d6_d2[data8_2[0]] <<2) | (data_d8_d7[data8_2[1]] <<7) | DATA_D9_D10;
    printf("vol:%d,data[0]:%d,data[1]:%d,vol_data:%d\n",vol,data8_2[0],data8_2[1],vol_data);

    return vol_data;
}

void M62429L_send_data(bool track_set,bool ctrl_set,int8_t vol)
{
    int16_t vol_data = 0;
    bool data_bit = 0;

    vol_data = M62429L_data(track_set,ctrl_set,vol);
    for(int i=0; i<=9;i++){
        data_bit = (vol_data>>i)&0x1;
        M62429L_set_clk(0);
        usleep(10);
        M62429L_set_data(data_bit);
        usleep(10);
        M62429L_set_clk(1);
        usleep(10);
        M62429L_set_data(0);
        usleep(10);
    }
    M62429L_set_clk(0);
    usleep(10);
    M62429L_set_data(1);
    usleep(10);
    M62429L_set_clk(1);
    usleep(10);
    M62429L_set_clk(0);
    usleep(10);

}

猜你喜欢

转载自blog.csdn.net/weixin_49576307/article/details/131610122