扫码加入

  • 正文
  • 相关推荐
申请入驻 产业图谱

RT1170 ADC 多通道采样实操:A/B 通道切换与链式采样实现

5小时前
153
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

NXP RT1170 搭载双 LPADC 模块,支持 A/B 双路通道划分(ADC1 含 6A+6B 通道、ADC2 含 7A+7B 通道),默认 SDK 示例仅支持 A 通道单端采样,实际开发中若需使用 B 通道并实现多通道连续采样,需完成通道引脚配置、A/B 通道切换寄存器配置、链式采样命令设置三步核心操作。本文基于 RT1170-EVKB 开发板MCUXpresso IDE,以 ADC1 的 CH1B/CH2B/CH3B 三通道为例,详解 B 通道启用、多通道链式采样的代码修改与硬件测试流程,解决 B 通道采样失败、多通道轮询效率低等问题。

资料获取:[RT1170] ADC多通道采样实验

1. RT1170 ADC 核心特性与问题根源

1.1 双 ADC 模块与 A/B 通道架构

RT1170 的 LPADC 模块采用A/B 双通道分离设计,核心特性如下:

  • ADC1:共 12 通道,分为 6 个 A 通道(CH0A~CH5A)、6 个 B 通道(CH0B~CH5B),对应 GPIO_AD_06~GPIO_AD_15 引脚;
  • ADC2:共 14 通道,分为 7 个 A 通道(CH0A~CH6A)、7 个 B 通道(CH0B~CH6B),对应 GPIO_AD_16~GPIO_AD_25 引脚;
  • 单端 / 差分模式:支持单端采样(单独 A/B 通道)、差分采样(A+B 通道对),由专用寄存器控制;
  • 通道复用:双 ADC 模块共用 6 个通道资源,整机实际可用 20 个独立 ADC 通道。

1.2 B 通道采样失败的核心原因

SDK 默认示例(如lpadc_polling_cm7)仅能实现 A 通道采样,B 通道采样失败的根本原因是寄存器默认配置为 A 通道单端采样,关键控制位为 LPADC 转换命令中的 **sampleChannelMode与硬件寄存器的DIFF/ABSEL**:

寄存器位 配置值 采样模式 通道选择
DIFF(差分使能) 0 单端模式 由 ABSEL/sampleChannelMode决定
ABSEL(A/B 选择) 0 单端模式 选择 A 通道
ABSEL(A/B 选择) 1 单端模式 选择 B 通道
sampleChannelMode(SDK 枚举) kLPADC_SampleChannelSingleEndSideA 单端模式 底层配置 ABSEL=0,A 通道
sampleChannelMode(SDK 枚举) kLPADC_SampleChannelSingleEndSideB 单端模式 底层配置 ABSEL=1,B 通道
简单来说,SDK 默认将sampleChannelMode设为 A 通道,未修改该配置时,即使配置了 B 通道引脚,也无法实现有效采样。

1.3 多通道采样的两种实现方式

RT1170 支持两种多通道 ADC 采样方式,按需选择:
  • 轮询采样:单命令单通道,循环触发不同通道的采样命令,实现简单但效率较低;
  • 链式采样:多命令级联,配置通道采样命令的下一跳指令,由 ADC 模块自动完成多通道连续采样,无需 CPU 频繁干预,效率更高(本文重点实现)。

2. 实验环境准备

2.1 软硬件环境

  • 硬件:RT1170-EVKB 开发板、杜邦线、电位器(用于模拟模拟量输入)、3.3V 电源(可选);
  • 软件:MCUXpresso IDE V11.9.0、RT1170 SDK 2.15.000;
  • 基础工程:SDK 自带的lpadc_polling_cm7(ADC 轮询采样示例,基于 ADC1,默认 CH0A 采样);
  • 核心引脚:ADC1 的 CH1B/CH2B/CH3B 对应 RT1170-EVKB 引脚(均为 Freedom Header J26):
    • CH1B:GPIO_AD_09 → J26[10]
    • CH2B:GPIO_AD_11 → J26[4]
    • CH3B:GPIO_AD_13 → J26[8]

