关于具有I2C总线的TEA6320的使用

2018-12-04 07:13:59来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

 

现在先了解一下TEA6320,TEA6320是一个I2C总线控制音响应用的立体声放大器,,它的I2C协议和音量控制如下:

 



 

 

 

 

它的主要代码:


void delay1ms(unsigned int Delay ) //1ms延时
{
    unsigned int j;
    for(;Delay>0;Delay--)
    for(j=0;j<125;j++);
}

void init()                 ///总线初始化 将总线都拉高一释放总线  发送启动信号前,要先初始化总线。即总线检测到总线空闲才开始发送启动信号
{
    SDA=1;
    _nop_();
    SCL=1;
    _nop_();
}

void InitUART(void)
{
    TMOD = 0x20;                     //将Timer1设置为Mode2以产生波特率
    SCON = 0x50;                    //串口工作方式2
    TH1 = 0xfd;                        //波特率9600
    TL1 = TH1;
    PCON = 0x00;                    //将SMOD设置为0
    TR1 = 1;                        //开启定时器1
    EA=1;                           //开启总中断
    ES=1;                           //开启串口中断
}

void SendData(uchar Dat)             //发送数据
{
    ACC = Dat;
    CY=P;
    TB8=~CY;
    SBUF=ACC;
    while(!TI);
    TI = 0;                             //软件复位      
}
            
void I2C_start()
{
    SDA=1;           //起始信号
    _nop_();
    SCL=1;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    SDA=0;  
    _nop_();
    _nop_();
    _nop_();            
    _nop_();           
    _nop_();

}
void I2C_stop()
{
    SDA=0;           //停止信号
    _nop_();
    SCL=1;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    SDA=1;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
}
void ack()   //应答信号
{
        SDA=0;
        _nop_();
        SCL=1;
        _nop_();
        SCL=0;
        _nop_();
//    SDA = 1;
//    SCL = 1;
//    _nop_();
//    while(SDA==1);
//    SCL = 0;
}

