cancel
Showing results for 
Search instead for 
Did you mean: 

Problems with HRTIM on STM32F334

marcogrossi89
Associate II
Posted on June 20, 2017 at 10:34

I write since I have a problem using HRTIM with the Nucleo F334R8 development board.

The firmware is developed using System Workbench for STM32, using the STM32 HAL libraries (and code Snippet for HRTIM). The MCU clock source is 128MHz (High Speed Internal Oscillator with PLL).

The code must generate two PWM signals with frequency 6.78MHz with a phase_shift defined by the uint16_t variable i_phase. The two PWM signals are generated using HRTIM counter channels TD1 and TD2 (output on pins PB14 and PB15). The variable _6and78MHz_PERIOD is defined as 604. The variable I_PHASE can be initialized to any integer between 0 and 302. TD1 is set when the counter overflows and reset at _6and78MHz_PERIOD/2. TD2 is set when the counter value is I_PHASE and reset at _6and78MHz_PERIOD/2 + I_PHASE. The code for HRTIM initialization is the following:

static void

HRTIM1_Init(

void

)

{

        

/* --------------------- Timer D initialization --------------------------- */

        

/* TIMD counter operating in continuous mode,

preload

enabled on REP event */

         HRTIM1->

sTimerxRegs

[HRTIM_TIMERINDEX_TIMER_D].

TIMxCR

= HRTIM_TIMCR_CONT

                                                              + HRTIM_TIMCR_PREEN

                                                              + HRTIM_TIMCR_TREPU;

        

/* Set period TIMD*/

         HRTIM1->

sTimerxRegs

[HRTIM_TIMERINDEX_TIMER_D].

PERxR

= _6and78MHz_PERIOD;

         HRTIM1->

sTimerxRegs

[HRTIM_TIMERINDEX_TIMER_D].

CMP1xR

= _6and78MHz_PERIOD;

         HRTIM1->

sTimerxRegs

[HRTIM_TIMERINDEX_TIMER_D].

CMP2xR

= _6and78MHz_PERIOD/2;

        

if

(i_phase == 0)

         HRTIM1->

sTimerxRegs

[HRTIM_TIMERINDEX_TIMER_D].

CMP3xR

= _6and78MHz_PERIOD;

        

else

         HRTIM1->

sTimerxRegs

[HRTIM_TIMERINDEX_TIMER_D].

CMP3xR

= i_phase;

         HRTIM1->

sTimerxRegs

[HRTIM_TIMERINDEX_TIMER_D].

CMP4xR

= _6and78MHz_PERIOD/2 + i_phase;

        

/* TD1 output */

         HRTIM1->

sTimerxRegs

[HRTIM_TIMERINDEX_TIMER_D].

SETx1R

= HRTIM_SET1R_CMP1;

         HRTIM1->

sTimerxRegs

[HRTIM_TIMERINDEX_TIMER_D].

RSTx1R

= HRTIM_RST1R_CMP2;

        

/* TD2 output */

         HRTIM1->

sTimerxRegs

[HRTIM_TIMERINDEX_TIMER_D].

SETx2R

= HRTIM_SET2R_CMP3;

         HRTIM1->

sTimerxRegs

[HRTIM_TIMERINDEX_TIMER_D].

RSTx2R

= HRTIM_RST2R_CMP4;

         HRTIM1->

sCommonRegs

.

OENR

= HRTIM_OENR_TD1OEN + HRTIM_OENR_TD2OEN;

         GPIO_HRTIM_outputs_Config(); 

/* Initialize HRTIM GPIO outputs */

         HRTIM1->

sMasterRegs

.

MCR

|= HRTIM_MCR_TDCEN;

}

However the second (phase_shifted) PWM output presents some glitches depending on the value of I_PHASE.

When I_PHASE = 0 the two PWM signals are correct. However for I_PHASE values from 2 to 60 a glitch is present with TD2 losing some periods with respect to TD1 (the number of lost periods is higher for lower values of I_PHASE). For values of I_PHASE between 62 and 302 the generated PWM signals are correct. Please refer to the attached figure where the two PWM signal waveforms are presented for different values of I_PHASE (waveforms acquired using an Agilent MSO6014A Mixed Signal Oscilloscope).

I ask if anyone can help fixing this problem.

Thanks.

Best regards.

#hrtim #stm32f334
1 REPLY 1
Zt Liu
Senior III
Posted on June 26, 2017 at 05:43

Hey, I think you've missed the minimal of the compare value.

(?from ref man

?

)0690X00000607W8QAI.png

Your cmp value should range from 96 (32*3)....

So you may both add this minimal val to your CMPx,

(For example, CMP1 = 0x60, CMP3 = 0x65, then you get a phase shift with 5 HRTIM Ticks)

Moreover, you would probably use an external crystal, for the HSI changes with the temperature.

Good Luck!