数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 128|回复: 4

[C51] 三叶草ES9038Q2M解码板不出声,请高手看一下代码

[复制链接]
发表于 5 小时前 | 显示全部楼层 |阅读模式
本人有一张三叶草ES9038Q2M音频解码板,因板子单片机损坏,从新买了一片单片机(STC15W204S-35I-SOP16)。然后用AI软件写的代码,下载不论怎么修改程序都不能出声,输入通道LED指示是能够切换的。板子硬件部分本人用原装单片机验证过功能是正常的。那么问题还是在AI给我写的程序逻辑上有问题,请高手帮我看一下代码,怎样修改,本人是个对单片机程序小白

简易电路图


原实物电路板



代码
  1. #include <stc15.h>
  2. #include <intrins.h>

  3. typedef unsigned char u8;
  4. typedef unsigned int  u16;

  5. /* 硬件引脚定义 */
  6. sbit SDA      = P1^4;
  7. sbit SCL      = P1^5;
  8. sbit KEY_SW   = P1^3;
  9. sbit LED_USB  = P1^0;
  10. sbit LED_COAX = P1^1;
  11. sbit LED_OPT  = P1^2;

  12. /* I2C地址 根据ADDR引脚选择 */
  13. #define ES9038_WR_ADDR     0x90
  14. #define ES9038_RD_ADDR     0x91

  15. /* EEPROM配置 */
  16. #define EEPROM_CH_ADDR     0x00
  17. #define EEPROM_MAGIC_ADDR  0x01
  18. #define MAGIC_KEY          0xAA

  19. /* I2C时序延时,<a href="mailto:STC15W204S@22.1184M">STC15W204S@22.1184M</a>,满足I2C标准模式时序 */
  20. void I2C_Delay(void)
  21. {
  22.     u16 i;
  23.     for(i = 40; i > 0; i--);
  24. }

  25. void I2C_Start(void)
  26. {
  27.     SDA = 1; SCL = 1; I2C_Delay();
  28.     SDA = 0; I2C_Delay();
  29.     SCL = 0; I2C_Delay();
  30. }

  31. void I2C_Stop(void)
  32. {
  33.     SDA = 0; SCL = 1; I2C_Delay();
  34.     SDA = 1; I2C_Delay();
  35. }

  36. u8 I2C_WriteByte(u8 dat)
  37. {
  38.     u8 i;
  39.     u8 ack = 1;
  40.     for(i = 0; i < 8; i++)
  41.     {
  42.         SDA = dat & 0x80;
  43.         dat <<= 1;
  44.         I2C_Delay();
  45.         SCL = 1; I2C_Delay();
  46.         SCL = 0; I2C_Delay();
  47.     }
  48.     SDA = 1;
  49.     I2C_Delay();
  50.     SCL = 1; I2C_Delay();
  51.     ack = SDA;
  52.     SCL = 0;
  53.     return ack;
  54. }

  55. u8 I2C_ReadByte(u8 ack_en)
  56. {
  57.     u8 i;
  58.     u8 dat = 0;
  59.     for(i = 0; i < 8; i++)
  60.     {
  61.         dat <<= 1;
  62.         SCL = 1; I2C_Delay();
  63.         if(SDA) dat |= 0x01;
  64.         SCL = 0; I2C_Delay();
  65.     }
  66.     if(ack_en)
  67.         SDA = 0;
  68.     else
  69.         SDA = 1;
  70.     I2C_Delay();
  71.     SCL = 1; I2C_Delay();
  72.     SCL = 0;
  73.     return dat;
  74. }

  75. /* ES9038Q2M I2C单字节写寄存器 */
  76. u8 ES9038_WriteReg(u8 reg, u8 val)
  77. {
  78.     u8 ret;
  79.     I2C_Start();
  80.     ret = I2C_WriteByte(ES9038_WR_ADDR);
  81.     if(ret) { I2C_Stop(); return 1; }
  82.     ret = I2C_WriteByte(reg);
  83.     if(ret) { I2C_Stop(); return 1; }
  84.     ret = I2C_WriteByte(val);
  85.     I2C_Stop();
  86.     return ret;
  87. }

  88. /* ES9038Q2M I2C单字节读寄存器,datasheet说明:不支持多字节读 */
  89. u8 ES9038_ReadReg(u8 reg)
  90. {
  91.     u8 dat;
  92.     I2C_Start();
  93.     I2C_WriteByte(ES9038_WR_ADDR);
  94.     I2C_WriteByte(reg);
  95.     I2C_Start();
  96.     I2C_WriteByte(ES9038_RD_ADDR);
  97.     dat = I2C_ReadByte(0);
  98.     I2C_Stop();
  99.     return dat;
  100. }

  101. void DelayMs(u16 t)
  102. {
  103.     u16 i,j;
  104.     for(i = t; i > 0; i--)
  105.         for(j = 110; j > 0; j--);
  106. }

  107. void RefreshLed(u8 ch)
  108. {
  109.     LED_USB  = 1;
  110.     LED_COAX = 1;
  111.     LED_OPT  = 1;
  112.     switch(ch)
  113.     {
  114.         case 0: LED_USB  = 0; break; /* 0: I2S‑USB */
  115.         case 1: LED_COAX = 0; break; /* 1: 同轴SPDIF GPIO1(PIN17) */
  116.         case 2: LED_OPT  = 0; break; /* 2: 光纤SPDIF GPIO2(PIN16) */
  117.     }
  118. }

  119. /**
  120. * ch=0: I2S‑USB输入
  121. * ch=1: 同轴SPDIF(GPIO1 PIN17)
  122. * ch=2: 光纤SPDIF(GPIO2 PIN16)
  123. * 参考datasheet:
  124. * REG0x01 input_select:00=I2S;01=SPDIF;auto_select=00 关闭自动选择
  125. * REG0x0B(11h) spdif_sel:3=GPIO1,4=GPIO2
  126. * REG0x0C(12h) dpll_bw_serial:SPDIF DPLL带宽,0x0F最大带宽利于44.1K锁定
  127. */
  128. void SetInputSource(u8 ch)
  129. {
  130.     switch(ch)
  131.     {
  132.         case 0:
  133.             ES9038_WriteReg(0x01, 0x00);  /* auto_sel=00, input_sel=00 I2S */
  134.             ES9038_WriteReg(0x0C, 0x05);   /* I2S DPLL带宽默认 */
  135.             break;
  136.         case 1:
  137.             ES9038_WriteReg(0x01, 0x41);  /* auto_sel=00,input_sel=01 SPDIF */
  138.             ES9038_WriteReg(0x0B, 0x03);   /* spdif_sel=3 → GPIO1(PIN17)同轴 */
  139.             ES9038_WriteReg(0x0C, 0x0F);   /* DPLL最大带宽,利于44.1K锁定 */
  140.             break;
  141.         case 2:
  142.             ES9038_WriteReg(0x01, 0x41);  /* auto_sel=00,input_sel=01 SPDIF */
  143.             ES9038_WriteReg(0x0B, 0x04);   /* spdif_sel=4 → GPIO2(PIN16)光纤 */
  144.             ES9038_WriteReg(0x0C, 0x0F);   /* DPLL最大带宽 */
  145.             break;
  146.     }
  147.     DelayMs(400); /* DPLL锁定等待时间 */
  148. }

  149. /**
  150. * ES9038‑Q2M初始化,严格参考datasheet上电流程
  151. * 硬件:XI=100MHz有源时钟输入,XO悬空
  152. * REG0x00: osc_drv=0xF(关闭内部振荡器), clk_gear=11(÷8), soft_reset=1执行软件复位
  153. * 复位后写0x00=0xF8退出复位
  154. * REG0x14(0x0E) bit7 soft_start=1,DAC才能输出模拟电压!!该位非常关键
  155. */
  156. void ES9038_Init(void)
  157. {
  158.     DelayMs(800);  /* 等待电源、100M有源时钟稳定,datasheet上电时序要求 */

  159.     ES9038_WriteReg(0x00, 0xF9);  /* osc_drv=0xF关闭内部振荡;clk_gear=11(/8); soft_reset=1软件复位 */
  160.     DelayMs(200);
  161.     ES9038_WriteReg(0x00, 0xF8);  /* soft_reset=0,退出软件复位 */
  162.     DelayMs(300);

  163.     ES9038_WriteReg(0x02, 0x08);  /* 主音量 */
  164.     ES9038_WriteReg(0x07, 0x40);  /* bit7 soft_start=1 使能DAC模拟输出;mute=0解除静音 */
  165.     ES9038_WriteReg(0x06, 0x40);  /* de‑emph bypass,volume ramp默认 */
  166.     ES9038_WriteReg(0x0A, 0x00);  /* SPDIF配置默认 */
  167.     ES9038_WriteReg(0x0D, 0x02);  /* lock_speed默认 */
  168.     DelayMs(200);
  169. }

  170. /* STC IAP‑EEPROM读写 */
  171. u8 EEPROM_Read(u8 addr)
  172. {
  173.     u8 dat;
  174.     EA = 0;
  175.     IAP_CONTR = 0x80;
  176.     IAP_ADDRH = 0x00;
  177.     IAP_ADDRL = addr;
  178.     IAP_CMD   = 0x01;
  179.     IAP_TRIG  = 0x5A; IAP_TRIG = 0x59;
  180.     dat = IAP_DATA;
  181.     IAP_CMD = 0;
  182.     IAP_CONTR = 0x00;
  183.     EA = 1;
  184.     return dat;
  185. }

  186. void EEPROM_Save(u8 addr, u8 dat)
  187. {
  188.     EA = 0;
  189.     IAP_CONTR = 0x80;
  190.     IAP_ADDRH = 0x00;
  191.     IAP_ADDRL = addr;
  192.     IAP_CMD   = 0x02;
  193.     IAP_DATA  = dat;
  194.     IAP_TRIG  = 0x5A; IAP_TRIG = 0x59;
  195.     IAP_CMD = 0;
  196.     IAP_CONTR = 0x00;
  197.     EA = 1;
  198. }

  199. u8 cur_ch;

  200. void main(void)
  201. {
  202.     /* IO模式配置 */
  203.     P1M0 = 0x07;      /* P1.0‑1.2 LED推挽输出 */
  204.     P1M1 = 0x00;

  205.     P1M0 &= ~(1U << 3); /* P1.3按键准双向输入 */
  206.     P1M1 &= ~(1U << 3);

  207.     P1M0 &= ~0x30U;     /* P1.4 P1.5 I2C准双向 */
  208.     P1M1 &= ~0x30U;

  209.     DelayMs(800);

  210.     /* EEPROM魔术标记,首次上电默认光纤输入ch=2 */
  211.     if(EEPROM_Read(EEPROM_MAGIC_ADDR) != MAGIC_KEY)
  212.     {
  213.         cur_ch = 2;
  214.         EEPROM_Save(EEPROM_CH_ADDR, cur_ch);
  215.         EEPROM_Save(EEPROM_MAGIC_ADDR, MAGIC_KEY);
  216.     }
  217.     else
  218.     {
  219.         cur_ch = EEPROM_Read(EEPROM_CH_ADDR);
  220.         if(cur_ch > 2) cur_ch = 2;
  221.     }

  222.     ES9038_Init();
  223.     SetInputSource(cur_ch);
  224.     RefreshLed(cur_ch);

  225.     while(1)
  226.     {
  227.         if(KEY_SW == 0)
  228.         {
  229.             DelayMs(20);
  230.             if(KEY_SW == 0)
  231.             {
  232.                 ES9038_WriteReg(0x07, 0x41); /* bit0置1,软件静音 */
  233.                 cur_ch ++;
  234.                 if(cur_ch > 2) cur_ch = 0;

  235.                 SetInputSource(cur_ch);
  236.                 RefreshLed(cur_ch);
  237.                 EEPROM_Save(EEPROM_CH_ADDR, cur_ch);

  238.                 DelayMs(150);
  239.                 ES9038_WriteReg(0x07, 0x40); /* 解除静音,soft_start保持1 */

  240.                 while(!KEY_SW);
  241.                 DelayMs(20);
  242.             }
  243.         }
  244.         DelayMs(100);
  245.     }
  246. }

复制代码


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
发表于 3 小时前 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 2 小时前 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

 楼主| 发表于 1 小时前 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层
游客请登录后查看回复内容
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|数码之家-技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2026-9-10 18:46 , Processed in 0.109200 second(s), 8 queries , Gzip On, Redis On.

Powered by Discuz!

© MyDigit.Net Since 2006

快速回复 返回顶部 返回列表