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.

[参考译文] MSP432P401R:PWM 不更新

Guru**** 2524460 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/675926/msp432p401r-pwm-not-updating

器件型号:MSP432P401R

我正在尝试使用模拟输出接近传感器构建具有障碍物检测功能的汽车。 问题是、每当我集成 PWM 模块以移动车辆和接近传感器时、PWM 不会更新(我使用示波器测量)。 奇怪的是、每当我逐行进入程序时、PWM 都会更新、但如果我运行程序、它不会更新。

下面是我当前使用的代码。

Timer_A_PWMConfig 伺服配置=
{
Timer_A_CLOCKSOURCE_SMCLK、
Timer_A_CLOCKSOURCE_divider _1、
1300、
Timer_A_CAPTURECOMPARE 寄存器_1、
Timer_A_OUTPUTMODE_RESET_SET、
94 //center
};

// Timer_A 伺服 PWM 配置参数*/
Timer_A_PWMConfig motorConfig =
{
Timer_A_CLOCKSOURCE_SMCLK、
Timer_A_CLOCKSOURCE_divider _1、
1300、
Timer_A_CAPTURECOMPARE 寄存器_2、
Timer_A_OUTPUTMODE_RESET_SET、
75
};




int main (void)
{
/*停止 WDT */
MAP_WDT_A_HOLDTimer();
MAP_Interrupt_disableSlepOnIsrExit();

/*零填充缓冲器*/
memset (resultsBuffer、0x00、8);

对于 LF 模式、//将 MCLK 设置为 REFO 为128Khz
*将 SMCLK 设置为64Khz */
MAP_CS_setReferenceOscillatorFrequency (CS_REFO_128KHZ);
///map_CS_initClockSignal (CS_MCLK、CS_REFOCLK_select、CS_clock_divider);
MAP_CS_initClockSignal (CS_SMCLK、CS_REFOCLK_SELECT、CS_CLOCK_DEVIDER_2);
MAP_PCM_setPowerState (PCM_AM_LF_VCORE0);

/*将 GPIO2.4配置为 PWM 的外设输出和按钮的 P1.1
*中断*/
MAP_GPIO_setPeripheralModuleFunctionOutputPin (GPIO_PORT_P2、GPIO_PIN4、GPIO_PRIMARY_MODULE_Function);
MAP_GPIO_setPeripheralModuleFunctionOutputPin (GPIO_PORT_P2、GPIO_PIN5、GPIO_PRIMARY_MODULE_Function);

/*将 Timer_A 配置为具有大约500ms 的周期和
*初始占空比为其10%(3200个节拍)*/
MAP_Timer_A_generatePWM (TIMER_A0_BASE、&servoConfig);

/*将 Timer_A 配置为具有大约500ms 的周期和
*初始占空比为其10%(3200个节拍)*/
MAP_Timer_A_generatePWM (TIMER_A0_BASE、&motorConfig);

/*将 GPIO2.4配置为 PWM 的外设输出和按钮的 P1.1
*中断*/
MAP_GPIO_setPeripheralModuleFunctionOutputPin (GPIO_PORT_P2、GPIO_PIN4、GPIO_PRIMARY_MODULE_Function);
MAP_GPIO_setPeripheralModuleFunctionOutputPin (GPIO_PORT_P2、GPIO_PIN5、GPIO_PRIMARY_MODULE_Function);




/*初始化 ADC (MCLK/64/8)*/
MAP_ADC14_enableModule();
MAP_ADC14_initModule (ADC_CLOCKSOURCE_MCLK、ADC_PREDIVIDER_64、ADC_DIVIDER_8、
0);

/*在*/中为模拟配置 GPIO
MAP_GPIO_setPeripheralModuleFunctionInputPin (GPIO_PORT_P5、
GPIO_PIN5 | GPIO_PIN4 | GPIO_PIN3 | GPIO_PIN2 | GPIO_PIN1
| GPIO_PIN0、GPIO_TICE_MODULE_FUNCTION);
MAP_GPIO_setPeripheralModuleFunctionInputPin (GPIO_PORT_P4、
GPIO_PIN7 | GPIO_PIN6、GPIO_Terti_MODULE_FUNCTION);
MAP_GPIO_setAsOutputPin (GPIO_PORT_P2、GPIO_PIN1);
MAP_GPIO_setOutputLowOnPin (GPIO_PORT_P2、GPIO_PIN1);


/*配置 ADC 内存(ADC_MEM0 - ADC_MEM7 (A0 - A2),重复)*/
MAP_ADC14_configureMultiSequenceMode (ADC_MEM0、ADC_MEM2、TRUE);
MAP_ADC14_configureConversionMemory (ADC_MEM0、
ADC_VREFPOS_INTBUF_VREFNEG_VSS、
ADC_INPUT_A0、false);
MAP_ADC14_configureConversionMemory (ADC_MEM1、
ADC_VREFPOS_INTBUF_VREFNEG_VSS、
ADC_INPUT_A1、false);
MAP_ADC14_configureConversionMemory (ADC_MEM2、
ADC_VREFPOS_INTBUF_VREFNEG_VSS、
ADC_INPUT_A6、false);

/*在通道7 (序列结束)上进行转换时启用中断
*已完成并启用转换*/
MAP_ADC14_enableInterrupt (ADC_INT2);

/*启用中断*/
MAP_Interrupt_enableInterrupt (INT_ADC14);
MAP_Interrupt_enableMaster();

/*将采样计时器设置为自动单步执行序列
*转换。
*
MAP_ADC14_enableSampleTimer (ADC_AUTOMATE_DIOTIVation);

/*触发样本开始*/
MAP_ADC14_enableConversion();
MAP_ADC14_toggleConversionTrigger ();


_DELAY_CYCLES (20000);

MAP_Timer_A_generatePWM (TIMER_A0_BASE、&motorConfig);
motorConfig.dutyCycle = 90;
/*正在休眠*/
while (1)
{
//map_Timer_a_generatePWM (timer_A0_BASE、&motorConfig);
/*
if (ADC_SampleComplete = 1){
if ((resultsBuffer[0]> 11000)|(resultsBuffer[1]> 11000)|(resultsBuffer[2]> 11000)){
motorConfig.dutyCycle = 70;
MAP_GPIO_setOutputHighOnPin (GPIO_PORT_P2、GPIO_PIN1);
//map_Timer_a_generatePWM (timer_A0_BASE、&motorConfig);
}
否则{
MAP_GPIO_setOutputLowOnPin (GPIO_PORT_P2、GPIO_PIN1);
motorConfig.dutyCycle = 97;
// map_Timer_a_generatePWM (timer_A0_BASE、&motorConfig);
}
}
*

// map_pcm_gotoLPM0();
}
}

//每当转换完成并放置在
* ADC_MEM7中时,就会触发此中断。 这表示转换结束、结果数组
被*抓取并放置在 resultsBuffer */
void ADC14_IRQHandler (void)
{中
uint64_t status;

STATUS = MAP_ADC14_getEncableInterruptStatus();
ADC_SampleComplete = 0;
if (status & ADC_INT2)
{
resultsBuffer[0]= MAP_ADC14_getResult (ADC_MEM0);
resultsBuffer[1]= MAP_ADC14_getResult (ADC_MEM1);
resultsBuffer[2]= MAP_ADC14_getResult (ADC_MEM2);
ADC_SampleComplete = 1;

if ((resultsBuffer[0]> 11000)|(resultsBuffer[1]> 11000)|(resultsBuffer[2]> 11000)){
motorConfig.dutyCycle = 70;
MAP_GPIO_setOutputHighOnPin (GPIO_PORT_P2、GPIO_PIN1);
MAP_Timer_A_generatePWM (TIMER_A0_BASE、&motorConfig);
}
否则{
MAP_GPIO_setOutputLowOnPin (GPIO_PORT_P2、GPIO_PIN1);
motorConfig.dutyCycle = 97;
MAP_Timer_A_generatePWM (TIMER_A0_BASE、&motorConfig);
}
}
MAP_ADC14_clearInterruptFlag (status);
} 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    当我读取该值时、您的(PWM)定时器周期为1300/65536=~20ms、并且您的 ADC 中断每3MHz/64/8/(4+16)/3=~10ms 到达一次。

    在每个 ADC 中断上、MAP_Timer_A_generatePWM()正在重新启动计时器(TACLR)。 因此计数器永远不会到达 TA0CCR0。 在复位/置位模式中、输出在 EQU0上被设定为高电平[另请参见 SLAU356G 图17-12]、这种情况永远不会发生、所以输出从低电平开始、然后复位(至低电平)、然后定时器重新启动。

    如果给定您正在使用的特定值、您可能可以通过明智地(在 ISR 中)使用 Timer_A_setCompareValue 而不是 MAP_Timer_A_generatePWM 来获得。 但您仍将以实际运行速度将 PWM 更新两倍、这并不有用。

    我建议您降低 ADC 的速度、使其中断频率不超过您的计时器周期(20ms)。 首选的方法是使用计时器和 CONSEQ=1来调整它的速度、而不是 CONSEQ=3。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您是如何到达 ADC 中断的~10ms 的? 我知道64和8的位置,但我不明白你是怎么得到(4+16)/3的
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    4来自 ADC14SHT0=0 [SLAU356H 表22-5]、因为您没有设置它。 [另请参见 ADC14_setSampleHoldTime ()。]
    16来自 SLAU356H 图22-10、表示"转换"步骤需要16个时钟。 (再看一下、我发现还有另一个用于存储结果的时钟、因此应该是(4+16+1)/3、但这不会对估算造成太大的影响。)
    3来自每3次转换中断一次。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢您提供这些信息!
    那么、如果我想将 ADC 中断连接到计时器、我该如何处理它。 我是否使用连续计时器模式? 或者最好的方法是什么?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我在 TIREX 中看到一个示例:"adc14_single_conversion 重复_dimera_source"、似乎就是这样。 它可以实现单个通道、但您已经了解了如何实现多个通道。

    其思路是在增模式下运行一个计时器、并使用 OUTMOD 设置某些 CCR (切换可能还可以)以在计时器周期生成脉冲、然后将 ADC14SHS 设置为使用该 CCR 作为触发器。 SLAS826G 表6-51中列出了可能的触发器。

    在示例中、此行将它们连接在一起:
    MAP_ADC14_setSampleHoldTrigger (ADC_TRIGGER_SOURCE1、false);

    CONSEQ=1和 MSC=1时不明显的情况:根据 SLAU356H 图22-8、您需要在每个突发之间切换 ENC (ADC14_disableConversion、然后 ADC14_enableConversion)。 ISR 可能是执行此操作的好地方。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    切换 ENC 的示例可在以下位置找到: e2e.ti.com/.../2189011

    此致、
    Chris