2.2 工程导入

  1. 打开 MCUXpresso IDE,点击「Import SDK Examples」;
  2. 选择硬件为MIMXRT1170-EVK,筛选lpadc分类,导入lpadc_polling_cm7工程;
  3. 编译工程并烧录,默认可实现 CH0A(GPIO_AD_06)的单端采样,串口可输出采样值,验证基础工程有效性。

3. 核心配置步骤:B 通道启用 + 三通道链式采样

整个改造分为引脚配置、ADC 基础配置修改、链式采样命令配置、采样结果读取四步,基于原有轮询工程,实现 CH1B/CH2B/CH3B 的自动连续采样。

步骤 1:B 通道引脚配置(ConfigTool)

使用 IDE 自带的 ConfigTool 配置 B 通道引脚为 ADC1 输入功能,替代默认的 CH0A 引脚:
  1. 打开工程中的「Pins」配置工具(左侧栏 ConfigTools → Pins);
  2. 筛选引脚GPIO_AD_09GPIO_AD_11GPIO_AD_13,将其功能均配置为ADC1输入;
  3. 配置引脚电气属性:慢摆率、高驱动能力、禁止上拉 / 下拉、禁止开漏(与默认 ADC 引脚配置一致,配置值 0x02U);
  4. 点击「Update Code」,工具自动更新BOARD_InitPins.c文件,完成引脚底层初始化。

步骤 2:ADC 基础配置修改(启用 FIFO,支持多结果存储)

链式采样的多通道结果需通过 FIFO 暂存,需修改 ADC 初始化配置,设置 FIFO 水位线,确保能存储 3 个通道的采样结果:
  1. 找到工程中 ADC 初始化代码,修改LPADC_GetDefaultConfig后的配置项:
    LPADC_Config_t mLpadcConfigStruct;
    LPADC_GetDefaultConfig(&mLpadcConfigStruct);
    // 关键修改:设置FIFO水位线为2,FIFO可存储3个采样结果(水位线=存储数-1)
    mLpadcConfigStruct.FIFOWatermark = 2;
    // 启用模拟预采样,提升采样精度
    mLpadcConfigStruct.enableAnalogPreliminary = true;
    // 初始化ADC1
    LPADC_Init(DEMO_LPADC_BASE, &mLpadcConfigStruct);
    
  2. 宏定义保持 ADC1 为基础模块,无需修改:#define DEMO_LPADC_BASE LPADC1

步骤 3:链式采样命令配置(核心:A/B 通道切换 + 命令级联)

RT1170 的 LPADC 支持最多 16 个采样命令(CMD0~CMD15),通过配置chainedNextCommandNumber实现命令级联,同时将sampleChannelMode设为 B 通道,实现 CH1B→CH2B→CH3B 的自动采样:

核心配置逻辑

  • 命令 1(CMD1):采样 CH1B,下一跳命令为 2(CMD2);
  • 命令 2(CMD2):采样 CH2B,下一跳命令为 3(CMD3);
  • 命令 3(CMD3):采样 CH3B,下一跳命令为 0(无后续命令,链式结束);
  • 所有命令的sampleChannelMode均设为kLPADC_SampleChannelSingleEndSideB,启用 B 通道。

完整代码实现

LPADC_ConvCommandConfig_t mLpadcCommandConfigStruct;
// 配置CMD1:CH1B,下一跳CMD2
LPADC_GetDefaultConvCommandConfig(&mLpadcCommandConfigStruct);
mLpadcCommandConfigStruct.chainedNextCommandNumber = 2; // 下一跳命令2
mLpadcCommandConfigStruct.sampleChannelMode = kLPADC_SampleChannelSingleEndSideB; // B通道
mLpadcCommandConfigStruct.channelNumber = 1; // CH1B
LPADC_SetConvCommandConfig(DEMO_LPADC_BASE, 1, &mLpadcCommandConfigStruct);

// 配置CMD2:CH2B,下一跳CMD3
LPADC_GetDefaultConvCommandConfig(&mLpadcCommandConfigStruct);
mLpadcCommandConfigStruct.chainedNextCommandNumber = 3; // 下一跳命令3
mLpadcCommandConfigStruct.sampleChannelMode = kLPADC_SampleChannelSingleEndSideB; // B通道
mLpadcCommandConfigStruct.channelNumber = 2; // CH2B
LPADC_SetConvCommandConfig(DEMO_LPADC_BASE, 2, &mLpadcCommandConfigStruct);

