关于具有I2C总线的TEA6320的使用
程序员文章站
2023-10-26 17:24:28
现在先了解一下TEA6320,TEA6320是一个I2C总线控制音响应用的立体声放大器,,它的I2C协议和音量控制如下: 它的主要代码: 下面屏蔽的那几段代码会影响到I2C的接收,发送 怎么对TEA6320的理解呢,详看TEA6320的协议,MAD(从地址)是第一个字节,SAD(子地址)是第二个字节 ......
现在先了解一下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,余下的子地址功能寄存器,系统会自动增加,而第三个字节就需要一一写上全部控制的数据。
这是本人自己查找资料结合自己的思考理解,有需要的同行看了,有发现什么不对的地方,请指出来,谢谢。