S32K344 adc自检算法分析

最小的转换单位是group,不同的group可以包含相同的通道,不同的转换方式

Group转换支持排队,在没有优先级的作用下,先到先处理。

Adc_Ipw_StartNormalConversion转换的始终是队列中的0元素

同一个group可以包含标准转换和精准转换

S32K344支持看门狗,一旦转换的结果不在区域内会触发中断。

 

ADC自检功能,支持两种自检算法(可以用一种或者两种):

1,连续采集3次参考电压,分别是bandgap ,VrefH,VrefH,这三次采集是原子操作,不允许被其他高优先级ADC转换抢占。

2,每次ADC转换完后,采集校准电压并与之前校准后电压做差,大于某个范围说明,说明需要重新校验或者ADC模块损坏。

单次转换和连续转换时序图‘

 

 

 ADC的自检时机是ADC转换结束,这个是周期性,不太好用。如果转换不到指定的次数,自检算法不算完成。

Mcal库提供一个函数用于一次自检。他的工作原理是

选取一个精准通道0 ,设置为连续转换模式,通道不断转换,从而完成自检查算法。

因此这个函数是一个同步函数,无法立刻返回的。需要等待。

 

    /*  Each for loop checks the conversion of all steps in self-test S algorithm
    *   ForLoop(0): while (AlgS-start-1) ->S0 -> S1 -> S2 -> while (Alg-end-1) -> C0 to C11 ->
    *   ForLoop(1): while (AlgS-start-2) ->S0 -> S1 -> S2 -> while (Alg-end-2)
    */
    for (Index = 0U; Index < 2U; Index++)
    {
        /* Wait until Alg S has started*/
        ElapsedTicks = 0U;
        while ((((*MSRAddr) & ADC_MSR_SELF_TEST_S_MASK) != ADC_MSR_SELF_TEST_S_MASK) && (ElapsedTicks < TimeoutTicks))
        {
            ElapsedTicks += OsIf_GetElapsed(&CurrentTicks, ADC_SAR_IP_TIMEOUT_TYPE);
        }
        if (ElapsedTicks >= TimeoutTicks)
        {
            Status = ADC_SAR_IP_STATUS_TIMEOUT;
        }
        if (Status == ADC_SAR_IP_STATUS_SUCCESS)
        {
            /* Wait until Alg S has finished*/
            ElapsedTicks = 0U;
            while ((((*MSRAddr) & ADC_MSR_SELF_TEST_S_MASK) == ADC_MSR_SELF_TEST_S_MASK) && (ElapsedTicks < TimeoutTicks))
            {
                ElapsedTicks += OsIf_GetElapsed(&CurrentTicks, ADC_SAR_IP_TIMEOUT_TYPE);
            }
            if (ElapsedTicks >= TimeoutTicks)
            {
                Status = ADC_SAR_IP_STATUS_TIMEOUT;
            }
        }
        if (Status == ADC_SAR_IP_STATUS_TIMEOUT)
        {
            /* Break the loop if timeout occured in order to increase performance */
            break;
        }
    }

实现原理:ADC转换完成后会把SELF_TEST_S 标志位设置为1,等校验算法S结束后,将标志位设为0 。当进行校验算法C时,SELF_TEST_S标志位不会改变。因此会发生瞎胡说情况

ADC一直在转换,我们并不知道校验算法处于那一步

1,假如第一次进入for循环时,此时在进行C算法,因此SELF_TEST_S为0,此时直接过第一个WHILE循环,会卡在第二个while循环,直到SELF_TEST_S为1,这意味着C算法结束了,并且一个ADC转换完了,即将进行S算发自检;第二次进入for循环时:

  • 假如此时S算法没有完成,SELF_TEST_S为1,会卡在第一个while循环,直到S算法结束,SELF_TEST_S为0,此时会卡在第二个while循环,直到C算法结束并又发生一次ADC转换,退出while循环,退出for循环,这样久至少执行了一次s+c算法
  • 假如此时S算法完成,SELF_TEST_S为0,会卡在第2个while循环,直到C算法结束并又发生一次ADC转换,退出while循环,退出for循环,这样久至少执行了一次s+c算法

2,假如第一次进入for循环时,此时在进行S算法,因此SELF_TEST_S为1,此时会卡在第一个WHILE循环,直到SELF_TEST_S为0,这意味着S算法结束了,此时会卡在第二个while循环,

直到C算法执行完,再次准备执行S算法;此时第二次进入循环:

  • 假如此时S算法没有完成,SELF_TEST_S为1,会卡在第一个while循环,直到S算法结束,SELF_TEST_S为0,此时会卡在第二个while循环,直到C算法结束并又发生一次ADC转换,退出while循环,退出for循环,这样久至少执行了一次s+c算法
  • 假如此时S算法完成,SELF_TEST_S为0,会卡在第2个while循环,直到C算法结束并又发生一次ADC转换,退出while循环,退出for循环,这样久至少执行了一次s+c算法

第一次进入for循环,必须是即将进行S算法才能进入第二次for循环。

同样,第二次进入for循环,只有再次进行S算法,才可以退出for循环。

所以Mcal库提供的自检啊哈桑农户返回时间是不一样的。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
S32K344ADC模块中,BCTU(Basic Counter Timer Unit)可以用来触发ADC采集。以下是配置BCTU触发采集电压的步骤: 1. 配置ADC模块的通道和分辨率等参数。 2. 配置BCTU模块,使其能够产生定期的触发信号。可以选择不同的计数器和定时器,以及设置触发周期和触发模式等参数。 3. 配置ADC模块的BCTU触发模式,选择BCTU触发源和触发方式等参数。可以选择在上升沿、下降沿或者两者都触发ADC采样。 4. 配置ADC模块的结果转换器(Result Converter),将ADC采样结果转换为电压值。可以设置转换系数和参考电压等参数。 下面是一个简单的代码示例,演示如何配置BCTU触发采集电压: ```c adc16_config_t adcConfigStruct; adc16_channel_config_t adcChnConfigStruct; bctu_config_t bctuConfigStruct; // 配置ADC模块的参数 ADC16_GetDefaultConfig(&adcConfigStruct); adcConfigStruct.clockSource = kADC16_ClockSourceAlt0; adcConfigStruct.resolution = kADC16_Resolution16Bit; ADC16_Init(ADC0, &adcConfigStruct); ADC16_EnableHardwareTrigger(ADC0, false); // 禁用硬件触发 // 配置ADC通道的参数 adcChnConfigStruct.channelNumber = 0U; adcChnConfigStruct.enableInterruptOnConversionCompleted = false; ADC16_SetChannelConfig(ADC0, 0U, &adcChnConfigStruct); // 配置BCTU模块的参数 BCTU_GetDefaultConfig(&bctuConfigStruct); bctuConfigStruct.counter = kBCTU_Counter0; bctuConfigStruct.timer = kBCTU_Timer0; bctuConfigStruct.triggerMode = kBCTU_TriggerSingleShot; bctuConfigStruct.triggerPeriod = 1000U; // 触发周期为1ms BCTU_Init(BCTU0, &bctuConfigStruct); // 配置ADC模块的BCTU触发模式 adc16_hw_average_config_t hwAverageConfigStruct; hwAverageConfigStruct.hwAverageEnable = false; ADC16_SetHardwareAverageConfig(ADC0, &hwAverageConfigStruct); ADC16_SetHardwareTriggerSrc(ADC0, kADC16_HardwareTriggerBctu0, false); // 设置BCTU0为ADC触发源 ADC16_EnableHardwareTrigger(ADC0, true); // 启用硬件触发 // 循环读取ADC采样结果并转换为电压值 while (1) { ADC16_StartConversion(ADC0, false); while (0U == (kADC16_ChannelConversionDoneFlag & ADC16_GetChannelStatusFlags(ADC0, 0U))) { } uint16_t adcValue = ADC16_GetChannelConversionValue(ADC0, 0U); float voltage = (float)adcValue / 65535.0f * 3.3f; // 假设参考电压为3.3V } ``` 需要注意的是,以上代码只是一个简单的示例,实际应用中需要根据具体的要求进行调整和完善。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值