2419612_zh-CN

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

2419612_zh-CN

2419612_zh-CN

i.MX8ULP LPADC 比较功能

你好,


我正在尝试使用 M33 内核中的 i.MX8ULP ADC 的比较器模式,具体来说,我设置 ADC,以便如果转换值低于阈值,则发出中断来处理该事件。

根据参考手册,我的理解是这应该是可行的:

- 将 ADC 的 FIFO 水位设置为 1,这样任何数据都会触发信号中断(这部分是有效的,在下面的示例中,我删除了中断代码以简化代码)。

- 设置比较函数为“重复比较直到为真”,并适当调整 CVH/CVL 和触发器,然后持续对 ADC 进行采样,并在达到要求时触发数据。

很遗憾,我一直无法让比较值正常工作。手册上说,根据 CVL/CVH 的不同,可以进行各种操作,但我使用 ADC1 / 命令 1 / 触发信号 1 时,这些操作似乎都不起作用:

martinetd_0-1791506359158.png

通过实验,我发现:

- CVL < CVH(手册上说如果在范围之外则为真,例如val < CVL || val > CVH): 始终返回值(即使它在范围内)

- CVH 最大值,CVL 设置(应小于 CVL):由于未指定最大值,我不确定。将 CVH 设置为 0xfff 或 0x1000 时,无论 CVL 的值如何,都会返回该值;将 CVH 设置为 0xffff 时,则永远不会返回该值。

- CVL 最小值,CVH 设置值(应大于 CVH):始终返回该值

- CVL > CVH(应在范围内,例如CVH < val < CVL): 值永远不会返回


以下是我使用的代码:

      lpadc_config_t adcConfig;
      LPADC_GetDefaultConfig(&adcConfig);
      adcConfig.FIFOWatermark           = 0;
      adcConfig.enableAnalogPreliminary = true;
      LPADC_Init(ADC1, &adcConfig);
  
      lpadc_conv_trigger_config_t triggerConfig;
      LPADC_GetDefaultConvTriggerConfig(&triggerConfig);
      triggerConfig.targetCommandId       = 1;
      triggerConfig.enableHardwareTrigger = true;
      LPADC_SetConvTriggerConfig(ADC1, 0, &triggerConfig);
  
      lpadc_conv_command_config_t commandConfig; 
      LPADC_GetDefaultConvCommandConfig(&commandConfig);
      commandConfig.channelNumber       = 5;
      commandConfig.sampleChannelMode   = kLPADC_SampleChannelSingleEndSideB;
      commandConfig.sampleScaleMode     = kLPADC_SampleFullScale;
      commandConfig.hardwareAverageMode = kLPADC_HardwareAverageCount2;
      commandConfig.hardwareCompareMode = kLPADC_HardwareCompareRepeatUntilTrue;
      commandConfig.hardwareCompareValueHigh = v_high; 
      commandConfig.hardwareCompareValueLow  = v_low;  
      LPADC_SetConvCommandConfig(ADC1, 1, &commandConfig);
  
      SDK_DelayAtLeastUs(1000, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
      LPADC_DoSoftwareTrigger(ADC1, 1 << 0);
      // this is LPADC_GetConvResultBlocking() with a timeout
      uint32_t tmp, cnt = 0;
      tmp = ((ADC_Type *)ADC1)->RESFIFO;
      while (ADC_RESFIFO_VALID_MASK != (tmp & ADC_RESFIFO_VALID_MASK) && cnt < 100000)
      {
          tmp = ((ADC_Type *)ADC1)->RESFIFO;
          cnt++;
      }
      if (ADC_RESFIFO_VALID_MASK != (tmp & ADC_RESFIFO_VALID_MASK))
      {
          PRINTF("ADC timeout\r\n");
      }
      else
      {
          tmp &= ADC_RESFIFO_D_MASK;
          tmp >>= 3;
          PRINTF("got %d (%#x) in %d\r\n", tmp, tmp, cnt);
      }

我还导出了寄存器数据,我确信“比较重复直到为真”部分是有效的,因为 STAT 寄存器认为触发信号/命令仍在运行,而且我设置了“为真时存储”也得到了相同的结果(在命令运行时调整 CV(比较值)会产生奇怪的结果,但会正确返回等待条件为真的触发信号——我确定我们不应该在运行时更改 CV,所以我们忽略这部分)。

以下是等待转换期间的寄存器值,其中 CVL = 0xffe,CVH = 0x1(因此应该返回介于两者之间的任何值):

ADC1 0x280a2000
VERID: 0x200101a
PARAM: 0xf041004
CTRL: 0x1
^ ADCEN
STAT: 0x1000800
^ CMDACT 1, ADC_ACTIVE
IE: 0
DE: 0
CFG: 0x10800000
^ PWREN, PUDLY = 0x80
PAUSE: 0
TSTAT: 0
TCTRL[0]: 0x1000001
^ TCMD = CMD1, HTEN (no difference when disabled)
FCTRL: 0
CMD[0].CMDL: 0x2025
^ CSCALE full-scale, ABSEL = B, CH5
CMD[0].CMDH: 0x1003
^ AVGS = 2 conversions, CMPEN = repeat until true
CV[0]: 0x10ffe
^ compare value, CVH=1 and CVL=0xffe

我这样拿错了吗?


谢谢!

多米尼克

タグ(1)
評価なし
バージョン履歴
最終更新日:
土曜日
更新者: