2024-02-12 11:29 PM - last edited on 2024-02-13 12:09 AM by Peter BENSCH
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 :
Solved! Go to Solution.
2024-02-20 04:16 PM
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.
2024-02-13 12:07 AM - edited 2024-02-13 12:08 AM
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
2024-02-13 08:40 AM
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
2024-02-13 01:37 PM - edited 2024-02-13 01:44 PM
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.
2024-02-13 01:49 PM - edited 2024-02-13 01:49 PM
I tried decreasing my Scope time to 1uS and found nothing there.
2024-02-13 08:16 PM
> 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
2024-02-20 04:16 PM
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.