KL27Z64VFM4 PWM duty pulse reversed

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

KL27Z64VFM4 PWM duty pulse reversed

1,596 Views
albert_zhou
Contributor III

Hi, 

I configured PORTA1 as TPM2-CH(0) as the PWM pulse output and find a problem. The duty pulse level is reversed and I could not figure out what is going wrong.  I expected duty pulse 600 counts would be high and the rest time 6000 counts should be low but the real pulse out is reversed. 

Here is my code. Could some body help me to solve the problem? 

void PWM_init(void) //added by Albert 2019.06.17
{
CLOCK_EnableClock(kCLOCK_Tpm2);
SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_TPMSRC_MASK) | SIM_SOPT2_TPMSRC(1U)); //=1=48MHz

PORTA->PCR[1] =BIT8+BIT9;
TPM2->SC &=~(BIT3+BIT4); //disable timer
TPM2->SC = TPM_SC_PS(0);//prescale =1 TPM2-SC=1 ,disable the counter
TPM2->CNT =0U; //clear counter value
TPM2->MOD =6600U; //Modulo, PWM=400Hz set PWM period 60K =400Hz
TPM2->CONTROLS[0].CnSC =BIT3+BIT5; //BIT3+BIT5=Edge Aligned duty cycle output; BIT2+BIT4 =50% toggle on match
TPM2->CONTROLS[0].CnV =600U; //duty pulse
TPM2->CONF =TPM_CONF_TRGSEL(0);
TPM2->SC |=BIT3; //Start timer
}
int main(void) {
/* Init board hardware. */
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();

// initialize the system
system_manager_init(&s_sensor);
PWM_init();
while(1) {
// and off we go...
// GPIOC->PTOR |=BIT4;//RS485_TX_ON;
system_manager_process(&s_sensor);
}
}

0 Kudos
4 Replies

1,503 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

Hi Albert Zhou,

According to the description of "Table 23-5. Mode, Edge, and Level Selection", your configuration seems ok.
Maybe you should check if the invert mode is enabled on your oscilloscope.

Table 23-5. Mode, Edge, and Level Selection.png

Best Regards,

Robin

 

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

1,503 Views
albert_zhou
Contributor III

Hi Robin,

I know this code works on the other board with same MCU. I use the same scope to check the PWM output. The other board has the correct PWM output.

I know there is four functions declared before the PWM_init(). I wonder there are some code I need to added in the PWM_init() in order to make this function work.

Thanks for your response.

Albert Zhou

0 Kudos

1,503 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

You can check the register value of TPM2 and PORTA during debug.
The MCUXPresso SDK_2.6.0_MKL27Z64xxx4 using PTA1 as LPUART function, so I didn't call BOARD_InitDebugConsole() and modify the codes in BOARD_InitPins().

Best Regards,

Robin

 

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

1,503 Views
albert_zhou
Contributor III

Hi Robin,

I know if I use SDK board the code will function right as expected. I guess there must be something interferences the configuration of my code.

Do you know the function BOARD_BootClockRUN()?

the BOARD_InitPins() cod eas below:

