|
|
本人有一张三叶草ES9038Q2M音频解码板,因板子单片机损坏,从新买了一片单片机(STC15W204S-35I-SOP16)。然后用AI软件写的代码,下载不论怎么修改程序都不能出声,输入通道LED指示是能够切换的。板子硬件部分本人用原装单片机验证过功能是正常的。那么问题还是在AI给我写的程序逻辑上有问题,请高手帮我看一下代码,怎样修改,本人是个对单片机程序小白
简易电路图
原实物电路板
代码
- #include <stc15.h>
- #include <intrins.h>
- typedef unsigned char u8;
- typedef unsigned int u16;
- /* 硬件引脚定义 */
- sbit SDA = P1^4;
- sbit SCL = P1^5;
- sbit KEY_SW = P1^3;
- sbit LED_USB = P1^0;
- sbit LED_COAX = P1^1;
- sbit LED_OPT = P1^2;
- /* I2C地址 根据ADDR引脚选择 */
- #define ES9038_WR_ADDR 0x90
- #define ES9038_RD_ADDR 0x91
- /* EEPROM配置 */
- #define EEPROM_CH_ADDR 0x00
- #define EEPROM_MAGIC_ADDR 0x01
- #define MAGIC_KEY 0xAA
- /* I2C时序延时,<a href="mailto:STC15W204S@22.1184M">STC15W204S@22.1184M</a>,满足I2C标准模式时序 */
- void I2C_Delay(void)
- {
- u16 i;
- for(i = 40; i > 0; i--);
- }
- void I2C_Start(void)
- {
- SDA = 1; SCL = 1; I2C_Delay();
- SDA = 0; I2C_Delay();
- SCL = 0; I2C_Delay();
- }
- void I2C_Stop(void)
- {
- SDA = 0; SCL = 1; I2C_Delay();
- SDA = 1; I2C_Delay();
- }
- u8 I2C_WriteByte(u8 dat)
- {
- u8 i;
- u8 ack = 1;
- for(i = 0; i < 8; i++)
- {
- SDA = dat & 0x80;
- dat <<= 1;
- I2C_Delay();
- SCL = 1; I2C_Delay();
- SCL = 0; I2C_Delay();
- }
- SDA = 1;
- I2C_Delay();
- SCL = 1; I2C_Delay();
- ack = SDA;
- SCL = 0;
- return ack;
- }
- u8 I2C_ReadByte(u8 ack_en)
- {
- u8 i;
- u8 dat = 0;
- for(i = 0; i < 8; i++)
- {
- dat <<= 1;
- SCL = 1; I2C_Delay();
- if(SDA) dat |= 0x01;
- SCL = 0; I2C_Delay();
- }
- if(ack_en)
- SDA = 0;
- else
- SDA = 1;
- I2C_Delay();
- SCL = 1; I2C_Delay();
- SCL = 0;
- return dat;
- }
- /* ES9038Q2M I2C单字节写寄存器 */
- u8 ES9038_WriteReg(u8 reg, u8 val)
- {
- u8 ret;
- I2C_Start();
- ret = I2C_WriteByte(ES9038_WR_ADDR);
- if(ret) { I2C_Stop(); return 1; }
- ret = I2C_WriteByte(reg);
- if(ret) { I2C_Stop(); return 1; }
- ret = I2C_WriteByte(val);
- I2C_Stop();
- return ret;
- }
- /* ES9038Q2M I2C单字节读寄存器,datasheet说明:不支持多字节读 */
- u8 ES9038_ReadReg(u8 reg)
- {
- u8 dat;
- I2C_Start();
- I2C_WriteByte(ES9038_WR_ADDR);
- I2C_WriteByte(reg);
- I2C_Start();
- I2C_WriteByte(ES9038_RD_ADDR);
- dat = I2C_ReadByte(0);
- I2C_Stop();
- return dat;
- }
- void DelayMs(u16 t)
- {
- u16 i,j;
- for(i = t; i > 0; i--)
- for(j = 110; j > 0; j--);
- }
- void RefreshLed(u8 ch)
- {
- LED_USB = 1;
- LED_COAX = 1;
- LED_OPT = 1;
- switch(ch)
- {
- case 0: LED_USB = 0; break; /* 0: I2S‑USB */
- case 1: LED_COAX = 0; break; /* 1: 同轴SPDIF GPIO1(PIN17) */
- case 2: LED_OPT = 0; break; /* 2: 光纤SPDIF GPIO2(PIN16) */
- }
- }
- /**
- * ch=0: I2S‑USB输入
- * ch=1: 同轴SPDIF(GPIO1 PIN17)
- * ch=2: 光纤SPDIF(GPIO2 PIN16)
- * 参考datasheet:
- * REG0x01 input_select:00=I2S;01=SPDIF;auto_select=00 关闭自动选择
- * REG0x0B(11h) spdif_sel:3=GPIO1,4=GPIO2
- * REG0x0C(12h) dpll_bw_serial:SPDIF DPLL带宽,0x0F最大带宽利于44.1K锁定
- */
- void SetInputSource(u8 ch)
- {
- switch(ch)
- {
- case 0:
- ES9038_WriteReg(0x01, 0x00); /* auto_sel=00, input_sel=00 I2S */
- ES9038_WriteReg(0x0C, 0x05); /* I2S DPLL带宽默认 */
- break;
- case 1:
- ES9038_WriteReg(0x01, 0x41); /* auto_sel=00,input_sel=01 SPDIF */
- ES9038_WriteReg(0x0B, 0x03); /* spdif_sel=3 → GPIO1(PIN17)同轴 */
- ES9038_WriteReg(0x0C, 0x0F); /* DPLL最大带宽,利于44.1K锁定 */
- break;
- case 2:
- ES9038_WriteReg(0x01, 0x41); /* auto_sel=00,input_sel=01 SPDIF */
- ES9038_WriteReg(0x0B, 0x04); /* spdif_sel=4 → GPIO2(PIN16)光纤 */
- ES9038_WriteReg(0x0C, 0x0F); /* DPLL最大带宽 */
- break;
- }
- DelayMs(400); /* DPLL锁定等待时间 */
- }
- /**
- * ES9038‑Q2M初始化,严格参考datasheet上电流程
- * 硬件:XI=100MHz有源时钟输入,XO悬空
- * REG0x00: osc_drv=0xF(关闭内部振荡器), clk_gear=11(÷8), soft_reset=1执行软件复位
- * 复位后写0x00=0xF8退出复位
- * REG0x14(0x0E) bit7 soft_start=1,DAC才能输出模拟电压!!该位非常关键
- */
- void ES9038_Init(void)
- {
- DelayMs(800); /* 等待电源、100M有源时钟稳定,datasheet上电时序要求 */
- ES9038_WriteReg(0x00, 0xF9); /* osc_drv=0xF关闭内部振荡;clk_gear=11(/8); soft_reset=1软件复位 */
- DelayMs(200);
- ES9038_WriteReg(0x00, 0xF8); /* soft_reset=0,退出软件复位 */
- DelayMs(300);
- ES9038_WriteReg(0x02, 0x08); /* 主音量 */
- ES9038_WriteReg(0x07, 0x40); /* bit7 soft_start=1 使能DAC模拟输出;mute=0解除静音 */
- ES9038_WriteReg(0x06, 0x40); /* de‑emph bypass,volume ramp默认 */
- ES9038_WriteReg(0x0A, 0x00); /* SPDIF配置默认 */
- ES9038_WriteReg(0x0D, 0x02); /* lock_speed默认 */
- DelayMs(200);
- }
- /* STC IAP‑EEPROM读写 */
- u8 EEPROM_Read(u8 addr)
- {
- u8 dat;
- EA = 0;
- IAP_CONTR = 0x80;
- IAP_ADDRH = 0x00;
- IAP_ADDRL = addr;
- IAP_CMD = 0x01;
- IAP_TRIG = 0x5A; IAP_TRIG = 0x59;
- dat = IAP_DATA;
- IAP_CMD = 0;
- IAP_CONTR = 0x00;
- EA = 1;
- return dat;
- }
- void EEPROM_Save(u8 addr, u8 dat)
- {
- EA = 0;
- IAP_CONTR = 0x80;
- IAP_ADDRH = 0x00;
- IAP_ADDRL = addr;
- IAP_CMD = 0x02;
- IAP_DATA = dat;
- IAP_TRIG = 0x5A; IAP_TRIG = 0x59;
- IAP_CMD = 0;
- IAP_CONTR = 0x00;
- EA = 1;
- }
- u8 cur_ch;
- void main(void)
- {
- /* IO模式配置 */
- P1M0 = 0x07; /* P1.0‑1.2 LED推挽输出 */
- P1M1 = 0x00;
- P1M0 &= ~(1U << 3); /* P1.3按键准双向输入 */
- P1M1 &= ~(1U << 3);
- P1M0 &= ~0x30U; /* P1.4 P1.5 I2C准双向 */
- P1M1 &= ~0x30U;
- DelayMs(800);
- /* EEPROM魔术标记,首次上电默认光纤输入ch=2 */
- if(EEPROM_Read(EEPROM_MAGIC_ADDR) != MAGIC_KEY)
- {
- cur_ch = 2;
- EEPROM_Save(EEPROM_CH_ADDR, cur_ch);
- EEPROM_Save(EEPROM_MAGIC_ADDR, MAGIC_KEY);
- }
- else
- {
- cur_ch = EEPROM_Read(EEPROM_CH_ADDR);
- if(cur_ch > 2) cur_ch = 2;
- }
- ES9038_Init();
- SetInputSource(cur_ch);
- RefreshLed(cur_ch);
- while(1)
- {
- if(KEY_SW == 0)
- {
- DelayMs(20);
- if(KEY_SW == 0)
- {
- ES9038_WriteReg(0x07, 0x41); /* bit0置1,软件静音 */
- cur_ch ++;
- if(cur_ch > 2) cur_ch = 0;
- SetInputSource(cur_ch);
- RefreshLed(cur_ch);
- EEPROM_Save(EEPROM_CH_ADDR, cur_ch);
- DelayMs(150);
- ES9038_WriteReg(0x07, 0x40); /* 解除静音,soft_start保持1 */
- while(!KEY_SW);
- DelayMs(20);
- }
- }
- DelayMs(100);
- }
- }
复制代码
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|