现在先了解一下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,余下的子地址功能寄存器,系统会自动增加,而第三个字节就需要一一写上全部控制的数据。
这是本人自己查找资料结合自己的思考理解,有需要的同行看了,有发现什么不对的地方,请指出来,谢谢。
原文地址:https://www.cnblogs.com/weir1214/p/9692104.html
时间: 2024-10-31 09:31:54