This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TM4C1231H6PM:ADC 数字比较器输出

Guru**** 2526700 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1257053/tm4c1231h6pm-adc-digital-comparator-output

器件型号:TM4C1231H6PM

按计时器每1ms 触发一次 ADC 数字比较器

#define ADC_SEQUENCE_NUMBER 3

void adc_comparator_config(void) {
    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    SysCtlPeripheralReset(SYSCTL_PERIPH_ADC0);

    GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_0);
    GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, GPIO_PIN_2);
    GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_2, GPIO_PIN_2);

    //
    // Disable the sequence.
    //
    ADCSequenceDisable(ADC0_BASE, ADC_SEQUENCE_NUMBER);
    ADCSequenceDisable(ADC0_BASE, 0);
    ADCIntClear(ADC0_BASE, ADC_SEQUENCE_NUMBER); // Clear any interrupts

    //
    // Reconfigure and enable the sequence.
    //
    ADCSequenceConfigure(ADC0_BASE, ADC_SEQUENCE_NUMBER,
                         ADC_TRIGGER_TIMER, 3);
    ADCSequenceStepConfigure(ADC0_BASE, ADC_SEQUENCE_NUMBER, 0,
                             ADC_CTL_CH7 | ADC_CTL_END | ADC_CTL_IE | ADC_CTL_CMP7);
	ADCSequenceEnable(ADC0_BASE, ADC_SEQUENCE_NUMBER);

    // Reset the ADC comparator
    ADCComparatorReset(ADC0_BASE, ADC_CTL_CH7, true, true);
    ADCComparatorIntClear(ADC0_BASE, ADC_SEQUENCE_NUMBER);
    
    // Configure the ADC comparator
    ADCComparatorConfigure(ADC0_BASE, ADC_CTL_CMP7,
                           ADC_COMP_INT_HIGH_ALWAYS);
    ADCComparatorRegionSet(ADC0_BASE, ADC_CTL_CH7, 1024, 3600); // High threshold = 3600mV
    ADCComparatorIntEnable(ADC0_BASE, ADC_SEQUENCE_NUMBER);
    
    // Register the interrupt handler
    IntMasterEnable();
    ADCIntRegister(ADC0_BASE, ADC_SEQUENCE_NUMBER, adc_comparator_int_handler);
    ADCIntEnable(ADC0_BASE, ADC_SEQUENCE_NUMBER);
    IntEnable(INT_ADC0SS3);

}

// Once interrupt trigger, get the ADC value and print.
void adc_comparator_int_handler(void) {
    ADCComparatorIntClear(ADC0_BASE, ADC_SEQUENCE_NUMBER);
    uint32_t pui32ADC0Value[8] = {0};
    ADCSequenceDataGet(ADC0_BASE, ADC_SEQUENCE_NUMBER, pui32ADC0Value);
    printf("ADC value: %d", pui32ADC0Value[0]);
}

