cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F031 PWM input capture without CubeMx.

alexandre fortier
Associate
Posted on May 03, 2018 at 15:03

Hello I am Alexandre,

I am working on STM32F031C4T6

I succeed to read the duty cycle and period of PWM on port PA8

I tried to do the same on port PA4, PA6, PA7, PB0, PB1, PB10 and PB11, but it is not working at all.

Here my working code on PA8:

/*************************************************************************************************/

//Initialisation for GPIOA

RCC->AHBENR |= RCC_AHBENR_GPIOAEN;

//Work for PA5/8/9

GPIOA->MODER = (GPIOA->MODER & ~(GPIO_MODER_MODER4 | GPIO_MODER_MODER8

| GPIO_MODER_MODER9)) | GPIO_MODER_MODER4_1

| GPIO_MODER_MODER8_1 | GPIO_MODER_MODER9_1;

GPIOA->AFR[0] |= 0x02 << (5 * 4);

GPIOA->AFR[1] |= 0x02 | (0x02 << ((9 - 8) * 4));

//Initialisation for TIM1

RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; 

TIM1->CR1 |= TIM_CR1_CEN; 

TIM1->CCMR1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_1; 

TIM1->SMCR |= TIM_SMCR_TS_2 | TIM_SMCR_TS_0 

                        | TIM_SMCR_SMS_2;

TIM1->CCER |= TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC2P; 

TIM1->DIER |= TIM_DIER_CC1IE;

/*************************************************************************************************/

With this code i can get the dutry cycle on CCR2 and the period on CCR1.

Here below the code for PB1 and PB0 which is not working:

/*************************************************************************************************/

//Initialisation for GPIOB

RCC->AHBENR |= RCC_AHBENR_GPIOBEN; //active l'horloge du GPIOB

GPIOB->MODER = (GPIOB->MODER & ~(GPIO_MODER_MODER0 | GPIO_MODER_MODER1))

                                   | GPIO_MODER_MODER0_1| GPIO_MODER_MODER1_1 ;

GPIOB->AFR[0] |= 0x02 << (1 * 4);

GPIOB->AFR[0] |= 0x02 << (0 * 4);

//Initialisation for TIM3

RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;

TIM3->CR2 |= TIM_CR2_TI1S;

TIM3->CR1 |= TIM_CR1_CEN;

TIM3->CCMR1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_1;

TIM3->SMCR |= TIM_SMCR_TS_2 | TIM_SMCR_TS_0

| TIM_SMCR_SMS_2;

TIM3->CCER |= TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC2P;

TIM3->DIER |= TIM_DIER_CC1IE;

/*************************************************************************************************/

I want to receive the duty cycle and the period on every port, can you help me?

I am beginner on micro programming thanks for your help. =)

4 REPLIES 4
Posted on May 03, 2018 at 23:22

The 'PWM input' as described in the datasheet works on CH1 and CH2 only for each timer. And it's not a very useful mode (one other reason is, that the reset through slave mode may impose an undocumented delay which in turn results in incorrectly shorter measured period).

Also, CHxN pins can't be used as inputs.

You want to capture the time of both edges. To achieve that, route the signal from one input to two capture units and set them to different edge (that's the same as in the 'PWM mode', except that you don't set the slave controller to reset the timer). From successive times for one edge you'll read the period, from difference between times for the two eges you'll have the duty cycle. There are corner cases to be considered (e.g. for 0% and 100% duty), but those could be solved with a bit of thinking.

As one signal 'occupies' two capture units, you can handle only two signals per timer (if timing permits this at all).

Tell us more about your particular requirements.

JW

alexandre fortier
Associate
Posted on May 04, 2018 at 10:18

I have an electronic board which can received inputs on the ports PA4,PA6,PA7,PB0,PB1,PB10,PB11, PA8 a signal PWM.

 i need to get the period and the duty cycle (I can receive a PWM on any input)

 to launch my action.

I found in the datasheet of the micro an exemple that allow me to initialize my register to capture the period and the duty cycle on the ports PA8/9/5. I try to understand my exemple for use on the other ports but as you explained above it is not possible.

So I am looking for a solution to capture the period and the duty cycle on any ports.

I think I understood that all ports can not work with the same timer, for the example PA8/9 works with TIM1 CHA1 and CHA2 while PB4 works with TIM3 CHA1 so I don't understand why change the initialisation of the slave mode (TIMx_SMCR register) can solve my problem.

This is my first programming on micro so thank you very much for your help!

A.F

Posted on May 06, 2018 at 15:40

This is far from being trivial and certainly is not a beginner's task.

why change the initialisation of the slave mode (TIMx_SMCR register) can solve my problem.

It won't solve your problem. I just say, that you can use it only for CH1+CH2.

I meant, describe exactly what are the expected PWM input frequency and duty range, and if all the PWMs are needed to be detected at once, if they are synchronized in some way, and what's the expected precision of the detection. Also, what else should the mcu do (what do you mean by 'launch my action').

Honestly, unless the PWM is very slow compared to the mcu's system frequency, and the duty range is relatively far from 0 and 100 percent (i.e. there's enough time between the edges to read them out), and unless only a few of them are active at the same time, this may easily turn out to be an impossible task.

JW

henry.dick
Senior II
Posted on May 06, 2018 at 19:47

'

I tried to do the same on port PA4, PA6, PA7, PB0, PB1, PB10 and PB11, but it is not working at all.'

for hardware-based input capture, those pins should be supported by the hardware for it to work. 

just as your code shows correctly, the hardware approach works so far as the hardware supports it. 

once you understand how and why your code works, you understand why you code may not work on all pins.