// 配置CMD3:CH3B,下一跳0(链式结束)
LPADC_GetDefaultConvCommandConfig(&mLpadcCommandConfigStruct);
mLpadcCommandConfigStruct.chainedNextCommandNumber = 0; // 无后续命令
mLpadcCommandConfigStruct.sampleChannelMode = kLPADC_SampleChannelSingleEndSideB; // B通道
mLpadcCommandConfigStruct.channelNumber = 3; // CH3B
LPADC_SetConvCommandConfig(DEMO_LPADC_BASE, 3, &mLpadcCommandConfigStruct);

步骤 4:采样结果读取(循环读取 FIFO,区分通道)

链式采样触发后,ADC 模块自动完成 3 个通道的采样,结果依次存入 FIFO,通过LPADC_GetConvResult循环读取 FIFO 数据,并根据commandIdSource区分采样通道(对应 CMD1/CMD2/CMD3):
LPADC_ConvResultConfig_t mLpadcResultConfigStruct;
while (1)
{
    // 按任意键触发链式采样(SDK默认串口触发,可改为自动触发)
    GETCHAR();
    // 触发CMD1,启动链式采样(1U为trigger0掩码)
    LPADC_DoSoftwareTrigger(DEMO_LPADC_BASE, 1U);

    // 读取CMD1(CH1B)结果
    while (!LPADC_GetConvResult(DEMO_LPADC_BASE, &mLpadcResultConfigStruct)){}
    PRINTF("ADC CMD1(CH1B) value: %drn", (mLpadcResultConfigStruct.convValue) >> g_LpadcResultShift);

    // 读取CMD2(CH2B)结果
    while (!LPADC_GetConvResult(DEMO_LPADC_BASE, &mLpadcResultConfigStruct)){}
    PRINTF("ADC CMD2(CH2B) value: %drn", (mLpadcResultConfigStruct.convValue) >> g_LpadcResultShift);

    // 读取CMD3(CH3B)结果
    while (!LPADC_GetConvResult(DEMO_LPADC_BASE, &mLpadcResultConfigStruct)){}
    PRINTF("ADC CMD3(CH3B) value: %drn", (mLpadcResultConfigStruct.convValue) >> g_LpadcResultShift);
    PRINTF("-------------------------rn");
}
  • 注:g_LpadcResultShift为采样结果移位值,SDK 默认定义,用于将原始采样值转换为实际有效数值(RT1170 ADC 为 12 位,取值 0~4095)。

4. 硬件测试与结果验证

4.1 硬件接线

用电位器模拟模拟量输入,验证 B 通道采样有效性:
  1. 将电位器的两个固定端分别连接开发板的GND3.3V
  2. 电位器的滑动端通过杜邦线连接到 CH1B(J26 [10]),CH2B/CH3B 可接固定电平(GND/3.3V)作为对比;
  3. 连接开发板的 UART 串口(GPIO_AD_24/TXD、GPIO_AD_25/RXD)到 PC,配置串口工具(波特率 115200、8N1)。

4.2 烧录与测试

  1. 编译修改后的工程,烧录到 RT1170-EVKB 开发板;
  2. 打开串口工具,复位开发板,串口输出提示信息:LPADC Polling Example ADC Full Range:4096
  3. 按串口工具的任意键,触发链式采样,串口输出采样结果:
    Please press any key to get user channel's ADC value.
    ADC CMD1(CH1B) value: 1256
    ADC CMD2(CH2B) value: 0
    ADC CMD3(CH3B) value: 4095
    -------------------------
    ADC CMD1(CH1B) value: 2048
    ADC CMD2(CH2B) value: 0
    ADC CMD3(CH3B) value: 4095
    -------------------------
    
  4. 旋转电位器,CH1B 的采样值会随电位器阻值变化在 0~4095 之间连续变化,说明 B 通道采样有效;CH2B 接 GND 值为 0,CH3B 接 3.3V 值为 4095,验证采样精度正常。

5. 扩展配置:支持更多 B 通道 / 混合 A/B 通道采样

5.1 增加 B 通道数量

