连接测试
在I2C与控制器连接后,使用我的I2C教程中的扫描程序测试
测试后可以得到芯片的I2C地址为 0x4E
官方使用说明
双通道模拟输入设计
▽设计过程引用自TAA3020数据手册
- 为器件通电:
- 为 IOVDD 和 AVDD 电源上电
- 等待至少 1ms,让器件初始化内部寄存器
- 器件现在进入睡眠模式(低功耗模式 < 10µA)
- 每次录音操作需要时,从睡眠模式转换到工作模式:
- 通过写入 P0_R2 以禁用睡眠模式来唤醒器件
- 等待至少 1ms,让器件完成内部唤醒序列
- 根据需要覆盖默认配置寄存器或可编程系数值(这一步是可选操作)
- 通过写入 P0_R115 来启用所有需要的输入通道
- 通过写入 P0_R116 来启用所有需要的音频串行接口输出通道
- 通过写入 P0_R117 来为 ADC、MICBIAS 和 PLL 上电
- 施加具有所需输出采样速率和 BCLK 与 FSYNC 之比的 FSYNC 和 BCLK该特定步骤可以在步骤 a 后序列的任意时间点完成。有关支持的采样速率和 BCLK 与 FSYNC 之比,请参阅锁相环 (PLL) 和时钟生成 一节。
- 器件录音数据现在通过 TDM 音频串行数据总线发送到主机处理器
- 根据系统的低功耗运行要求,从工作模式(再次)转换到睡眠模式:
- 通过写入 P0_R2 以启用睡眠模式来进入睡眠模式
- 等待至少 6ms(FSYNC = 48kHz 时),让音量下降并让所有模块断电
- 读取 P0_R119 以检查器件关断和睡眠模式状态
- 如果器件 P0_R119_D7 状态位为 1'b1,则停止系统中的 FSYNC 和 BCLK
- 器件现在进入睡眠模式(低功耗模式 < 10µA)并保留所有寄存器值
- 根据录音操作需要,从睡眠模式(再次)转换到工作模式:
- 通过写入 P0_R2 以禁用睡眠模式来唤醒器件
- 等待至少 1ms,让器件完成内部唤醒序列
- 施加具有所需输出采样速率和 BCLK 与 FSYNC 之比的 FSYNC 和 BCLK
- 器件录音数据现在通过 TDM 音频串行数据总线发送到主机处理器
- 根据配置更改需要重复步骤 2 至步骤 4,或根据模式转换需要重复步骤 3 至步骤 4
板载麦克风配置
▽配置过程引用自TAA3020评估版使用手册
若要为这两个板载麦克风配置 ADC,请使用 PPC3 GUI 中的板载麦克风预设,或在 I2C 主应用程序中复制并粘贴以下脚本:
#####On-Board MIC Config######
w 9c 02 81 #Wake up device and enable AREG
w 9c 01 01 #Software Reset
d 100 #Wait 100ms
w 9c 00 00 #Set page 0
w 9c 02 81 #Wake up device and enable AREG
d 10 #wait 10 ms
w 9c 0d 01 #Set Ch-3 data to ASI left slot 1
w 9c 22 41 #Set IN2M_GPO1 to PDCMLK output (Default 3.072MHz)
w 9c 2b 50 #Set IN2P_GPI1 to PDMDIN2 for channel 3 and 4
w 9c 73 A0 #Enable input Ch-1 and Ch-3
w 9c 74 A0 # Enable ASI Output Ch-1 and Ch-3 slots
w 9c 75 E0 # Power-up ADC, MICBIAS and PLL
相关寄存器
▽简单初始化所需寄存器
软件复位寄存器
7.2.2 SW_RESET 寄存器(地址 = 0x1)[复位 = 0x00]
| 位 | 字段 | 类型 | 复位 | 说明 |
|---|---|---|---|---|
| 7-1 | RESERVED | R | 0b | 保留位;仅写入复位值 |
| 0 | SW_RESET | R/W | 0b | 软件复位。此位可自行清除。 0d = 不复位 1d = 将所有寄存器复位为其复位值 |
睡眠模式寄存器
7.2.3 SLEEP_CFG 寄存器(地址 = 0x2)[复位 = 0x00]
| 位 | 字段 | 类型 | 复位 | 说明 |
|---|---|---|---|---|
| 7 | AREG_SELECT | R/W | 0b | 从内部稳压器电源或外部 AREG 电源选择模拟电源。 0d = 外部 1.8V AREG 电源(当 AVDD 为 1.8V 且 AREG 与 AVDD 短接时使用该设置) 1d = 内部使用片上稳压器生成的 1.8V AREG 电源(当 AVDD 为 3.3V 时使用该设置) |
| 6-5 | RESERVED | R | 0b | 保留位;仅写入复位值 |
| 4-3 | VREF_QCHG[1:0] | R/W | 00b | VREF 外部电容器的快速充电持续时间使用 200Ω 的内部串联电阻来设置。 0d = VREF 快速充电持续时间为 3.5ms(典型值) 1d = VREF 快速充电持续时间为 10ms(典型值) 2d = VREF 快速充电持续时间为 50ms(典型值) 3d = VREF 快速充电持续时间为 100ms(典型值) |
| 2 | I2C_BRDCAST_EN | R/W | 0b | I2C 广播寻址设置。 0d = 禁用 I2C 广播模式 1d = 启用 I2C 广播模式;I2C 目标地址固定为 1001 100 |
| 1 | RESERVED | R | 0b | 保留位;仅写入复位值 |
| 0 | SLEEP_ENZ | R/W | 0b | 睡眠模式设置。 0d = 器件处于睡眠模式 1d = 器件未处于睡眠模式 |
输入通道使能配置寄存器
7.2.50 IN_CH_EN 寄存器(地址 = 0x73)[复位 = 0xC0]
| 位 | 字段 | 类型 | 复位 | 说明 |
|---|---|---|---|---|
| 7 | IN_CH1_EN | R/W | 1b | 输入通道 1 使能设置。 0d = 通道 1 禁用 1d = 通道 1 启用 |
| 6 | IN_CH2_EN | R/W | 1b | 输入通道 2 使能设置。 0d = 通道 2 禁用 1d = 通道 2 启用 |
| 5 | IN_CH3_EN | R/W | 0b | 输入通道 3(仅限 PDM)使能设置。 0d = 通道 3 禁用 1d = 通道 3 启用 |
| 4 | IN_CH4_EN | R/W | 0b | 输入通道 4(仅限 PDM)使能设置。 0d = 通道 4 禁用 1d = 通道 4 启用 |
| 3-0 | RESERVED | R | 0b | 保留位;仅写入复位值 |
ASI 输出通道使能配置寄存器
7.2.51 ASI_OUT_CH_EN 寄存器(地址 = 0x74)[复位 = 0x00]
| 位 | 字段 | 类型 | 复位 | 说明 |
|---|---|---|---|---|
| 7 | ASI_OUT_CH1_EN | R/W | 0b | ASI 输出通道 1 启用设置。 0d = 通道 1 输出时隙处于三态条件 1d = 通道 1 输出时隙已启用 |
| 6 | ASI_OUT_CH2_EN | R/W | 0b | ASI 输出通道 2 启用设置。 0d = 通道 2 输出时隙处于三态条件 1d = 通道 2 输出时隙已启用 |
| 5 | ASI_OUT_CH3_EN | R/W | 0b | ASI 输出通道 3 启用设置。 0d = 通道 3 输出时隙处于三态条件 1d = 通道 3 输出时隙已启用 |
| 4 | ASI_OUT_CH4_EN | R/W | 0b | ASI 输出通道 4 启用设置。 0d = 通道 4 输出时隙处于三态条件 1d = 通道 4 输出时隙已启用 |
| 3-0 | RESERVED | R | 0b | 保留位;仅写入复位值 |
上电配置寄存器
7.2.52 PWR_CFG 寄存器(地址 = 0x75)[复位 = 0x00]
| 位 | 字段 | 类型 | 复位 | 说明 |
|---|---|---|---|---|
| 7 | MICBIAS_PDZ | R/W | 0b | MICBIAS 的电源控制。 0d = MICBIAS 断电 1d = MICBIAS 上电 |
| 6 | ADC_PDZ | R/W | 0b | ADC 和 PDM 通道的电源控制。 0d = 所有 ADC 和 PDM 通道断电 1d = 所有已启用的 ADC 和 PDM 通道上电 |
| 5 | PLL_PDZ | R/W | 0b | PLL 的电源控制。 0d = PLL 断电 1d = PLL 上电 |
| 4 | DYN_CH_PUPD_EN | R/W | 0b | 动态通道上电/断电使能。 0d = 如果任何通道录音处于开启状态,则不支持通道上电/断电 1d = 即使通道录音处于开启状态,通道也可以单独上电或断电 |
| 3-2 | DYN_MAXCH_SEL[1:0] | R/W | 00b | 动态模式最大通道选择配置。 0d = 启用动态通道上电/断电功能时使用通道 1 和通道 2 1d = 启用动态通道上电/断电功能时使用通道 1 至通道 4 2d = 保留;不使用 3d = 保留;不使用 |
| 1 | RESERVED | R | 0b | 保留位;仅写入复位值 |
| 0 | VAD_EN | R/W | 0b | 启用语音活动检测 (VAD) 算法。 0d = 禁用 VAD 1d = 启用 VAD |
▽状态寄存器
器件状态值寄存器 0
7.2.53 DEV_STS0 寄存器(地址 = 0x76)[复位 = 0x00]
| 位 | 字段 | 类型 | 复位 | 说明 |
|---|---|---|---|---|
| 7 | CH1_STATUS | R | 0b | ADC 或 PDM 通道 1 电源状态。 0d = ADC 或 PDM 通道断电 1d = ADC 或 PDM 通道上电 |
| 6 | CH2_STATUS | R | 0b | ADC 或 PDM 通道 2 电源状态。 0d = ADC 或 PDM 通道断电 1d = ADC 或 PDM 通道上电 |
| 5-0 | RESERVED | R | 0b | 保留位;仅写入复位值 |
器件状态值寄存器 1
7.2.54 DEV_STS1 寄存器(地址 = 0x77)[复位 = 0x80]
| 位 | 字段 | 类型 | 复位 | 说明 |
|---|---|---|---|---|
| 7-5 | MODE_STS[2:0] | R | 100b | 器件模式状态。 4d = 器件处于睡眠模式或软件关断模式 6d = 器件处于工作模式且所有 ADC 或 PDM 通道都关闭 7d = 器件处于工作模式且至少一个 ADC 或 PDM 通道开启 |
| 4-0 | RESERVED | R | 0b | 保留位;仅写入复位值 |
芯片主模式初始化配置
#include <Arduino.h>
#include <Wire.h>
static constexpr uint8_t ADDRESS = 0x4E;
/**
* @brief 写数据到I2C设备
*
* @param reg 要写入的寄存器地址
* @param data 要写入的数据
* @return true
* @return false
*/
bool i2cWrite(uint8_t reg, uint8_t data) {
Wire.beginTransmission(ADDRESS);
Wire.write(reg);
Wire.write(data);
return Wire.endTransmission();
}
/**
* @brief 从I2C设备读取数据
*
* @param reg 要读取的寄存器地址
* @return uint8_t 读取到的数据
*/
uint8_t i2cRead(uint8_t reg) {
Wire.beginTransmission(ADDRESS);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom((uint8_t)ADDRESS, (uint8_t)0x01);
return Wire.read();
}
void setup() {
Serial0.begin(115200);
Wire.begin(8, 9, 100000); // I2C初始化
i2cWrite(0x02, 0x81); // 关闭睡眠
i2cWrite(0x01, 0x01); // 重启复位
delay(100);
i2cWrite(0x00, 0x00); // 配置寄存器页0
i2cWrite(0x02, 0x81); // 关闭睡眠
delay(10);
i2cWrite(0x73, 0xc0); // 开启通道1、2
i2cWrite(0x74, 0xc0); // 开启ASI输出通道1、2
i2cWrite(0x75, 0xe0); // 开启MICBIAS、ADC、PLL电源
Serial0.print("0x76: ");
Serial0.println(i2cRead(0x76), HEX); // 读取状态寄存器1
Serial0.print("0x77: ");
Serial0.println(i2cRead(0x77), HEX); // 读取状态寄存器2
}
void loop() {}
完成配置后发现串口打印 0x76: 0 ; 0x77: c0
理应不该如此,暂时没有找到问题,等待后续实验更新
I2S配置
注意查看数据手册中
6.3.2 锁相环 (PLL) 和时钟生成

