Spider999
Spider999

Reputation: 135

STM32F100 PWM with SPL setup

I am trying to figure out what I am doing wrong with my PWM setup on PC6 with my STM32F100 MCU, TIM3 Channel 1.

It is an old project with only one pin left that I am trying to expand a little bit.

My current setup is like this : #EDITED the TIM_SetCompare3(SERVO_TIM, 5000); to 50 as suggested below but no joy.

void SERVO_Init(void) 
{

    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure ;
    TIM_OCInitTypeDef TIM_OCInitStructure;

    RCC_APB1PeriphClockCmd(RCC_APBxPeriph_SERVO_PWM_TIM, 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 = 50;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

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

I know I need to setup this as an alternat function pinout but I can seem to get anything oput of the pin. In my main loop I have

TIM_SetCompare1(SERVO_TIM, 50);
}

Since I can not change the current code to HAL I am stuck with SPL sadly.

I have also found the following online but get plenty errors with this :

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_OCInitTypeDef  TIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;

/* GPIOA, GPIOB and GPIOE Clocks enable */
RCC_APB1PeriphClockCmd( RCC_APBxPeriph_SERVO_PWM_TIM, ENABLE);

// Set to Alt function
  GPIO_InitStructure.GPIO_Pin = SERVO_PWM_Pin;
  GPIO_InitStructure.GPIO_Mode = GPIO_MODE_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_FREQ_LOW;
  GPIO_InitStructure.OutputType = GPIO_OUTPUT_PUSHPULL;
  GPIO_Init(SERVO_PWM_GPIO_Port, &GPIO_InitStruct);

  GPIO_AF_EnableRemap_TIM3();

// setup timer scales
    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 = 5000;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

// enable settings
TIM_OC1Init(SERVO_TIM, &TIM_OCInitStructure);

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

Any suggestions would be of great help.

Upvotes: 0

Views: 155

Answers (2)

Spider999
Spider999

Reputation: 135

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.


#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 below did still help, thanks for all those that made the effort.

Upvotes: 0

Flexz
Flexz

Reputation: 706

Timer period is 100, yet OC pulse is set to 5000. Timer counter never reaches this value.

Call to TIM_SetCompare3(SERVO_TIM, 5000); will set pulse length on SERVO_TIM's channel 3. You've already set pulse length on channel 1 with TIM_OC1Init.

If you don't like SPL, then revert to the direct register programming. This way you'll get better understanding of the mcu.

Upvotes: 0

Related Questions