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.

[参考译文] TM4C123GH6PM:即使占空比为0%、序列发生器 PWM 触发器仍会发生

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1176839/tm4c123gh6pm-sequencer-pwm-trigger-still-happens-even-with-0-duty-cycle

器件型号:TM4C123GH6PM

在移植框架以与 Tiva C 配合使用后、我将重复使用来自 NXP 微控制器的单位测试

我的问题是、在我将 PWM 设置为触发器后、我似乎无法通过占空比控制触发器。 我只能通过改变 PWM 频率来减少触发器的数量。

触发器是与 PWM 信号的时钟相关联还是配置问题?

我有一个在每次触发时调用的 fucnion:

void UT_ANALOG_SEQUENCE_Hook(ANALOG_SEQUENCE_t* sequence, ANALOG_t* analog, void* data)
{
//	gUT_ANALOG_SEQUENCE_acc += ANALOG_Read( analog );
	int32_t temp;
	ADCSequenceDataGet(ANALOG_SEQUENCE_GetAdcBase(sequence), ANALOG_SEQUENCE_GetSequencerNumber(sequence), &temp);
	gUT_ANALOG_SEQUENCE_acc += temp;
	gUT_ANALOG_SEQUENCE_counter++;
}

我的代码会根据已使用的序列发生器以及我们希望序列发生器运行的最大通道数自动定义序列发生器。 由于该单位测试仅需要1个通道、因此它将序列发生器3定义为所选的通道。

按照以下步骤启用序列发生器:

ADCSequenceDisable();
ADCSequenceConfigure(); // here I just use the sequencer number as a priority
                        // because we don't actually need proper priorities set up
ADCSequenceStepConfigure(); // as many as we need for the channels we want
                            // being the last added channel the one that will
                            // carry ADC_CTL_IE | ADC_CTL_END | channel
ADCIntRegister(); // this one registers the proper irq handler based
                  // on adc [0..1] and sequencer [0..3]
PWMGenIntTrigEnable() // here I set up the trigger for pwm based on
                      // a previous pwm created, using PWM_TR_CNT_ZERO
                      // (I'm a begginer in embedded engineering, I don't
                      // know how to use all the other flags that are
                      // possible here, nor what do they mean...
                      // I'd love a quick reference to something
                      // as I can't find a detailed description on these hahaha)
ADCIntEnable();
IntEnable();
ADCSequenceEnable();

