cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F100 PWM signal on PC6, setup question

TDuck.1
Associate II

Hi

Firstly, sadly I can not change to HAL as I don't have time to port this all across right now for this project dealine.

I am trying to setup a PWM signal on PC6 on the STM32F100, I am pretty sure I need to set it as an alternat function but I have no idea how to do this or if I even need to.

I can get another PWM signal to work on PB0 with the same setup but PC6 does not give me any output.

Just checking but PC6 is TIM3 and channel 1 right ? I am starting to doubt myself on everything right now.

 

Any ideas would be of great help.

 

Currently my setup is as follows :

 

void SERVO_Init(void)
{

    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure ;
    TIM_OCInitTypeDef TIM_OCInitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
   
    /* configure Projector fan PWM timer */
    TIM_TimeBaseStructure.TIM_Prescaler = 65535;    /* 24 MHz divided by this gives pwm input clock */
    TIM_TimeBaseStructure.TIM_Period = 100-1; /* 100 0..99     */
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 1;
    TIM_TimeBaseInit(SERVO_TIM, &TIM_TimeBaseStructure);

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = 0;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

    TIM_OC1Init(TIM3, &TIM_OCInitStructure);
   
    /* turning on TIM PWM output */
    TIM_Cmd(TIM3, ENABLE);
    TIM_CtrlPWMOutputs(TIM3, ENABLE);

    TIM_SetCompare1(TIM3, 50);
}
 
 
1 ACCEPTED SOLUTION

Accepted Solutions

Hi

So you had a great point there and it was part of the solution for me, I knew it was connected by as you said toggeling the pin manually and seeing the expected output.

So after a while a colleague found an old snippet of code that he had working years ago.

Long and short of it is that I had the Remap function in the wrong place and I had a PWM on TIM3 channel 3 ( PB0 ) this one does not play nicely with TIM3 channel 1 on PC6 so I had to get rid of the PWM on PB0, lucky my project could work with that and I'll just bit bang the signal I need later.

Here is the setup I ended up using for anyone who needs help with this, it is in unsupported Standard Peripheral libraries so can be ifficult to get help.

Also another problem I had was I thought I could use PC4 with TIM12 but my package was not a high density device and so this was not supported, not the end of the world for me, but future people might want to know that bit too.

 

#define SERVO_PWM_GPIO_Port GPIOC
#define SERVO_PWM_Pin       GPIO_Pin_6
#define SERVO_TIM TIM3
#define RCC_APBxPeriph_SERVO_ENABLE_TIM     RCC_APB1Periph_TIM3


void SERVO_Init(void) {

    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = (SERVO_PWM_Pin);
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure ;
    TIM_OCInitTypeDef TIM_OCInitStructure;

    RCC_APB1PeriphClockCmd(RCC_APBxPeriph_SERVO_ENABLE_TIM, ENABLE);

    /* configure UV LED PWM timer */
    TIM_TimeBaseStructure.TIM_Prescaler = 24-1;    /* 24 MHz divided by this gives pwm input clock */
    TIM_TimeBaseStructure.TIM_Period = 10000-1; /* 10000 0..9999     */
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 1;
    TIM_TimeBaseInit(SERVO_TIM, &TIM_TimeBaseStructure);

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = 0;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

    TIM_OC1Init(SERVO_TIM, &TIM_OCInitStructure); /* uv led pwm */

    /* turning on UV_LED_TIM PWM output */
    TIM_Cmd(SERVO_TIM, ENABLE);
    TIM_CtrlPWMOutputs(SERVO_TIM, ENABLE);

// Turn off the PWR to the SERVO
GPIO_SetBits(SERVO_ENABLE_GPIO_Port, SERVO_ENABLE_Pin);
// GPIO_SetBits(SERVO_PWM_GPIO_Port, SERVO_PWM_Pin);

GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE);

}

 

This final line Remapping the TIM3 was important and one that I did not have in the correct place before this.

The PWM signal is set with :

TIM_SetCompare1(SERVO_TIM, valueWanted); // between 9999 and 0 in this setup.

 All the comments and answers did still help me keep my sanity, thanks for all those that made the effort.

