stm32stm32f1

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.


Solution

  • 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.