cancel
Showing results for 
Search instead for 
Did you mean: 

One pulse with repitition counter

Imran Arshad
Associate II
Posted on March 03, 2017 at 08:14

Hi all,

I am a newbie developer for STM I am developing an application using the STM32F746 Discovery board and KEIL uVision. I need to output two pulses on GPIO that I will feed to another board. The first pulse is a simple PWM with 250kHz frequency and 60% duty cycle. This part was easy as I simply modified the examples of PWM given in DFP 2.8 using HAL library and I outputted it on TIM3 Channel 1.

The tricky part is the second pulse. It should start on the falling edge of pulse 1 and out put a fixed number of pulses and then stop and start on next falling edge. The processor should never be involved in this. So I searched for solutions and found that it could be done using One Pulse mode and Repetition Counter register.

Also I figured out that only TIM1 and TIM8 have repetition counter.

So my question is how can I start the One Pulse Mode with N-Pulse generation using TIM3 Channel 1 falling edge as trigger? The reason I am asking is because in the HAL library there is a function HAL_TIM_OnePulse_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OnePulse_InitTypeDef* sConfig, uint32_t OutputChannel, uint32_t InputChannel). So it requires two channels of same timer (One for Input i.e trigger and other for the desired waveform output). So do we need to physically short the output of TIM3 channel 1 to TIM1 Channel 2?

Or can we set the trigger internally without doing any such thing?

Also is there any example of this available? Anyone who has completed this who can share their work? I am a newbie and facing great difficulty in my first STM32 project.

0690X00000603i0QAA.jpg

Note: this post was migrated and contained many threaded conversations, some content may be missing.
16 REPLIES 16
Posted on March 06, 2017 at 09:07

Thanks for the Code... I will look into it although I will need lots of modifications as it is for 476 while I am working on 7 I will try to understand it and then modify it to my needs....

Posted on March 06, 2017 at 09:08

Thanks for the Code... I will look into it although I will need lots of modifications as it is for 476 while I am working on 7 I will try to understand it and then modify it to my needs....

Posted on March 06, 2017 at 09:24

This is also a very good suggestion to use DMA pattern buffer in cyclic mode to generate the Pulses.... I will also look into it and play with it... I guess I will need to initialize DMA as in the following code.

https://community.st.com/0D50X00009XkYYvSAN

Posted on March 09, 2017 at 02:37

www.efton.sk/STM32/slave_onex3.zip

Sorry but that code has a flaw in that the 3 short pulses don't start at the falling edge of the long pulse but after a delay. This is due to the one-pulse mode parking after update which happens when timer arrives at 0, so that the 'idle' level is that corresponding to the lower part of the ARR span.

I believe I still could pull out the required waveform only with two timers in a different way, using the gated mode in the slave timer.

JW

Imran Arshad
Associate II
Posted on March 16, 2017 at 05:47

Here is the final version of working code for Discovery 746NG boards. This is for someone in future who will come here looking for same issue....

