2018-03-06 08:49 AM
Hello,
I have been using the STM32L1 Discovery Kit with the STM32L152RCT6 MCU.
A project that I am working on requires me to output two PWM signals. One of these is a 100KHz square wave and the other is 5MHz square wave.
I have gotten the 100KHz wave to work correctly, however I am unable to generate a 5MHz pwm from my board. I am using Timers 4 and 11 currently to generate these two signals and the code is as follows:
/* TIM3 init function */
static void MX_TIM3_Init(void){TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig; TIM_OC_InitTypeDef sConfigOC;htim3.Instance = TIM3;
htim3.Init.Prescaler = 2; htim3.Init.CounterMode = TIM_COUNTERMODE_UP; htim3.Init.Period = 2; htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; if (HAL_TIM_Base_Init(&htim3) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
{ _Error_Handler(__FILE__, __LINE__); }sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 1; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }HAL_TIM_MspPostInit(&htim3);
}
/* TIM4 init function */
static void MX_TIM4_Init(void){TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig; TIM_OC_InitTypeDef sConfigOC;htim4.Instance = TIM4;
htim4.Init.Prescaler = 106; htim4.Init.CounterMode = TIM_COUNTERMODE_UP; htim4.Init.Period = 2; htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; if (HAL_TIM_Base_Init(&htim4) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }if (HAL_TIM_PWM_Init(&htim4) != HAL_OK)
{ _Error_Handler(__FILE__, __LINE__); }sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 1; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }HAL_TIM_MspPostInit(&htim4);
}
/* TIM11 init function */
static void MX_TIM11_Init(void){TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_OC_InitTypeDef sConfigOC;htim11.Instance = TIM11;
htim11.Init.Prescaler = 2; htim11.Init.CounterMode = TIM_COUNTERMODE_UP; htim11.Init.Period = 2; htim11.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; if (HAL_TIM_Base_Init(&htim11) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim11, &sClockSourceConfig) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }if (HAL_TIM_PWM_Init(&htim11) != HAL_OK)
{ _Error_Handler(__FILE__, __LINE__); }sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 1; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_PWM_ConfigChannel(&htim11, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }HAL_TIM_MspPostInit(&htim11);
}
When I run my board with this code I find that the TIM4 correctly ouputs a 100KHz square wave with a peak to peak voltage of 3V. The TIM11 channel outputs an unclean square wave with a very low peak to peak voltage and only approx. a 3.5MHz signal. If I try to reduce the prescaler value to 1 in order to increase the frequency further, I lose the waveform completely. The results from the oscilliscope are show below:
TIM4 -
TIM11 -
Any help on getting the TIM11 pwm to be a clean square at 5MHz with 3V peak to peak would be greatly appreciated.
Thanks,
Arthur
#tim-pwm #stm32l152Solved! Go to Solution.
2018-03-06 02:36 PM
Set higher speed setting on given pin in GPIO.
How do you load that pin?
Also, check your oscilloscope probe rating.
If you need pwm if that kind of frequency, there is something serious wrong with your approach, usually.
Probably yes, but the waveform should be clean nonetheless.
JW
2018-03-06 09:50 AM
'
the other is 5MHz square wave. '
Let me give you a big secrete that I rarely share with anybody else.
If you need pwm if that kind of frequency, there is something serious wrong with your approach, usually.
If you really need something that fast, think about something other than a MCU.
2018-03-06 02:36 PM
Set higher speed setting on given pin in GPIO.
How do you load that pin?
Also, check your oscilloscope probe rating.
If you need pwm if that kind of frequency, there is something serious wrong with your approach, usually.
Probably yes, but the waveform should be clean nonetheless.
JW
2018-03-06 04:03 PM
5MHz PWM should be easy enough. but maybe not exactly 5.0MHz
Its child's play for the STM32 processors.
there will be no CPU overhead
Waclawek.Jan
is correct,check the PIN IO Speed.
check the ground probe on your scope.
check the pin loading.
Upto about 16MHz should be possible, however, since the process is ' divide the fixed frequency primary clock', only some frequency choices are available. 32Mhz/2, 32/3. 32/4 etc.
2018-03-06 04:04 PM
JW,
I used the CubeMX software to generate this script file. It allowed me to just select the timer that I wanted to use and I then specified the channel I desired and that allocated the pin on for me on the GUI. I then output the script file from this software.
I went back into the CubeMX software and saw that my pin for the timer output was set to a low speed so this may very well be the problem. I have now set it to a high speed and will test soon.
Thank you for your reply!
2018-03-06 06:38 PM
Posted on March 07, 2018 at 03:38
The pin problem - Use my program, you can generate any frequency, you wish. For second channel use another timer.
2018-03-06 07:56 PM
You aren't going to get 5 MHz by dividing down 32 MHz
Usually I'd suggest setting Prescaler = 0, and Period = N-1 where N is a integer.
For 5 MHz consider a 30 MHz CPU clock
30,000,000 / 100,000 = 300
Prescaler = 0, Period = 300-1
Pulse = 150
30,000,000 / 5,000,000 = 6
Prescaler = 0, Period = 6-1
Pulse = 3
2018-03-06 09:13 PM
5.1mhz stm32f103
HardwareTimer pwmtimer3(3);
void setup() {
pinMode(PA6, PWM); //5.1mhz pwmtimer3.pause(); pwmtimer3.setPrescaleFactor(1); pwmtimer3.setOverflow(14); pwmtimer3.setCompare(TIMER_CH1, 7); pwmtimer3.refresh(); pwmtimer3.resume();}2018-03-07 01:18 AM
I am using also CubeMX , for my stm32f103 I don't see anything about pin speed set up, there is a limitation , @ 5.1MHz has 10% less amplitude. If you need exactly 5MHz on your board you need to change crystal to 30MHz.
2018-03-07 07:38 AM
Ted,
If you look in the configuration section of CubeMX, under the Control tab click on the timer that you have set up in the GUI and navigate to the GPIO Settings tab, there is a maximum output speed setting which can be set from Very Low all the way to High.
I don't need precisely 5MHz so I think I should be ok.