void I2C_sendByte(unsigned char dat)  //发送数据
{ 
unsigned char temp; unsigned char i; SCL=0; _nop_(); _nop_(); _nop_(); _nop_(); for(i=0;i<8;i++) //要发送的数据长度为8位 { temp=dat; if(temp<<i&0x80) SDA=1; //判断发送位 else SDA=0; _nop_(); SCL=1; //置时钟线为高,通知从机开始接受数据位 _nop_(); _nop_(); _nop_(); //保证时钟高电平周期大于4us ` _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); SCL=0; //拉低SCL,为下次数据传输做好准备 _nop_(); _nop_(); } SDA=1; //释放SDA总线,接下来由从设备控制,比如从设备接收完数据后,在SCL为高时,拉低SDA作为应答信号 _nop_(); _nop_(); _nop_(); _nop_(); } main() { InitUART(); init(); while(1) { CS=1; A10=0; A11=0; A12=0; A13=0; A14=0; OE=0; /*.....ENABLE变低,总线开始接受数据.....*/ ALE=0; bb=0; ii=P0; aa=0xff; V24=0; if(ii==0x8f) // 5个按钮不动作,关的状态 { delay1ms(50); if(ii==0x8f) { bb=0xf9; P0=bb; aa=0x11; delay1ms(200); CS=1; A10=1; A11=0; A12=0; A13=0; A14=0; WE=0; delay1ms(500); } } if(ii==0x8e) { delay1ms(50); if(ii==0x8e) { bb=0xf1; P0=bb; aa=0x11; delay1ms(200); CS=1; A10=1; A11=0; A12=0; A13=0; A14=0; WE=0; delay1ms(500); SendData(0xAA); I2C_start(); I2C_sendByte(0x80); //MAD,第一个字节 ack(); I2C_sendByte(0x00); //SAD,第二个字节 ack(); I2C_sendByte(0x2C); //响度 +20dB ack(); I2C_sendByte(0x3f); //前右 响度0dB ack(); I2C_sendByte(0x3f); //前左 响度0dB ack(); I2C_sendByte(0x3F); //后右 响度0dB ack(); I2C_sendByte(0x3F); //后左 响度0dB ack(); I2C_sendByte(0x10); //低音 响度+15dB ack(); I2C_sendByte(0x10); //高音 响度+15dB ack(); I2C_sendByte(0x7f); //声道选择 直接静音关闭,选通IAL和IAR ack(); I2C_stop(); delay1ms(5000); I2C_start(); I2C_sendByte(0x80); //MAD ack(); I2C_sendByte(0x00); //SAD ack(); I2C_sendByte(0x2C); //响度 +20dB ack(); I2C_sendByte(0x3f); //前右 响度0dB ack(); I2C_sendByte(0x3f); //前左 响度0dB ack(); I2C_sendByte(0x3F); //后右 响度0dB ack(); I2C_sendByte(0x3F); //后左 响度0dB ack(); I2C_sendByte(0x10); //低音 响度+15dB ack(); I2C_sendByte(0x10); //高音 响度+15dB ack(); I2C_sendByte(0xff); //声道选择 直接静音,选通IAL和IAR ack(); I2C_stop(); SendData(0x55); } } if(ii==0x8d) //4脚按钮动作处于开的状态 { delay1ms(50); if(ii==0x8d) { bb=0xe9; P0=bb; aa=0x11; delay1ms(200); CS=1; A10=1; A11=0; A12=0; A13=0; A14=0; WE=0; delay1ms(500); SendData(0xAA); I2C_start(); I2C_sendByte(0x80); //MAD ack(); I2C_sendByte(0x00); //SAD ack(); I2C_sendByte(0x2C); //响度 +20dB ack(); I2C_sendByte(0x3f); //前右 响度0dB ack(); I2C_sendByte(0x3f); //前左 响度0dB ack(); I2C_sendByte(0x3F); //后右 响度0dB ack(); I2C_sendByte(0x3F); //后左 响度0dB ack(); I2C_sendByte(0x10); //低音 响度+15dB ack(); I2C_sendByte(0x10); //高音 响度+15dB ack(); I2C_sendByte(0x7e); //声道选择 直接静音关闭,选通IBL和IBR ack(); I2C_stop(); delay1ms(5000); I2C_start(); I2C_sendByte(0x80); //MAD ack(); I2C_sendByte(0x00); //SAD ack(); I2C_sendByte(0x2C); //响度 +20dB ack(); I2C_sendByte(0x3f); //前右 响度0dB ack(); I2C_sendByte(0x3f); //前左 响度0dB ack(); I2C_sendByte(0x3F); //后右 响度0dB ack(); I2C_sendByte(0x3F); //后左 响度0dB ack(); I2C_sendByte(0x10); //低音 响度+15dB ack(); I2C_sendByte(0x10); //高音 响度+15dB ack(); I2C_sendByte(0xfe); //声道选择 直接静音 ack(); I2C_stop(); SendData(0x55); } } if(ii==0x8B) //8脚按钮动作处于开的状态 { delay1ms(50); if(ii==0x8B) { bb=0xd9; P0=bb; aa=0x11; delay1ms(200); CS=1; A10=1; A11=0; A12=0; A13=0; A14=0; WE=0; delay1ms(500); SendData(0xAA); I2C_start(); I2C_sendByte(0x80); //MAD ack(); I2C_sendByte(0x00); //SAD ack(); I2C_sendByte(0x2C); //响度 +20dB ack(); I2C_sendByte(0x3f); //前右 响度0dB ack(); I2C_sendByte(0x3f); //前左 响度0dB ack(); I2C_sendByte(0x3F); //后右 响度0dB ack(); I2C_sendByte(0x3F); //后左 响度0dB ack(); I2C_sendByte(0x10); //低音 响度+15dB ack(); I2C_sendByte(0x10); //高音 响度+15dB ack(); I2C_sendByte(0x7D); //声道选择 直接静音关闭,选通ICL和ICR ack(); I2C_stop(); delay1ms(5000); I2C_start(); I2C_sendByte(0x80); //MAD ack(); I2C_sendByte(0x00); //SAD ack(); I2C_sendByte(0x2C); //响度 +20dB ack(); I2C_sendByte(0x3f); //前右 响度0dB ack(); I2C_sendByte(0x3f); //前左 响度0dB ack(); I2C_sendByte(0x3F); //后右 响度0dB ack(); I2C_sendByte(0x3F); //后左 响度0dB ack(); I2C_sendByte(0x10); //低音 响度+15dB ack(); I2C_sendByte(0x10); //高音 响度+15dB ack(); I2C_sendByte(0xfD); //声道选择 直接静音,选通ICL和ICR ack(); I2C_stop(); SendData(0x55); } } if(ii==0x87) //8脚按钮动作处于开的状态 { delay1ms(50); if(ii==0x87) { bb=0xb9; P0=bb; aa=0x11; delay1ms(200); CS=1; A10=1; A11=0; A12=0; A13=0; A14=0; WE=0; delay1ms(500); SendData(0xAA); I2C_start(); I2C_sendByte(0x80); //MAD ack(); I2C_sendByte(0x00); //SAD ack(); I2C_sendByte(0x2C); //响度 +20dB ack(); I2C_sendByte(0x3f); //前右 响度0dB ack(); I2C_sendByte(0x3f); //前左 响度0dB ack(); I2C_sendByte(0x3F); //后右 响度0dB ack(); I2C_sendByte(0x3F); //后左 响度0dB ack(); I2C_sendByte(0x10); //低音 响度+15dB ack(); I2C_sendByte(0x10); //高音 响度+15dB ack(); I2C_sendByte(0x7D); //声道选择 直接静音关闭,选通ICL和ICR ack(); I2C_stop(); delay1ms(5000); I2C_start(); I2C_sendByte(0x80); //MAD ack(); I2C_sendByte(0x00); //SAD ack(); I2C_sendByte(0x2C); //响度 +20dB ack(); I2C_sendByte(0x3f); //前右 响度0dB ack(); I2C_sendByte(0x3f); //前左 响度0dB ack(); I2C_sendByte(0x3F); //后右 响度0dB ack(); I2C_sendByte(0x3F); //后左 响度0dB ack(); I2C_sendByte(0x10); //低音 响度+15dB ack(); I2C_sendByte(0x10); //高音 响度+15dB ack(); I2C_sendByte(0xfD); //声道选择 直接静音,选通ICL和ICR ack(); I2C_stop(); SendData(0x55); } } if(ii==0x0f) { delay1ms(50); if(ii==0x0f) { bb=0x79; P0=bb; aa=0x11; delay1ms(200); CS=1; A10=1; A11=0; A12=0; A13=0; A14=0; WE=0; delay1ms(500); } } SendData(bb); delay1ms(500); if(aa==0xff) { P0=0x89; CS=1; A10=1; A11=0; A12=0; A13=0; A14=0; WE=0; delay1ms(500); } SendData(aa); delay1ms(500); } }

其中I2C的应答代码
void ack()   //应答信号
{
        SDA=0;
        _nop_();
        SCL=1;
        _nop_();
        SCL=0;
        _nop_();
//    SDA = 1;
//    SCL = 1;
//    _nop_();
//    while(SDA==1);
//    SCL = 0;
}

 下面屏蔽的那几段代码会影响到I2C的接收,发送

怎么对TEA6320的理解呢,详看TEA6320的协议,MAD(从地址)是第一个字节,SAD(子地址)是第二个字节,第三个字节就是I2C真正要传输的数据,协议上说超过1个字节,数据将被发送,自动增加显著子地址,即TEA6320在写入数据超过1个字节的时候,子地址能自动递增,所以,子地址只需取列表第一个音量/响度的控制寄存器0x00,余下的子地址功能寄存器,系统会自动增加,而第三个字节就需要一一写上全部控制的数据。

这是本人自己查找资料结合自己的思考理解,有需要的同行看了,有发现什么不对的地方,请指出来,谢谢。

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:c语言实现通讯录管理系统(c课程设计)

下一篇:单片机,struct ,union定义标志,节约RAM