目 录CONTENT

文章目录

NXP实战笔记(五):S32K3xx基于RTD-SDK在S32DS上配置ADC的硬件触发同步采样与软件采样过程

moke
2024-07-10 / 0 评论 / 0 点赞 / 112 阅读 / 0 字

1、概述

        恩智浦 S32K3xx 系列汽车微控制器器件具有 15 位分辨率逐次逼近模数转换器(SAR ADC),可用于模拟输入信号的采集和数字化。

        -15 位的分辨率。转换数据总是 15 位宽,与所选转换分辨率无关(每转换数据 14、12、10、8 个有效位,减少这个数字会加快数据转换,因为 SAR 算法的执行步骤会更少)。

        -每个输入通道捕获的转换数据放在单独寄存器中。

        -可使用“ 平均法” 提高精度,即通过计算最高 32 次转换数据的平均数来提供最终结果。

        -正常转换触发转换多个输入通道,每次触发转换一次或连续转换。

        -注入转换触发中断正在进行的正常转换,并转换另一组输入通道。

硬件转换触发

        -BCTU 转换触发中断正在进行的转换并转换输入通道,在该通道中选择输入并通过BCTU 启动转换。

        -其他硬件触发信号可由 TRGMUX 输出提供。

        -模拟看门狗监控每个输入通道的转换数据,如果转换数据低于或高于配置极限值,则进行中断。

        -DMA 功能将转换数据传输到其他模块。

        -当一个输入通道或一组输入通道的转换完成时,可编程中断可选择发出中断。

        -自检功能在功能运行期间验证 ADC 结构完整性,并在发现任何问题时生成具有不同严重等级的事件。

        -转换时钟(AD_clk)控制通过使用内部时钟分频器,让时钟频率更高的系统中可以使用ADC。

        -ADC 始终处于功能模式。不存在其他模式选择,当 ADC 空闲时自动关闭转换时钟。向 MCR[PWDN]写入 1,将 ADC 置于关断状态,以降低功耗。当 ADC 处于空闲状态时,向 MCR[ACKO]写入 1 对时钟信号进行门控。

        S32K3xx 系列芯片中的 SAR ADC 具有自校准机制,可调整内部采样电容库,从而为每个 IC 单元补偿器件出厂时的电容差异。用户必须在每次上电复位后启动 ADC 自校准,以获得数据表中规定的 ADC 精度。

1.1、软件触发

        软件触发是最简单的触发模式。 只需使用 CPU 和 DMA 启动正常或注入转换。每个 ADC 在一次 DMA 触发信号内支持单个 CPU 中断请求。 它可在每个通道转换后请求中断。当使用 DMA 时,转换结果由 DMA 处理并存储到 DMA 寄存器中,以便通过 DMA 或主机访问传输数据。 CPU 通过 ADC 主机接口直接连接到 DMA。

1.2、硬件触发 - BCTU

        该芯片可以从 BCTU 和 TRGMUX 输出端提供硬件触发信号。此功能允许同步转换两个独立的ADC 实例。

        BCTU 触发方案是 ADC 的默认和建议的硬件触发方法。所有 ADC 实例都是从 BCTU 触发的。BCTU 向 ADC 提供通道转换命令,包括通道信息。此外,ADC 将转换结果返回给 BCTU,包括所有通道信息。

        BCTU 向 ADC 的所有 72 个通道发出触发脉冲,以根据 BCTU 通道号启动转换。

        当使用 BCTU 触发时,BCTU-ADC 结果寄存器如下所示:

        BCTU 接口增强了 ADC 的注入转换能力。它包含控制输入,用于从适当的事件配置寄存器中选择要转换的通道。下图展示了 BCTU 接口。

        BCTU 生成要转换的触发(bctu_trigger)和通道号(bctu_numchannel)。每个请求都会转换一个通道。执行转换后,ADC 返回结果到(bctu_dataout)总线上,包括(bctu_nextcmd)和(bctu_push)两个输出信号。信号的确定(bctu_nextcmd)意味着 ADC 已准备好接受来自BCTU 的下一次触发。(bctu_push)信号在转换结束时被确定,表示转换完成,并且输出(bctu_dataout)的转换结果有效。

        转换结果也保存在相应通道的数据寄存器中,如请求,将与模拟看门狗阈值进行比较。信号(bctu_trigger、 bctu_nextcmd)和(bctu_push)均为 ADC 时钟域中的单周期有源高脉冲。当(bctu_trigger)处于高激活状态时,BCTU 提供的通道号必须有效。 ADC 的结果数据在(bctu_push)高电平下有效。