// (C)2017 wek at efton dot sk
// example for:
// -- linked timers, slave in trigger mode, i.e. counter enabled from the master
// -- (slave) timer in one-pulse-mode with repetition
void TIM_TEST(void)
{
#define F_CPU 216000000UL
#define TIM_CCMR_CCS__OUTPUT 0
#define TIM_CCMR_OCM__PWM1 6 
#define TIM_CCMR_OCM__PWM2 7 
#define TIM_CR2_MMS__OC1REF 4
#define TIM_CR2_MMS__OC2REF 5
#define TIM1_SMCR_TS__TIM2 1
#define TIM1_SMCR_TS__TIM3 2
#define TIM_SMCR_SMS__TRIGGER 6
GPIO_InitTypeDef GPIO_InitStruct;
 /*##-1- Enable peripherals and GPIO Clocks #################################*/
 /* TIMx Peripheral clock enable */
 __TIM2_CLK_ENABLE();
//__TIM1_CLK_ENABLE();//For future use if any...
__TIM8_CLK_ENABLE();
 /* Enable all GPIO Channels Clock requested */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
 /* Configure PA.15 (pin 2 in CN7 connector) (TIM2_Channel1), 
 PA.08 (pin 6 in CN4 connector) (TIM1_Channel1), 
 PC.06 (pin 2 in CN4 connector) (TIM8_Channel1)
 in output, push-pull, alternate function mode
 */
 /* Common configuration for all channels */
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_PULLUP;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
 GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
 GPIO_InitStruct.Pin = GPIO_PIN_15;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
 GPIO_InitStruct.Pin = GPIO_PIN_8;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 GPIO_InitStruct.Alternate = GPIO_AF3_TIM8;
 GPIO_InitStruct.Pin = GPIO_PIN_6;
 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

// setup TIM2 to provide the continued PWM waveform, 250kHz period and 60:40% duty
 TIM2->PSC = 0;// this sets prescaler shadow
 TIM2->ARR = 432;// want 250 kHz. Formula is Update Event Frequency = TIM_CLK / (Prescaler +1) * (Autoreload +1) 
 TIM2->EGR = TIM_EGR_UG; // through forced update load prescaler from shadow
 TIM2->CCMR1 = 0
 | (TIM_CCMR_CCS__OUTPUT * TIM_CCMR1_CC1S_0) // output compare on CH2
 | (TIM_CCMR_OCM__PWM2 * TIM_CCMR1_OC1M_0) // PWM2 mode on CH2
 ;
 TIM2->CCER = 0
 | (1 * TIM_CCER_CC1P) // invert TIM2_CH2 
 | (1 * TIM_CCER_CC1E) // enable TIM2_CH2
 ;
 TIM2->CCR1 = (60ULL * 432/ 100);//60% duty cycle. Here 432 is ARR set above. If changed above change here also...
 TIM2->CR2 = 0
 | (TIM_CR2_MMS__OC1REF * TIM_CR2_MMS_0) // select OC1Ref as TRGO
 ;
 TIM2->CR1 = 0
 | (1 * TIM_CR1_CEN) // finally, counter enable
 ;
// now setup TIM8 - we want it to disable itself i.e. one-pulse mode; 16 pulses, that goes to repetition counter.
TIM8->PSC = 0; // this sets prescaler shadow
 TIM8->ARR = 12; // want 16 MHz
 TIM8->RCR = 16 - 1; // want 16 pulses until CR1.CEN goes off
 TIM8->EGR = TIM_EGR_UG; // through forced update load prescaler from shadow
 TIM8->CCMR1 = 0
 | (TIM_CCMR_CCS__OUTPUT * TIM_CCMR1_CC1S_0) // output compare
 | (TIM_CCMR_OCM__PWM2 * TIM_CCMR1_OC1M_0) // PWM2 mode - low, then high
 ;
TIM8->CCER = 0
 | (1 * TIM_CCER_CC1E) // enable TIM8_CH1
 ;
 TIM8->BDTR = 0
 | (1 * TIM_BDTR_MOE) // and the advanced-timers' gotcha: main output enable
 ;
 TIM8->CCR1 = (50ULL * 12 / 100); // this is to achieve 50: Note here 12 is ARR. So if change ARR above then also change here. 
 TIM8->SMCR = 0
 | (TIM1_SMCR_TS__TIM2 * TIM_SMCR_TS_0) // select TIM1/TIM8 as TRGI source
 | (TIM_SMCR_SMS__TRIGGER * TIM_SMCR_SMS_0) // and set trigger mode for slave controller
 ;
// Notes By Imran.... Above register setting for SMCR means
// SMS 0110: Trigger Mode - The counter starts at a rising edge of the trigger TRGI.
// TS 001: Internal Trigger 1 (ITR1) i.e From TIM2 to TIM1/TIM8 (Slave)
// See refernce manual page 672 for details.... 
 TIM8->CR1 = 0
 | (1 * TIM_CR1_OPM) // want one-time mode
 | (0 * TIM_CR1_CEN) // we don't set CEN bit in CR1, it will be set from the slave controller by the trigger mode
 ;
while(1); // and, as promised, this is all, folks. Lean back and enjoy! :-)
}
 �?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Hi @waclawek.jan  - I am looking at implementing a similar logic. I found this post useful, however, I am not able to access the zip folders attached.

www.efton.sk/STM32/slave_onex3.zip

 www.efton.sk/STM32/stm32l476xx.zip 

 

It would be of great help if there's an access provided to the proposed solution here.

Thanks,

Janani

Those links got damaged due to the forum migration, I've fixed them. But basically you will find there the same code as is posted above.

JW