软件模拟I2S引脚的定义如下:
#define I2S_WS GPIO_PIN_5//模拟I2S声道选择时钟控制位
#define I2S_BCK GPIO_PIN_6//模拟I2S位时钟控制位
#define I2S_DATA GPIO_PIN_7//模拟I2S数据传送位
根据MS6336的I2S总线格式以及数据发送流程,软件模拟I2S总线的步骤如下:
① 根据语音数据采样率及采样位数计算得到SCK的值和WS的值(WS的值等于采样频率)。
系统采样率为44.1 kHz,则SCK=2×44.1 kHz×103×16=1 411 200 Hz,WS=44 100 Hz。1个SCK时钟周期T=1/SCK=07 μs。采用延时程序模拟SCK时钟周期需要应用示波器来精确延时时间。本系统中一个SCK周期的延时为delayI2S(2)。
② 将WS、BCK和DATA均置为高电平。
③ 选择左右声道。首先发送左声道数据,将WS置低(若发送右声道数据则将WS置高)。
- for(ChannelCnt=0;ChannelCnt<2;ChannelCnt++){//双声道选择播放
- if(ChannelCnt==0){//右声道选择信号为高电平
- HWREG(GPIO_PORTA_BASE + (GPIO_O_DATA + (I2S_WS << 2))) = ~I2S_WS;
- }
- else{//左声道选择信号为低电平
- HWREG(GPIO_PORTA_BASE + (GPIO_O_DATA + (I2S_WS << 2))) = I2S_WS;
- }
- ……
- }
复制代码
④ 选择高低字节。将左声道数据以高低字节的顺序发送,在发送高字节第1位数据之前先发送1个周期的串行时钟。
- for(HorLCnt=0;HorLCnt<2;HorLCnt++){//声道数据高低字节选择
- if(ChannelCnt==1){//左声道
- if(HorLCnt==0){//低字节
- c=*(SampleData+1);//SampleData指向音频数据缓冲区首地址,即左声道低字节
- delayI2S(2);//发送第一个数据位之前需要延迟一个位时钟周期
- }
- else{//低字节
- c=*SampleData;
- }
- }
- ……
- }
复制代码
⑤ 开始传输音频数据(音频数据的传输在SCK下降沿准备数据,在SCK的上升沿发
送给数据接收端)。将采样点左声道数据的高字节最高位送给SD,设置SCK为低电平,此时为SCK的下降沿,数据准备好。延时半个SCK周期以后将SCK置为高电平,此时SD线上的数据发送给数据接收端,延时半个SCK周期。依次将左声道剩余位数据按照最高位的方式发送出去。
- for(BitCnt=0;BitCnt<8;BitCnt++){//1次传送的数据长度为8位,先传送高字节再传送低字节置时钟线SCK为低,开始准备数据位
- HWREG(GPIO_PORTA_BASE + (GPIO_O_DATA + (I2S_BCK << 2))) = ~I2S_BCK;
- if((c<
- HWREG(GPIO_PORTA_BASE + (GPIO_O_DATA + (I2S_DATA << 2))) = I2S_DATA;
- }
- else{
- HWREG(GPIO_PORTA_BASE + (GPIO_O_DATA + (I2S_DATA << 2))) = ~I2S_DATA;
- }
- delayI2S(1); //延时半个SCK时钟周期置时钟线为高,开始传输数据位
- HWREG(GPIO_PORTA_BASE + (GPIO_O_DATA + (I2S_BCK << 2))) = I2S_BCK;
- delayI2S(1);//延时半个时钟周期
- }
复制代码
⑥ 当将1个采样点的左声道的数据发送完以后,延时2个SCK周期,然后发送右声道的数据(同左声道数据的发送过程)。
根据以上的过程对每个采样点的数据进行处理,就可以实现通过软件模拟I2S总线传输音频数据了。以上实现的是典型I2S时序模拟,而左对齐和右对齐2种格式只是时序稍有差异,模拟实现过程同典型I2S总线模拟实现过程基本相同。
结语
在以太网数字语音广播系统中应用软件模拟实现I2S总线时序,能够成功地实现语音信号的数据传输,实现语音信号的实时广播,表明了软件模拟实现I2S总线的可行性,为解决不支持I2S总线的MCU和各种I2S总线设备间的
通信提供了一种可行的方法。但是,在应用软件模拟实现I2S的以太网数字语音广播系统实时播放语音信号时,存在一些噪声,表明在采用软件模拟实现I2S的时序精确性上存在一些欠缺。