哈哈,看见编辑推荐了,怎么说也得回应一下,现在放出MCU控制代码
- /*---------------------------------------------------------------------------------------------------------*/
- /* */
- /* Copyright(c) 2017 Nuvoton Technology Corp. All rights reserved. */
- /* */
- /*---------------------------------------------------------------------------------------------------------*/
- //***********************************************************************************************************
- // Nuvoton Technoledge Corp.
- // Website: http://www.nuvoton.com
- // E-Mail : MicroC-8bit@nuvoton.com
- // Date : Apr/29/2017
- //***********************************************************************************************************
- //***********************************************************************************************************
- // File Function: N76E003 I2C master mode demo code, the Slave address = 0xA4
- //
- // ____________ _____________
- // | | SDA | |
- // | |<-------->| |
- // | | | |
- // |N76E003(M) | | N76E003(S) |
- // |(I2C_Master)| | (I2C_Slave) |
- // | | SCL | |
- // | |--------->| |
- // |____________| |_____________|
- //
- // The protocol of I2C is same the "24LC64"
- //***********************************************************************************************************
- #include "N76E003.h"
- #include "Common.h"
- #include "Delay.h"
- #include "SFR_Macro.h"
- #include "Function_define.h"
- #define u8 unsigned char
- #define u16 unsigned int
- #define u32 unsigned long
- #define V_Up P17
- #define V_Down P00
- #define I2C_CLOCK 13
- #define TLV320_ADD 0x34
- #define Vol 120//0-127的一个数字,=0为静音
- #define VOL_ADJ_CON 40000
- u8 volume = Vol;
- u8 MUTE=1;
- //========================================================================================================
- void Init_I2C(void)
- {
- /* Set I2C clock rate */
- I2CLK = I2C_CLOCK;
- /* Enable I2C */
- set_I2CEN;
- }
- //========================================================================================================
- void I2C_Error(void)
- {
- // P3 = I2STAT;
- // P3 = ERROR_CODE;
- while (1);
- }
- //========================================================================================================
- void I2C_W_DATA(UINT8 REG_ADD , UINT8 u8DAT)
- {
- /* Step1 */
- set_STA; /* 发送Start位信号 */
- clr_SI;
- while (!SI); //检测总线,这里是主控单从芯片,单发送,其实可以不需要这个检测,
- if (I2STAT != 0x08) I2C_Error(); //不过原官方代码有这个,也不影响,就留着了。
-
-
- /* Step2 */
- clr_STA; //STA=0
- I2DAT = TLV320_ADD; //发送芯片IIC地址
- clr_SI;
- while (!SI); //检测ACK
- if (I2STAT != 0x18) I2C_Error();
-
- /* Step3 */
- REG_ADD<<=1; //TLV320AC23寄存器地址用的是D15-D9,因此,官方文档地址在这里必须左移一位。
- I2DAT = REG_ADD; //发送寄存器地址
- clr_SI;
- while (!SI); //检查ACK
- if (I2STAT != 0x28) I2C_Error();
-
- /* Step4 */
- I2DAT = u8DAT; //发送目的数据
- clr_SI;
- while (!SI); //检查ACK
- if (I2STAT != 0x28) I2C_Error();
- /* Step5 */
- set_STO;
- clr_SI;
- while (STO); /* 等待总线拉高*/
- }
- void MUTE_ISR (void) interrupt 0
- {
- u8 i;
- IE0=0;
- for(i=0;i<1000;i++){if(P30!=0)return;} //加个电容抗抖的话,这里软件抗抖可以不要
- MUTE++;
- MUTE&=0x01;
- I2C_W_DATA(0x02,(0X80+volume*MUTE)); //MUTE=0 or 1 volume*MUTE=volume or 0,等于0就直接实现静音.
- I2C_W_DATA(0x03,(0X80+volume*MUTE));
- }
- /*音量下降按钮中断,软件抗抖,抗抖完成后是一个瞬动(下降一个dB),
- 然后检测按钮是不是继续按着,如果是,进入循环连续调整(俗称连发)*/
- void Volume_Down_ISR (void) interrupt 7
- {
- u8 ADJ;
- u16 i;
- PIF=0;
- for(i=0;i<1000;i++){if(V_Down!=0)return;} //软件抗抖
- if(volume>0)volume--; //瞬动一次,立刻调整输出
- I2C_W_DATA(0x02,(0X80+volume));
- I2C_W_DATA(0x03,(0X80+volume));
- while(V_Down==0) //连发扳机检测,VOL_ADJ_CON是连发时间间隔计数。
- {
- ADJ=0;
- for(i=0;i<VOL_ADJ_CON;i++)
- {
- if(V_Down!=0){ADJ=1;return;}
- }
- if(ADJ==0)
- {
- if(volume>0)volume--;
- I2C_W_DATA(0x02,(0X80+volume)); //连发控制输出
- I2C_W_DATA(0x03,(0X80+volume));
- }
- }
- }
- void Volume_Up_ISR (void) interrupt 2
- {
-
- u8 ADJ;
- u16 i;
- IE1=0;
- for(i=0;i<500;i++){if(V_Up!=0)return;} //软件抗抖
- if(volume<127)volume++; //瞬动一次,立刻调整输出
- I2C_W_DATA(0x02,(0X80+volume));
- I2C_W_DATA(0x03,(0X80+volume));
- while(V_Up==0) //连发扳机检测,VOL_ADJ_CON是连发时间间隔计数。
- {
- ADJ=0;
- for(i=0;i<VOL_ADJ_CON;i++)
- {
- if(V_Up!=0){ADJ=1;return;}
- }
- if(ADJ==0)
- {
- if(volume<127)volume++;
- I2C_W_DATA(0x02,(0X80+volume)); //连发控制输出
- I2C_W_DATA(0x03,(0X80+volume));
- }
- }
- }
-
- //========================================================================================================
- void main(void)
- {
- Set_All_GPIO_Quasi_Mode; //全部用弱上拉模式,这样,可以节省3个按钮上拉电阻,IIC总线也可以用就简单点偷懒了。
- //P00_Quasi_Mode;
- //Enable_INT_Port0; //管脚切换到00组,这里是P00
- PINEN=0X01;
- PICON=0X04;
- //Enable_BIT0_FallEdge_Trig; //管脚中断边沿中断,下降沿
- while(P30==0);
- set_EPI;
- TCON=0X05;
- set_EX0;
- set_EX1;
- EA =1;
- Init_I2C();
- //I2C_Process(0x0F,0x00); //寄存器复位控制
- I2C_W_DATA(0x00,0x17); //线路L 音量、静音
- I2C_W_DATA(0x01,0x17); //线路R 音量、静音
- /*这里没做断电音量自动保存,要实现也很简单,每次音量改变中断完成后,用FLASH单元,代替EEPROM数据,用SPI自编程实现,
- 考虑到片内FLASH擦写寿命(10W)还可以用连续单元,顺序检测第一个FF单元,并进行编程,一个一个的写下去,直到一页全部写满,
- 到该页内没有FF单元,才进行一次页擦除,然后就又可以继续保存音量数据了。*/
- I2C_W_DATA(0x02,(0X80+volume)); //耳机L音量同时更新、零电压更新、音量控制
- I2C_W_DATA(0x03,(0X80+volume)); //耳机L音量同时更新、零电压更新、音量控制
- I2C_W_DATA(0x04,0x18); //音频路径控制
- I2C_W_DATA(0x05,0x00); //DAC 控制 软静音、过采样、高通
- I2C_W_DATA(0x06,0x07); //电源控制,ADC、line输入 MIC关闭,其余全部开启
- I2C_W_DATA(0x07,0x3E); //主从、数据格式控制 88.2
- I2C_W_DATA(0x08,0x20); //过采样控制 44.1
- I2C_W_DATA(0x09,0x01); //数字界面激活控制
-
- while (1)
- {
- UINT16 tmp;
-
- for (tmp=0;tmp<2000;tmp++){;}
- }
- /* =================== */
- }
|