// Enable hw timer to trigger the ADC in every 1ms
void hw_timer_init()
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_WTIMER1);

    TimerDisable(WTIMER1_BASE, TIMER_A);

    TimerConfigure(WTIMER1_BASE, TIMER_CFG_A_PERIODIC);
    TimerLoadSet(WTIMER1_BASE, TIMER_A, SysCtlClockGet() / 1000 * 1);
    TimerControlTrigger(WTIMER1_BASE, TIMER_A, true);
    TimerEnable(WTIMER1_BASE,TIMER_A);

}
问题说明:ADC 数字比较器中断状态未被置位(ADCComparatorIntStatus (ADC0_BASE))。
问题1: 如何 获取/计算 ADC 数字比较器值(从哪个寄存器读取值)? (我希望确保 ADC 值高于3600mV)
问题2. ADC 数字比较器的配置是否正确?
问题3: 如何确保 ADC 值引起的中断触发高于阈值?
请帮助澄清问题。 感谢您的时间和帮助。
此致、
Suraj Pramanik
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Suraj、

     在您的代码中、我没有看到您 要为 AIN7使用 PD0、则启用 PortD。 您应具有以下代码行。  

    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOD);

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    代码的其他注释。  

    您编写了以下代码。 ADC_CTL_CMP7不需要随 ADC_CTL_CH7一同运行。 这里没有严格的一对一映射。 您可以将 ADC_CTL_CMP0用作 ADC_CTL_CH7或其他通道的比较器。 话虽如此、 此处可以使用 ADC_CTL_CMP7。 只是想澄清 ADC_CTL_CMP7和 ADC_CTL_CH7之间没有硬关联 。  

    ADCSequenceStepConfigure (ADC0_BASE、ADC_serial_number、0、
    ADC_CTL_CH7 | ADC_CTL_END | ADC_CTL_IE | ADC_CTL_CMP7);

    您编写了以下代码。 您应提供位映射中断状态以进行清除、而不是 始终为3的 ADC_SEQUERY_NUMBER。 请参阅外设 driverlib 用户指南。  


    ADCComparatorIntClear (ADC0_BASE、ADC_sequence_number);


    您在以下行中写下。 需要注意的是、这是比较器与的转换值、而不是电压进行比较。 当您输入3600时、这并不意味着3600mV、而是 ADC 转换值。 由于 ADC 是12位、假设 VDDA 为3.3V、3600表示3.3 *(3600 / 4096)= 2.9V。 这是您真正想要的吗? 这就是您的应用。 您需要确定要触发中断的上限。  

     
    ADCComparatorRegionSet (ADC0_BASE、ADC_CTL_CH710210243600);//高阈值= 3600mV

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Charles、  
    感谢您指出 ADCComparatorIntClear 函数的使用方法。 现在、我非常清楚如何计算较高的阈值。  

    我还有一个关于中断配置的问题。 当我转储  

    HWREG (ADC0_BASE + ADC_O_IM)寄存器中、我看到值为0x80008 (位3和位19已设置)。  

    可以设置两个不同的中断设置吗?  
    我可以从 ADC Int 设置获得中断、但是看不到来自数字比较器的任何中断。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    HWREG (ADC0_BASE + ADC_O_IM)寄存器、我看到值为0x80008 (位3和位19已设置)。  

    可以设置两个不同的中断设置吗?  
    我可以从 ADC Int 设置中获得中断、但无法从数字比较器中看到任何中断。

    您好!

     您能否删除  ADC_CTL_IE? 这会有什么区别吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    否。 如果我删除此函数、则中断回调函数(adc_comparator_int_handler)绝不会执行。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    是否可以设置两个不同的中断设置?  
    我可以通过 ADC Int 设置获得中断、但无法从数字比较器看到任何中断。
    HWREG (ADC0_BASE + ADC_O_IM)寄存器、我看到值为0x80008 (位3和位19已设置)。  [/报价]

    我认为在您的情况下、应该可以 在 ADCIM 寄存器中同时启用 DCONSS3和 MASK3位。 原因是您将输入值路由到数字比较器。 输入值不会保存在 FIFO 中。 在 ISR 中、不应期望读取 ADC 值、而应检查 DCONSS3是否设置。 如果该位置位、则表示检测到了上限阈值。  

    如果同时设置了位3和位19、则表示它检测到您的输入通道高于 COMP1阈值。  

     您可以显示 ADC_DCCTL7和 ADC_DCCMP7寄存器的设置吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!  

     我叫 Kevin、是 Suraj 的大学、出于测试目的、我使用了一个条件、 无论 ADC 值 是多少都应该生成中断

     ADC_DCCTL7 : 0x14 -> 在中值带条件满足时启用中断和触发

     ADC_DCCMP7 :0xFFF0000 -> COMP1= 4095且 COMP0 = 0

     我们可以在 SS3完成转换时获得中断、但数字比较器中断永远不会显示。

     我们还检查

     ADC_SSOP3 :0x1 ->将 ADC 输出连接到比较器

     ADC_SSDP3 :0x07 ->连接比较器7

     不知道您能为我们提供一个寄存器设置脚本还是示例代码、以便在中值带条件下启用数字比较器中断?

     我们 希望数字比较器中断首先发生、非常感谢!  

      

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

     请参阅以下两个勘误表并应用权变措施。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Charles:

     感谢您的快速响应、我认为这正是我们所需要的。