分享

IIS是什么?+ mpy实例

 云深无际 2022-04-06

我今天收拾东西找到了几个IIS的传感器,看了下都是音频的器件。以前使用是ESP32 自带的IIS,因为时间的原因没有研究很多,这篇文章做下简单的总结。

I²S(Inter-IC Sound或Integrated Interchip Sound)是飞利浦公司制定的一种数字音频标准,于1986年发布,最近的一次修改是1996年。该总线适用于音频设备之间的数据传输,现已广泛应用于各种多媒体系统。它的时钟信号与音频数据流分离,与需要时钟恢复的系统相比,抖动比较低,为用户节省了购买抵抗音频抖动的专业设备的费用。

I²S总线规范

I²S至少有三条信号线:

SCK: (continuous serial clock) 串行时钟, 对应数字音频的每一位数据,SCK都有1个脉冲。SCK的频率=2×采样频率×采样位数。

WS: (word select) 字段(声道)选择,用于切换左右声道的数据。WS的频率等于采样频率。声道选择线表明了正在被传输的声道。

WS为“1”表示正在传输的是左声道的数据。

WS为“0”表示正在传输的是右声道的数据。

WS可以在串行时钟的上升沿或者下降沿发生改变,并且WS信号不需要一定是对称的。在从属设备端,WS在时钟信号的上升沿发生改变。

WS总是在最高位传输前的一个时钟周期发生改变,这样可以使从属设备得到与被传输的串行数据同步的时间,并且使接收端存储当前的命令以及为下次的命令清除空间。

SD: (serial data) 串行数据,用二进制补码表示的音频数据。I²S格式的信号无论有多少位有效数据,数据的最高位总是被最先传输(在WS变化(也就是一帧开始)后的第2个SCK脉冲处),因此最高位拥有固定的位置,而最低位的位置则是依赖于数据的有效位数。

这就使得接收端与发送端的有效位数可以不同。如果接收端能处理的有效位数少于发送端,可以放弃数据帧中多余的低位数据;如果接收端能处理的有效位数多于发送端,可以自行补足剩余的位(常补足为零)。

这种同步机制使得数字音频设备的互连更加方便,而且不会造成数据错位。为了保证数字音频信号的正确传输,发送端和接收端应该采用相同的数据格式和长度。当然,对I²S格式来说数据长度可以不同。

对于系统而言,产生SCK和WS的信号端就是主设备,用MASTER表示,简单系统示意图如下图所示:

系统示意图

此标准是Philips (后来为NXP,现在位Qualcomm)于1986年推出的,最后一个版本修订于1996年.现在是22年,大概就是26年了。

其实很简单,就是一个协议而已.现在好像是可以控制灯光了。

下面是参考文末的文章,使用ESP32 Cam实现:

from machine import I2Sfrom machine import Pinimport time # 初始化引脚定义sck_pin = Pin(14)  # 串行时钟输出ws_pin = Pin(13)   # 字时钟sd_pin = Pin(12)   # 串行数据输出 # 初始化i2saudio_out = I2S(1,sck=sck_pin,            ws=ws_pin,            sd=sd_pin,            mode=I2S.TX,            bits=16,            format=I2S.MONO,            rate=16000,            ibuf=20000)

使用microPython就是这样

sck 是串行时钟线的引脚对象ws 是单词选择行的引脚对象sd 是串行数据线的引脚对象mode 指定接收或发送bits 指定样本大小(位),16 或 32format 指定通道格式,STEREO(左右声道) 或 MONO(单声道)rate 指定音频采样率(样本/秒)ibuf 指定内部缓冲区长度(字节)

这些是参数的意思

from machine import I2Sfrom machine import Pinimport time
# 初始化引脚定义sck_pin = Pin(14) # 串行时钟输出ws_pin = Pin(13) # 字时钟sd_pin = Pin(12) # 串行数据输出
# 初始化i2saudio_out = I2S(1, sck=sck_pin, ws=ws_pin, sd=sd_pin, mode=I2S.TX, bits=16, format=I2S.MONO, rate=16000, ibuf=20000)wavtempfile = "temp.wav"wav = open(wavtempfile, 'rb')
# 前进到WAV文件中数据段的第一个字节pos = wav.seek(44)
# 分配样本数组# 用于减少while循环中堆分配的内存视图wav_samples = bytearray(1024)wav_samples_mv = memoryview(wav_samples)
print('播放音频')# 下面的0.016得来的方法:16000(采样率) x 8(采样位宽,我用的是8位音频,单位bit) x1(通道数,单声道1,立体声n) ÷ 8(1字节=8bit) ÷ 1000000(秒换算成微秒)# 上方的参数我都是使用的固定参数,我通过音频软件得出的,最好是从wav文件头中得出所有参数,就比较准确# 音频总时长 us(微秒)all_time = (len(wav)-44) / 0.016# 从WAV文件中连续读取音频样本# 并将其写入I2S DACwhile True: try: num_read = wav.readinto(wav_samples_mv) num_written = 0 # WAV文件结束 if num_read == 0: break # 前进到数据段的第一个字节 # pos = wav.seek(44) # 在首次执行的时候记录开始时间 if num_written == 0: # 记录播放开始时间 start_time = time.ticks_us() # 循环,直到所有样本都写入I2S外围设备 while num_written < num_read: num_written += audio_out.write( wav_samples_mv[num_written:num_read])
except Exception as e: print('错误,', e)        break

从SD卡中读取音频播放,之后注销:

# 等待音频播放完毕while 1:    # 播放结束时间    end_time = time.ticks_us()    # 如果当前时间减去开始播放的时间大于音频时长    if (end_time - start_time) > all_time:        # 取消初始化 I2S 总线        audio_out.deinit()        # 停止等待        break# 播放完毕# 关闭文件wav.close()

以上的的代码有毛病,ESP32 Cam的IO少,SD和IIS器件公用了引脚,所以效果不好。

import machine print('挂载sd卡...')try:    os.mount(machine.SDCard(), "/sd")    print('挂载成功,路径为:"/sd"')    # 卸载    # os.umount("/sd")except Exception as e:    print(e) # I2S from machine import I2Ssck_pin = Pin(14) ws_pin = Pin(13)  sd_pin = Pin(12)  audio_out = I2S(            1,            sck=sck_pin,             ws=ws_pin,             sd=sd_pin,            mode=I2S.TX,            bits=16,            format=I2S.MONO,            rate=16000,            ibuf=20000

那就可以设计成这样:

挂载SD卡->读取音频文件到内存->注销挂载SD卡->实例化I2S->播放音频->注销I2S->挂载SD卡

import ioimport urequests# 音频文件wavname = 'test.wav'# 请求音频文件wavbuf = urequests.get('http://www./music/%s' % wavname).content# 数据存到内存wav = io.BytesIO(wavbuf)# 以打开文件的方式读取内存数据buf = wav.read()

不过更好的方式,应该是使用网络实时的传输了。

https://blog.csdn.net/qq_33130395/article/details/120117741?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164923611516780366517961%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=164923611516780366517961&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-6-120117741.142^v5^pc_search_result_control_group,157^v4^control&utm_term=ESP32+IIS&spm=1018.2226.3001.418
https://www.stepfpga.com/doc/i2s

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多