void BOARD_InitPins(void) {

CLOCK_EnableClock(kCLOCK_PortA); /* Port A Clock Gate Control: Clock enabled */

CLOCK_EnableClock(kCLOCK_PortB); /* Port B Clock Gate Control: Clock enabled */

CLOCK_EnableClock(kCLOCK_PortC); /* Port C Clock Gate Control: Clock enabled */

CLOCK_EnableClock(kCLOCK_PortD); /* Port D Clock Gate Control: Clock enabled */

CLOCK_EnableClock(kCLOCK_PortE); /* Port E Clock Gate Control: Clock enabled */

CLOCK_EnableClock(kCLOCK_Tpm2);

PORT_SetPinMux(PORTA, 0U, kPORT_MuxAlt7); // PTA0 = SWD_CLK (SWD_CLK)

PORT_SetPinMux(PORTA, 1U, kPORT_MuxAlt3); // PTA1 = PWM out (TPM2_CH0)

// PTA2 nc

PORT_SetPinMux(PORTA, 3U, kPORT_MuxAlt7); // PTA3 = SWD_DIO (SDW_DIO)

PORT_SetPinMux(PORTA, 4U, kPORT_MuxAsGpio); // PTA4 = CPG1 (GPIO A4)

PORT_SetPinMux(PORTA, 18U, kPORT_MuxAlt3); // PTA18 = MBRx (LPUART1_RX)

PORT_SetPinMux(PORTA, 19U, kPORT_MuxAlt3); // PTA19 = MBTx (LPUART1_TX)

PORT_SetPinMux(PORTA, 20U, kPORT_MuxAlt7); // PTA20 = RESET_b (RESET_b)

PORT_SetPinMux(PORTB, 0U, kPORT_PinDisabledOrAnalog); // PTB0 = mV_h (ADC0_SE8)

PORT_SetPinMux(PORTB, 1U, kPORT_PinDisabledOrAnalog); // PTB1 = VB (ADC0_SE9?) [pin 21]

PORT_SetPinMux(PORTC, 1U, kPORT_PinDisabledOrAnalog); // PTC1 = ORP (ADC0_SE15)

PORT_SetPinMux(PORTC, 2U, kPORT_PinDisabledOrAnalog); // PTC2 = TEMP_H (ADC0_SE11)

PORT_SetPinMux(PORTC, 3U, kPORT_MuxAsGpio); // PTC3 = CPG0 (GPIO C3)

PORT_SetPinMux(PORTC, 4U, kPORT_MuxAsGpio); // PTC4 = MODBUS_EN (GPIO C4)

PORT_SetPinMux(PORTC, 5U, kPORT_MuxAsGpio); // PTC5 = LDO_HpH_SEL (GPIO C5)

PORT_SetPinMux(PORTC, 6U, kPORT_MuxAsGpio); // PTC6 = reed switch (GPIO C6)

PORT_SetPinMux(PORTC, 7U, kPORT_MuxAsGpio); // PTC7 = ?? ("E202")

PORT_SetPinMux(PORTD, 4U, kPORT_MuxAsGpio); // PTD4 = MBTXEN (GPIO D4)

PORT_SetPinMux(PORTD, 5U, kPORT_MuxAsGpio); // PTD5 = CPLH (GPIO D5)

PORT_SetPinMux(PORTD, 6U, kPORT_MuxAlt3); // PTD6 = ?? ("E209") (LPUART0_RX)

PORT_SetPinMux(PORTD, 7U, kPORT_MuxAlt3); // PTD7 = ?? ("E210") (LPUART0_TX)

PORT_SetPinMux(PORTE, 0U, kPORT_MuxAsGpio); // PTE0 = ?? ("E204")

PORT_SetPinMux(PORTE, 16U, kPORT_PinDisabledOrAnalog); // PTE16 = pH/DO (ADC0_SE1)

PORT_SetPinMux(PORTE, 30U, kPORT_PinDisabledOrAnalog); // PTE32 = PWM_FB (ADC_SE23)

// Configure loop current PWM (whether or not probe uses current loop)

SIM->SOPT2 = ((SIM->SOPT2 & ~SIM_SOPT2_TPMSRC_MASK) | SIM_SOPT2_TPMSRC(1U)); //=1=48MHz

// SIM->SOPT4 = ((SIM->SOPT4 &

// (~(SIM_SOPT4_TPM2CH0SRC_MASK))) // Mask bits to zero which are setting //

// | SIM_SOPT4_TPM2CH0SRC(SOPT4_TPM2CH0SRC_TPM2_CH0) // TPM2 Channel 0 Input Capture Source Select: TPM2_CH0 signal //

// );

//

// configure LPUART1 (used for Modbus i/o)

SIM->SOPT5 = ((SIM->SOPT5 &

(~(SIM_SOPT5_LPUART1TXSRC_MASK | SIM_SOPT5_LPUART1RXSRC_MASK))) /* Mask bits to zero which are setting */

| SIM_SOPT5_LPUART1TXSRC(SOPT5_LPUART1TXSRC_LPUART_TX) /* LPUART1 Transmit Data Source Select: LPUART1_TX pin */

| SIM_SOPT5_LPUART1RXSRC(SOPT5_LPUART1RXSRC_LPUART_RX) /* LPUART1 Receive Data Source Select: LPUART1_RX pin */

);

// PORTA->PCR[1] =BIT8+BIT9;

TPM2->SC &=~(BIT3+BIT4); //disable timer

TPM2->SC = TPM_SC_PS(0);//prescale =1 TPM2-SC=1 ,disable the counter

TPM2->CNT =0U; //clear counter value

TPM2->MOD =6600U; //Modulo, PWM=400Hz set PWM period 60K =400Hz

TPM2->CONTROLS[0].CnSC =BIT3+BIT5; //BIT3+BIT5=Edge Aligned duty cycle output; BIT2+BIT4 =50% toggle on match

TPM2->CONTROLS[0].CnV =600U; //duty

TPM2->CONF =TPM_CONF_TRGSEL(0);

TPM2->SC |=BIT3; //Start timer

}

and the BOARD_BootClockRUN(), do you think those code interferences the TPM2CH0?

void BOARD_BootClockRUN(void)

{

/* Set the system clock dividers in SIM to safe value. */

CLOCK_SetSimSafeDivs();

/* Set MCG to HIRC mode. */

CLOCK_SetMcgliteConfig(&mcgliteConfig_BOARD_BootClockRUN);

/* Set the clock configuration in SIM module. */

CLOCK_SetSimConfig(&simConfig_BOARD_BootClockRUN);

/* Set SystemCoreClock variable. */

SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK;

}

0 Kudos