1.3、硬件触发 - TRGMUX

        该芯片的硬件触发信号可以从 TRGMUX 输出端提供。 TRGMUX 是一个非常灵活的模块,用于将外围设备的触发输入与各种内部和/或外部触发信号(计时器模块、模拟模块标志、外部引脚)进行连接。

        特别是对于 S32K3xx 系列的 ADC,TRGMUX 可以与任何可用触发信号进行同步转换。

        值得一提的是,TRGMUX 机制可用于触发 TRGMUX 输出编号 0,1,2[ADC_0]4,5,6[ADC_0]和8,9,10[ADC_2]的 ADC 转换,分别用于正常转换、注入转换和正常转换同步脉冲。 想要深入理解这部分内容,请参阅器件参考手册中的“ 表 266 硬件触发” 。

        如果 ADC 处于空闲状态(即没有正在进行的转换阶段,MCR[PWDN]和 MCR[ACKO]字段为0),并且设置了 MCR[XSTRTEN],则外部启动信号上的事件会导致 ADC 启动正常转换或注入转换。 MCR[NSTART]/MCR[JSTART]字段将分别自动设置。

        正常转换同步脉冲与正常转换触发一起使用,以同步多个 ADC 实例之间正常转换的开始计时。

1.4、ADC的校准

        参考电压已经在受控条件下采样和转换,用以确定校正值(偏移、增益和电容错配)

校准的步骤:

        -配置 CALBISTREG(采样时间、平均启用)

        -设置 TEST_EN,开始校准

        -轮询 BUSY 位,结束校准

        -检查状态位,确定校准成功或失败

        -参考电压已经在受控条件下采样和转换,用以确定校正值(偏移、增益和电容错配)

核校验代码如下:

/* Perform Calibration */
/* 1. Configure the ADC operating clock for 40MHz operation (program ADCLKSEL=0b */
/* for 80 MHz system clock) */
ADC_1->MCR |=ADC_MCR_ADCLKSEL(1); /* AD_clk frequency is half bus clock frequency */
/* 2. Bring ADC from power down state to active conversion (program PWDN =0b) */
ADC_1->MCR &= ~ADC_MCR_PWDN_MASK; /* Resetting this bit will start ADC transition to IDLE mode */
//while ((ADC_0->MSR & ADC_MSR_ADCSTATUS_MASK )!= 0){}
/* 3. Configure the Calibration BIST Control and status register (CALBISTREG) for */
/* TEST conditions. The default values are set for maximum accuracy (recommended). */
ADC_1->CALBISTREG = (ADC_CALBISTREG_RESN(0) |
ADC_CALBISTREG_TSAMP(3) | /* RESN=0: 14-bit resolution selected */
ADC_CALBISTREG_CALSTFUL_MASK | /* TSAMP=3: 32 cycle of ADC clk for Sample period in
Calibration process */
ADC_CALBISTREG_NR_SMPL(3)| /* Enable full range (conversions start from bit 15) */
ADC_CALBISTREG_AVG_EN_MASK | /* ADC Calibration Result Average feature enabled */
/* 4. Start calibration (program TEST_EN =1b), calibration start immediately. */
ADC_CALBISTREG_TEST_EN_MASK); /* Enable the Calibration (self clearing) */
/* 5. Poll the status of C_T_BUSY for 0. (wait until it becomes '0') */
while( (ADC_1->CALBISTREG & ADC_CALBISTREG_C_T_BUSY_MASK) !=0 ) { }
/* 6. Check the TEST_FAIL to know the final status. If '1' then calibration failed. */
if ((ADC_1->CALBISTREG & ADC_CALBISTREG_TEST_FAIL_MASK )!=0 )
{
SIUL2->GPDO50 |= SIUL2_GPDO50_PDO_n_MASK; /* Drive high on PTB 18 to turn-on LED D33 */
while( 1 ) {} /* Trap CPU due to ADC calibration failure */
}
/* 7. Check the status of CALIBRTD bit. If calibration is successful this bit will be '1'. */
if ((ADC_1->MSR & ADC_MSR_CALIBRTD_MASK ) == 0 )
{
SIUL2->GPDO50 |= SIUL2_GPDO50_PDO_n_MASK; /* Drive high on PTB 18 to turn-on LED D33 */
while( 1 ) {} /* Trap CPU due to ADC calibration failure */
}

