cancel
Showing results for 
Search instead for 
Did you mean: 

How to use timers for generating signals?

dvoraj45
Associate
Posted on June 05, 2014 at 14:46

Hello, I am very new in STM32F103 CPU and I need to make very simple program. I need to generate PWM signal with definned on-time and off-time.

The on-time must be in range from 1us to 1000us, step is 1 us. The same with off-time.

I tried to use PWM from examples, but no success in this range. Can you help me what conception should I use? I will enter the values by UART, it must allow change of the on- and off-times during the operation.

Thank you

Jan

#stm32f #timers #input #pwm
4 REPLIES 4
Posted on June 05, 2014 at 16:08

This is NOT a ''very simple'' program.

Homework?

Start with something simple, e.g. blinking a LED in a simple loop, timed with a loop delay. The try to run some of the timers, observe it running in the debugger. The try to add the PWM function. Then start up the USART, simply echoing back the received character first, or observing received character in the debugger. Then add everything up.

What's your hardware?

JW

dvoraj45
Associate
Posted on June 05, 2014 at 16:12

Hello,

no homework, it should be a testing tool for C-axis encoder. I can use USART, everythink work, but I have never used timers periphery.

Posted on June 05, 2014 at 16:43

- select a timer (x) and a channel in it (y)

- enable timer clock in RCC

- set up pin to output some of the timer's channel (GPIO, AFIO if needed)

- set ARR register of timer to the desired period, optionally set also the prescaler (PSC)

- select channel 4 as compare (CCyS bits in the respective CCMR register)

- select PWM1 or PWM2 mode (CCyM bits in the respective CCMR register)

- enable output by setting CCyE bit in CCER register

- if timer is 1 or 8, also need to set MOE in BDTR

- enable timer by setting CEN bit in CR1

- changing value in CCRy the pulse width changes

JW
Posted on June 05, 2014 at 17:49

Here's the STM32 VL-Discovery (STM32F1 series) PWM code I built to demonstrate Servo control. It has a 50 Hz signal, with a pulse control at 1us

// STM32 4-channel Servo Demo for 24 MHz VL Discovery - sourcer32@gmail.com
#include ''stm32F10x.h''
#include ''STM32vldiscovery.h''
/**************************************************************************************/
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void TIM3_Configuration(void);
/**************************************************************************************/
volatile int servo_angle[4] = { 0, 0, 0, 0 }; // +/- 90 degrees, use floats for fractional
void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
// minimum high of 600 us for -90 degrees, with +90 degrees at 2400 us, 10 us per degree
// timer timebase set to us units to simplify the configuration/math
TIM3->CCR1 = 600 + ((servo_angle[0] + 90) * 10); // where angle is an int -90 to +90 degrees, PC.6
TIM3->CCR2 = 600 + ((servo_angle[1] + 90) * 10); // where angle is an int -90 to +90 degrees, PC.7
TIM3->CCR3 = 600 + ((servo_angle[2] + 90) * 10); // where angle is an int -90 to +90 degrees, PC.8
TIM3->CCR4 = 600 + ((servo_angle[3] + 90) * 10); // where angle is an int -90 to +90 degrees, PC.9
}
}
/**************************************************************************************/
int main(void)
{
RCC_Configuration();
GPIO_Configuration();
NVIC_Configuration();
TIM3_Configuration();
while(1)
{
// Insert code here to stroke your servos
}
}
/**************************************************************************************/
void RCC_Configuration(void)
{
// clock for GPIO and AFIO (Remap)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
// clock for TIM3
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
}
/**************************************************************************************/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure the NVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
/* Enable the TIM3 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**************************************************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
// PC.06 TIM3_CH1
// PC.07 TIM3_CH2
// PC.08 TIM3_CH3
// PC.09 TIM3_CH4
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE); // Remap to get signal on PC.06-09
}
/**************************************************************************************/
void TIM3_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
// Simplify the math here so TIM_Pulse has 1 us units
// Use (24-1) for VL @ 24 MHz
// Use (72-1) for STM32 @ 72 MHz
TIM_TimeBaseStructure.TIM_Prescaler = 24 - 1; // 24 MHz / 24 = 1 MHz
TIM_TimeBaseStructure.TIM_Period = 20000 - 1; // 1 MHz / 20000 = 50 Hz (20 ms)
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
// Set up 4 channel servo
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 600 + 900; // 1500 us - Servo Top Centre
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM3, &TIM_OCInitStructure); // Channel 1 configuration = PC.06 TIM3_CH1
TIM_OC2Init(TIM3, &TIM_OCInitStructure); // Channel 2 configuration = PC.07 TIM3_CH2
TIM_OC3Init(TIM3, &TIM_OCInitStructure); // Channel 3 configuration = PC.08 TIM3_CH3
TIM_OC4Init(TIM3, &TIM_OCInitStructure); // Channel 4 configuration = PC.09 TIM3_CH4
// turning on TIM3 and PWM outputs
TIM_Cmd(TIM3, ENABLE);
TIM_CtrlPWMOutputs(TIM3, ENABLE);
// TIM IT enable
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..