根据表格内容,最低只支持FSYNC(WS)频率最低为8k或者7.35k,请勿使用更低频率,否则芯片无法输出数据
参考测试代码(尚无数据处理内容,仅提供时序参考与数据查看,等待后续更新)
使用个人编写的I2S库,Arduino提供的并不好用
#include <Arduino.h>
#include <Wire.h>
#include "cl_i2s_lib.h"
CL_I2S_LIB taa3020(0, taa3020.MASTER, taa3020.RX, taa3020.PCM); // 创建I2S对象
static constexpr uint8_t ADDRESS = 0x4E;
static constexpr uint32_t SAMPLE_RATE = 8000; // 采样率(WS频率)
static constexpr uint8_t BPS = 32; // 采样位数
static int32_t readData[1440];
bool i2cWrite(uint8_t reg, uint8_t data) {
Wire.beginTransmission(ADDRESS);
Wire.write(reg);
Wire.write(data);
return Wire.endTransmission();
}
uint8_t i2cRead(uint8_t reg) {
Wire.beginTransmission(ADDRESS);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom((uint8_t)ADDRESS, (uint8_t)0x01);
return Wire.read();
}
void setup() {
Serial0.begin(115200);
Serial0.println("Serial0 Init OK");
Wire.begin(8, 9, 100000);
i2cWrite(0x02, 0x81);
i2cWrite(0x01, 0x01);
delay(100);
i2cWrite(0x00, 0x00); // 配置寄存器页0
i2cWrite(0x02, 0x81);
delay(10);
i2cWrite(0x73, 0xc0);
i2cWrite(0x74, 0xc0);
i2cWrite(0x75, 0xe0);
taa3020.begin(SAMPLE_RATE, BPS); // 初始化I2S
taa3020.setFormat(taa3020.RIGHT_LEFT, taa3020.I2S); // 设置I2S格式
taa3020.setDMABuffer(4, 480); // 设置DMA缓冲区大小
taa3020.install(17, 18, 19); // 安装I2S引脚,启动I2S
Serial0.println("I2S Init OK");
memset(readData, 0, sizeof(readData));
delay(1000);
taa3020.Read(readData, 1440); // 读取I2S接收到的数据存入数组
for (size_t i = 0; i < 1440; i++) {
Serial0.println(readData[i]); // 串口打印数组中的数据
}
}
void loop() {}

Comments NOTHING