最近在了解相关I2S模拟时序的资料,在网上流传的方案用一片AVR 模拟出I2S信号,让不具备I2S接口 的MCU处理音频数据与带I2S的DAC通信,完成音频解码输出。
有关于音频数据格式的计算参见另一篇blog,这里只分析I2S模拟时序作原理。
程序代码网上都有,介于各种权利在此只对其实现原理及硬件框架做分析。
声明:为尊重原作者的本意,下面按原作者的顺序进行阐述。
模拟I2S的主体思路有两种,但大致框架一致,如图:
思路1,用支持20MHz外部晶振且带CLKO的AVR,工作在音频DAC的工作频率(如16.9344MHz),
用3个定时器分别工作在CTC,CTC,Fast PWM模式下模拟出I2S总线的LRCLK(即fs)、
BCLK(SCLK)、SPI的片选CS,当然AVR的CLKO为MCLK且SPI的从机为另外发送SDATA的主机,如上图。
思路2,任意一款支持20MHz最大时钟的AVR,通过汇编对IO进行控制模拟出上面4个时钟信号。
介于我手上有mega328P我选择了第一种方案,原作者用的是mega48,AVR系列C代码也兼容,
用T/C0、T/C1、T/C2配置为相应的模式即可,需要注意的是熔丝配置的时候不要忘记使能CLKO以及
使用外部晶振。
C代码的实现也很简单,出于版权这里就不贴了,有兴趣可以百度,只大致分析一下原理:
1,初始化T/C0和T/C2为CTC,输出点空比50%的方波;计数TOP值根据AVR的定时器设置公式即可
计算出来;
2,初始化T/C1为比较输出的fast PWM模式,参考CS4334的DS介绍,支持24bit位宽 96KHz的数据
格式,并且要求T/C1模拟出的SPI片选CS时序满足一定要求;
a.观察CS4334波形,需要在BCLK/SCLK第一个周期后置低全能SPI通信;
b.且频率为LRCK的2倍,即在单个声道传输数据的时候就要完成一个周期的数据传输;
c.b中一个周期的数据在CS4334上可以是16BIT和24BIT,并且是DAC自适应,即不足24BIT时后8BIT
自动填充0;
所以,原作者让CS4334工作在16BIT有效数据的模式下,CS频率为2倍于BLK/SCL,且占空比为略小于
(24-16)BIT/24BIT,略小于的原因是CS4334的I2S时序要求,如上图:
如上图所示,C代码里在初始化代码的时候也很巧妙的利用nop()语句实现了时序的匹配,有关时钟计算
可以参考另外的我的blog。
这里只分析了产生I2S的时序部分,另外需要注意的是作为SPI从机的SDATA主机的时序配置,
原作者以CS4334为例,刚好我手上也有这片DAC,参数就不评价了,只从原理上进行学习分享!