View solution in original post

6 REPLIES 6
Peter BENSCH
ST Employee

The SPL snippet actually looks OK. Should actually result in a signal with 1% duty cycle and 24MHz/(65535+1) = ~366Hz, the pulse should be 27.3µs long.

Regards
/Peter

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Which STM32F100, exactly?

For TIM3_CH1 to be on PC6, you need to set TIM3_REMAP[1:0] =“11” (full remap) in the AFIO_MAPR register, see AFIO chapter in RM.

JW

I am using the STM32F100RBT6B.

When I try including:

TIM3_REMAP[1:0] =“11”

As page 119 , table 35 says for TIM3 I get an error of undeclaired function, could this be because they are not in my supported libs ?

 

But when I use the registers I get it to compile:

AFIO->MAPR |= 0x00000C00;// remap tim3

Yet it still gives me no output.

 

Also would doing this effect other Pins on the port ?

I am using them as general IOs so nothing fancy.

 

Thanks for the input.

I tried decreasing my Scope time to 1uS and found nothing there.

> Also would doing this effect other Pins on the port ?

The ancient 'F1 GPIO can be a surface of of nasty surprise, but if you don't enable other channels of the same timer (and if there's no related erratum) then probably not.

Check if pin is properly connected (soldered) by seeing it as GPIO output and toggling it manually.

Read out and check/post content of TIM and relevant GPIO/AFIO registers.

JW

Hi

So you had a great point there and it was part of the solution for me, I knew it was connected by as you said toggeling the pin manually and seeing the expected output.

So after a while a colleague found an old snippet of code that he had working years ago.

Long and short of it is that I had the Remap function in the wrong place and I had a PWM on TIM3 channel 3 ( PB0 ) this one does not play nicely with TIM3 channel 1 on PC6 so I had to get rid of the PWM on PB0, lucky my project could work with that and I'll just bit bang the signal I need later.

Here is the setup I ended up using for anyone who needs help with this, it is in unsupported Standard Peripheral libraries so can be ifficult to get help.

Also another problem I had was I thought I could use PC4 with TIM12 but my package was not a high density device and so this was not supported, not the end of the world for me, but future people might want to know that bit too.

 

#define SERVO_PWM_GPIO_Port GPIOC
#define SERVO_PWM_Pin       GPIO_Pin_6
#define SERVO_TIM TIM3
#define RCC_APBxPeriph_SERVO_ENABLE_TIM     RCC_APB1Periph_TIM3


void SERVO_Init(void) {

    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = (SERVO_PWM_Pin);
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure ;
    TIM_OCInitTypeDef TIM_OCInitStructure;

    RCC_APB1PeriphClockCmd(RCC_APBxPeriph_SERVO_ENABLE_TIM, ENABLE);

    /* configure UV LED PWM timer */
    TIM_TimeBaseStructure.TIM_Prescaler = 24-1;    /* 24 MHz divided by this gives pwm input clock */
    TIM_TimeBaseStructure.TIM_Period = 10000-1; /* 10000 0..9999     */
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 1;
    TIM_TimeBaseInit(SERVO_TIM, &TIM_TimeBaseStructure);

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = 0;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

    TIM_OC1Init(SERVO_TIM, &TIM_OCInitStructure); /* uv led pwm */

    /* turning on UV_LED_TIM PWM output */
    TIM_Cmd(SERVO_TIM, ENABLE);
    TIM_CtrlPWMOutputs(SERVO_TIM, ENABLE);

// Turn off the PWR to the SERVO
GPIO_SetBits(SERVO_ENABLE_GPIO_Port, SERVO_ENABLE_Pin);
// GPIO_SetBits(SERVO_PWM_GPIO_Port, SERVO_PWM_Pin);

GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE);

}

 

This final line Remapping the TIM3 was important and one that I did not have in the correct place before this.

The PWM signal is set with :

TIM_SetCompare1(SERVO_TIM, valueWanted); // between 9999 and 0 in this setup.

 All the comments and answers did still help me keep my sanity, thanks for all those that made the effort.