若需采样更多 ADC1 B 通道(如 CH4B/CH5B),仅需新增采样命令配置,延续链式即可:
// 配置CMD4:CH4B,下一跳CMD5
mLpadcCommandConfigStruct.chainedNextCommandNumber = 5;
mLpadcCommandConfigStruct.sampleChannelMode = kLPADC_SampleChannelSingleEndSideB;
mLpadcCommandConfigStruct.channelNumber = 4;
LPADC_SetConvCommandConfig(DEMO_LPADC_BASE, 4, &mLpadcCommandConfigStruct);
// 同时调整FIFO水位线为通道数-1,确保能存储所有结果

5.2 混合 A/B 通道采样

若需同时采样 A 通道和 B 通道(如 CH1A+CH2B+CH3B),仅需将对应命令的sampleChannelMode分别设为 A/B 通道即可:
// CMD1:CH1A(A通道)
mLpadcCommandConfigStruct.sampleChannelMode = kLPADC_SampleChannelSingleEndSideA;
mLpadcCommandConfigStruct.channelNumber = 1;
// CMD2:CH2B(B通道)
mLpadcCommandConfigStruct.sampleChannelMode = kLPADC_SampleChannelSingleEndSideB;
mLpadcCommandConfigStruct.channelNumber = 2;

5.3 改为硬件触发 / 自动采样

若需去掉串口按键触发,实现硬件触发(如 GPIO、定时器)或自动循环采样,仅需修改触发逻辑:
// 自动循环采样,间隔100ms
while (1)
{
    LPADC_DoSoftwareTrigger(DEMO_LPADC_BASE, 1U);
    // 读取采样结果...
    HAL_Delay(100); // 延时100ms
}

6. 常见问题排查与避坑指南

6.1 B 通道采样值固定为 0/4095,无变化

  • 原因 1:引脚未正确配置为 ADC1 功能,仍为默认 GPIO 功能;
  • 原因 2sampleChannelMode未改为kLPADC_SampleChannelSingleEndSideB,仍为 A 通道;
  • 原因 3:引脚电气属性配置错误(如开启上拉 / 下拉,导致电平被固定);
  • 解决:重新通过 ConfigTool 配置引脚功能,核对sampleChannelMode配置,确保引脚电气属性为 0x02U。

6.2 链式采样仅能读取第一个通道结果

  • 原因 1:FIFO 水位线设置过小,未存储后续通道结果;
  • 原因 2chainedNextCommandNumber配置错误(如下一跳命令号为 0,导致链式提前结束);
  • 原因 3:未循环调用LPADC_GetConvResult,仅读取了一次 FIFO 数据;
  • 解决:将 FIFO 水位线设为通道数 - 1,核对命令级联配置,确保按通道数循环读取 FIFO。

6.3 采样结果乱序,通道与数值不匹配

  • 原因:链式命令的channelNumbercommandIdSource对应关系错误,或 FIFO 读取顺序与采样顺序不一致;
  • 解决:确保命令号与通道号一一对应(CMD1→CH1B、CMD2→CH2B),按命令级联顺序依次读取 FIFO,不打乱读取顺序。

6.4 编译报错:kLPADC_SampleChannelSingleEndSideB未定义

  • 原因:SDK 版本过低,未支持 B 通道枚举定义;
  • 解决:升级 RT1170 SDK 至 2.15.000 及以上版本,或直接通过寄存器配置 ABSEL=1(不推荐,不如 SDK 枚举直观)。
RT1170 实现 ADC B 通道多通道链式采样的核心是两个关键配置:一是将sampleChannelMode设为kLPADC_SampleChannelSingleEndSideB,启用 B 通道;二是配置采样命令的chainedNextCommandNumber,实现多通道自动级联。同时需配合引脚配置、FIFO 水位线设置,确保采样结果的正确存储与读取。

该方案基于 SDK 原有工程改造,无需编写底层寄存器操作代码,实现简单、兼容性强,既支持纯 B 通道采样,也支持 A/B 通道混合采样,可灵活扩展通道数量。相比传统轮询采样,链式采样由 ADC 模块自动完成多通道连续采样,大幅降低 CPU 干预频率,提升采样效率,适用于工业检测、数据采集等需要多通道连续 ADC 采样的场景。

相关推荐