1.5、ADC时钟配置

        ADC_0 MODULE_CLK 来自 M7_CORE_CLK(即 160MHz)。当使用 FIRC 作为源时,可以绕过预分频器。预分频器应受到控制,使模拟区块的时钟频率小于或等于 80 MHz。转换时钟的频率必须在“ 组件数据表” 中规定的限制范围内。ADC 模拟区块的最低运行速度为 6 MHz(使用 FIRC/2 作为系统时钟源,MC_CGM.MUX_0_DC_O[DIV]作为 1 'b1,使用 ADC 预分频器。然而,需要重点考虑的一点是ADC 结果会衰减。

        ADC的时钟配置路径如下

示例代码如下

/* ADC0 Clocking */
/* Configure Clock for Analog-to-digital converter 0 */
/* ADC_0 MODULE_CLK is from M7_CORE_CLK (i.e. 160MHz) */
MC_ME->PRTN0_COFB1_CLKEN |= MC_ME_PRTN0_COFB1_CLKEN_REQ58(1); /* REQ58:
Analog-to-digital converter 0 */
MC_ME.PRTN0_PCONF.B.PCE = 1; /* PCE=1: Enable the clock to
Partition #0 */
MC_ME->PRTN0_PUPD |= MC_ME_PRTN0_PUPD_PCUD_MASK; /* PCUD=1:
Trigger the hardware process */
MC_ME->CTL_KEY = 0x5AF0; /* Enter key */
MC_ME->CTL_KEY = 0xA50F; /* Enter inverted key */
while(!(MC_ME->PRTN0_COFB1_STAT & MC_ME_PRTN0_COFB1_STAT_BLOCK58_MASK)) { }
/* Wait until ADC_0 clock is running */
/* ADC0 Set-up */
ADC_0->MCR |= ADC_MCR_PWDN_MASK; /* Power down before initialization */
/* the analog module is requested
to enter Power Down mode */
power-down mode */
/* ADCLKSEL is modifiable only in
ADC_0->MCR |= ADC_MCR_OWREN_MASK; /* Enable overwriting older conversion

SAR-ADC整体软硬件触发格式如下

ADC不会工作在STANDBY模式下

2、BTCU硬件触发ADC的SDK配置

硬件配置,要用到同步设置,需要ADC0与ADC1各使用并排的通道,这样可以保证无延时同步。

AdcSarGeneral

AdcHwUnit

ADC的时钟是有限制的,假设太大,ADC的校验无法通过

通道array设置入下

BCTU设置如下

ADC target mask:选择几个ADC的实例,例如ADC0与ADC1就是0b11二进制表示。

        代码实现,根据设置使用了BCTU与ADC,此时需要先初始化ADC,假设先初始化了BCTU,已经开始触发ADC的采样了,导致ADC的校准出现问题,初始化不过了。

    /* Initialize Bctu */
    Bctu_Ip_Init(0U, &BctuHwUnit_0);
    Bctu_Ip_EnableNotifications(0U, BCTU_IP_NOTIF_LIST);
    Bctu_Ip_SetGlobalTriggerEn(0U, TRUE);
    /* Initialize ADC */
    StatusType status;
    do {
        status = (StatusType)Adc_Sar_Ip_Init(0U, &AdcHwUnit_0);
    } while (status != E_OK);

    do {
        status = (StatusType)Adc_Sar_Ip_Init(1U, &AdcHwUnit_1);
    } while (status != E_OK);

    do {
        status = (StatusType)Adc_Sar_Ip_DoCalibration(0U);
    } while (status != E_OK);

    do {
        status = (StatusType)Adc_Sar_Ip_DoCalibration(1U);
    } while (status != E_OK);

回调函数

void Bctu_FIFO1_WatermarkNotification(void)
{
    a = (uint16)(((IP_BCTU->FIFO1DR)&(0x07FFF))>>3U);
    b = (uint16)(((IP_BCTU->FIFO1DR)&(0x07FFF))>>3U);
}

右移三位的原因:右对齐,12bit精度

测试结果

3、软件触发ADC

3.1、选择相应Port作为ADC的输入

3.2、ADC配置

3.3、代码示例

第一种:

可以通过SDK提供的函数接口进行获取值

采样结果会按照Chain触发所配置的顺序进行

第二种直接读取寄存器,ADC

PCDR[3] 其中的P表示精准通道P3

ICDR[10]表示 S18,其中的I表示标准通道

ECDR[16] E表示外部通道,16为 80 - 64 = 16

80的来源如下图

64的来源如下

测试代码

A  = (uint16)(((IP_ADC_0->PCDR[3]) &0xFFFF)>>3);
B  = (uint16)(((IP_ADC_0->ICDR[10])&0xFFFF)>>3);
C  = (uint16)(((IP_ADC_0->ECDR[16])&0xFFFF)>>3);

右移动三位的原因查看寄存器可得

转换结果总是15bit的,之前的配置选择12bit的精度,需要滤掉低3bit,

博主关闭了所有页面的评论