是否缺少我跳过的步骤? 还是仅根据 PWM 的时钟触发?

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

    尊敬的 Vinicius:

    如果看不到您用于序列配置的参数、我无法在这里提供任何支持。 请使用所有参数发布完整配置。

    关于   PWMGenIntTrigEnable API 的标志、pwm.h 文件具有以下信息:

    #define PWM_INT_CNT_ZERO        0x00000001  // Int if COUNT = 0
    #define PWM_INT_CNT_LOAD        0x00000002  // Int if COUNT = LOAD
    #define PWM_INT_CNT_AU          0x00000004  // Int if COUNT = CMPA U
    #define PWM_INT_CNT_AD          0x00000008  // Int if COUNT = CMPA D
    #define PWM_INT_CNT_BU          0x00000010  // Int if COUNT = CMPA U
    #define PWM_INT_CNT_BD          0x00000020  // Int if COUNT = CMPA D
    #define PWM_TR_CNT_ZERO         0x00000100  // Trig if COUNT = 0
    #define PWM_TR_CNT_LOAD         0x00000200  // Trig if COUNT = LOAD
    #define PWM_TR_CNT_AU           0x00000400  // Trig if COUNT = CMPA U
    #define PWM_TR_CNT_AD           0x00000800  // Trig if COUNT = CMPA D
    #define PWM_TR_CNT_BU           0x00001000  // Trig if COUNT = CMPA U
    #define PWM_TR_CNT_BD           0x00002000  // Trig if COUNT = CMPA D

    此致、

    Ralph Jacobi

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

    很抱歉、回答延迟、我周末无法访问代码。

    该序列配置如下:

    ADCSequenceDisable( ADC0_BASE, 3 );
    ADCSequenceConfigure( ADC0_BASE, 3,  ADC_TRIGGER_PWM0 | ADC_TRIGGER_PWM_MOD0, 3 ); // here I just use the sequencer number as a priority
                                                                       // because we don't actually need proper priorities set up
    ADCSequenceStepConfigure( ADC0_BASE, 3, 0, ADC_CTL_CH0 | ADC_CTL_IE | ADC_CTL_END );
    ADCIntRegister( ADC0_BASE, 3, ADC0_S3_IRQHandler ); // this one registers the proper irq handler based
                                                        // on adc [0..1] and sequencer [0..3]
                                                        // ADC0_S3_IRQHandler calls UT_ANALOG_SEQUENCE_Hook internally
    PWMGenIntTrigEnable( PWM0_BASE, PWM_GEN_0, PWM_TR_CNT_ZERO ) // here I set up the trigger for pwm based on
                                                                 // a previous pwm created, using PWM_TR_CNT_ZERO
                                                                 // (I'm a begginer in embedded engineering, I don't
                                                                 // know how to use all the other flags that are
                                                                 // possible here, nor what do they mean...
                                                                 // I'd love a quick reference to something
                                                                 // as I can't find a detailed description on these hahaha)
    ADCIntEnable( ADC0_BASE, 3 );
    IntEnable( INT_ADC0SS0_TM4C123 );
    ADCSequenceEnable( ADC0_BASE, 3 );

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

    尊敬的 Vinicius:

    谢谢。 因此、我对它的读取方式有一个问题、那就是在调整占空比时、ADC 触发器不会发生变化。 ADC 触发器基于频率。

    它实际上会跟踪您的配置。

    您正在使用  PWM_TR_CNT_ZERO 来触发 ADC 中断。 当您的计数在基于 PWM 频率的计数周期结束时达到零时、将触发此操作。

    占空比由 cmpA/CMPB 控制。 因此、如果您希望根据占空比触发、则需要根据 PWM 配置使用其中一个:

    #define PWM_TR_CNT_AU           0x00000400  // Trig if COUNT = CMPA U
    #define PWM_TR_CNT_AD           0x00000800  // Trig if COUNT = CMPA D
    #define PWM_TR_CNT_BU           0x00001000  // Trig if COUNT = CMPB U
    #define PWM_TR_CNT_BD           0x00002000  // Trig if COUNT = CMPB D

    对于这些触发器注释、简写如下:CMPA U =比较 A、向上、CMPB D =比较 B、向下等

    使用正确的标志后、您应该会看到每个占空比发生的触发器。

    我要给出的另一个建议是、我认为这不会显著影响绩效、但这是一个最佳实践:

    对于这样的连续触发器、建议的方法是使用 PWMEnable 作为触发点、而不是 ADCSequenceEnable。

    通常的过程是先配置 ADC、然后配置触发外设、并在将所有配置为触发采样启动后启动该外设。

    此致、

    Ralph Jacobi

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

    感谢您的回答! 我能够最好地了解寄存器是什么、我的代码现在运行得更好! 但是... 我似乎看不到一种使用100%占空比的方法、因为它仅根据时钟触发、而不是信号边沿触发。 是否有任何配置、或者我只是坚持时钟触发?

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

    尊敬的 Vinicius:

    您能否详细说明单个触发器? 如果您只配置一个比较触发器、我希望每个周期只有一个匹配项?

    此致、

    Ralph Jacobi

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

    如果您使用生成的 PWM 信号作为 ADC 的触发器、将其占空比设置为0%并将其切换为100%、则只有一个上升沿。

    该单个上升沿将触发。

    我尝试提出一个解决方案来在 Tiva 上进行此工作、但我遇到了困难、因为触发器都与时钟周期相关联、所以它将始终在我们为 PWM 信号设置的时间段内触发一次。

    现在,我可以根据占空比打开和关闭触发器,方法是0%=关闭, >0%=打开。

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

    尊敬的 Vinicius:

    我看到、我认为您的解决方案可能是最好的解决方案。 我无法说我们以前有过这样的用例、但阅读 D/S、我相信您的描述是准确的。

    我觉得使用计时器可能对您的用例更有意义、但我无法确定、您可能已经出于其他原因排除了计时器。 您可以很容易地了解加载周期并启用/禁用它、此外您还可以使用周期和单次触发模式。 只是一个思考、以防您尚未评估该途径。

    此致、

    Ralph Jacobi

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

    您好、Ralph!

    我已将 CMPA 和 CMPB 定义为适合我们设置的配置。 我们已经设置了计时器并使其正常工作。 我只是尝试按照之前针对 LPC 微控制器完成的单位测试进行操作。 由于触发器在每个 UC 中的工作方式不同、我无法使其像这样工作。

    感谢您的帮助! 现在、我更好地了解 PWM 的设置和触发器!