2013-07-29 06:49 AM
help again, I work with a four-timer but it does not work the channels one, two and three. I initialize them but they do not give a PWM.
CH4 working very good!My code:void init_pwm( void){ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure2; TIM_OCInitTypeDef TIM_OCInitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE); GPIO_InitStructure. GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15; GPIO_InitStructure. GPIO_Mode = GPIO_Mode_AF ; GPIO_InitStructure. GPIO_Speed = GPIO_Speed_50MHz ; GPIO_InitStructure. GPIO_OType = GPIO_OType_PP ; GPIO_InitStructure. GPIO_PuPd = GPIO_PuPd_UP ; GPIO_Init(GPIOD, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_2); GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_2); GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_2); GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_2); TIM_TimeBaseStructure2. TIM_Period = 19999; TIM_TimeBaseStructure2. TIM_Prescaler = 72-1; TIM_TimeBaseStructure2. TIM_ClockDivision = 0; TIM_TimeBaseStructure2. TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure2); TIM_OCInitStructure. TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure. TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure. TIM_Pulse = START; TIM_OCInitStructure. TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM4, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Disable); TIM_OCInitStructure. TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure. TIM_Pulse = START; TIM_OC2Init(TIM4, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Disable); TIM_OCInitStructure. TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure. TIM_Pulse = START; TIM_OC3Init(TIM4, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Disable); TIM_OCInitStructure. TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure. TIM_Pulse = START; TIM_OC4Init(TIM4, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Disable); TIM_Cmd(TIM4, ENABLE);} #understand-your-tools2013-07-29 08:44 AM
May be you have other issues.
This works on all 4 channels for me// STM32 4-channel Servo Demo for 72 MHz STM32F3 Discovery - sourcer32@gmail.com
#include ''stm32f3_discovery.h''
/**************************************************************************************/
// Integers, or scaled integers (*10) will be more efficient here
volatile float servo_angle[4] = { 0.0, 0.0, 0.0, 0.0 }; // +/- 0 degrees
void TIM4_IRQHandler(void)
{
if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM4, 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
TIM_SetCompare1(TIM4, 1500 + (int)(servo_angle[0] * 0f) ); // PD.12
TIM_SetCompare2(TIM4, 1500 + (int)(servo_angle[1] * 0f) ); // PD.13
TIM_SetCompare3(TIM4, 1500 + (int)(servo_angle[2] * 0f) ); // PD.14
TIM_SetCompare4(TIM4, 1500 + (int)(servo_angle[3] * 0f) ); // PD.15
}
}
/**************************************************************************************/
void RCC_Configuration(void)
{
/* --------------------------- System Clocks Configuration -----------------*/
/* TIM4 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
/* GPIOD clock enable */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
}
/**************************************************************************************/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the TIM4 gloabal Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**************************************************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*-------------------------- GPIO Configuration ----------------------------*/
/* GPIOD Configuration: Pins 12, 13, 14 and 15 in output push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* Connect TIM4 pins to AF2 */
GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_2);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_2);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_2);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_2);
}
/**************************************************************************************/
void TIM4_Configuration(void)
{
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
/* Time base configuration - SystemCoreClock = 72000000 for 72 MHz board */
TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t) ((SystemCoreClock / 1000000) - 1); // Shooting for 1 MHz, (1us)
TIM_TimeBaseStructure.TIM_Period = 20000 - 1; // 1 MHz / 20000 = 50 Hz (20ms)
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
/* Enable TIM4 Preload register on ARR */
TIM_ARRPreloadConfig(TIM4, ENABLE);
/* TIM PWM1 Mode configuration: Channel */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 1500; // Servo Top-Center
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
/* Output Compare PWM1 Mode configuration: Channel1 PD.12 */
TIM_OC1Init(TIM4, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
/* Output Compare PWM1 Mode configuration: Channel2 PD.13 */
TIM_OC2Init(TIM4, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);
/* Output Compare PWM1 Mode configuration: Channel3 PD.14 */
TIM_OC3Init(TIM4, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);
/* Output Compare PWM1 Mode configuration: Channel4 PD.15 */
TIM_OC4Init(TIM4, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);
/* TIM Interrupts enable */
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
/* TIM4 enable counter */
TIM_Cmd(TIM4, ENABLE);
}
/**************************************************************************************/
int main(void)
{
RCC_Configuration();
GPIO_Configuration();
NVIC_Configuration();
TIM4_Configuration();
while(1)
{
// Add code to stroke servos here
}
}
2013-10-04 12:42 PM
Add code to demo motion
// STM32 4-channel Servo Demo for 72 MHz STM32F3 Discovery - sourcer32@gmail.com
#include ''stm32f3_discovery.h''
/**************************************************************************************/
// Integers, or scaled integers (*10) will be more efficient here
volatile float servo_angle[4] = { -0, -0, 0, 0 }; // +/- 0 degrees
#define SLEWRATE (1.0 / 0) // slew 1 degree per second, 50 Hz update
volatile float angle_delta[4] = { -SLEWRATE, -SLEWRATE, SLEWRATE, SLEWRATE };
void TIM4_IRQHandler(void)
{
if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
{
int i;
TIM_ClearITPendingBit(TIM4, 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
TIM_SetCompare1(TIM4, 1500 + (int)(servo_angle[0] * 0f) ); // PD.12
TIM_SetCompare2(TIM4, 1500 + (int)(servo_angle[1] * 0f) ); // PD.13
TIM_SetCompare3(TIM4, 1500 + (int)(servo_angle[2] * 0f) ); // PD.14
TIM_SetCompare4(TIM4, 1500 + (int)(servo_angle[3] * 0f) ); // PD.15
// a quick hack to get the servo to stroke back and forth
for(i=0; i<
4
; i++)
{
servo_angle[i] += angle_delta[i];
if ((servo_angle[i] >= 0f) || (servo_angle[i] <= -0f))
{
angle_delta[i] = -angle_delta[i]; // reverse
servo_angle[i] += angle_delta[i];
}
}
}
}
/**************************************************************************************/
void RCC_Configuration(void)
{
/* --------------------------- System Clocks Configuration -----------------*/
/* TIM4 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
/* GPIOD clock enable */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
}
/**************************************************************************************/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the TIM4 gloabal Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**************************************************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*-------------------------- GPIO Configuration ----------------------------*/
/* GPIOD Configuration: Pins 12, 13, 14 and 15 in output push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* Connect TIM4 pins to AF2 */
GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_2);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_2);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_2);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_2);
}
/**************************************************************************************/
void TIM4_Configuration(void)
{
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_OCStructInit(&TIM_OCInitStructure);
/* Time base configuration - SystemCoreClock = 72000000 for 72 MHz board */
TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t) ((SystemCoreClock / 1000000) - 1); // Shooting for 1 MHz, (1us)
TIM_TimeBaseStructure.TIM_Period = 20000 - 1; // 1 MHz / 20000 = 50 Hz (20ms)
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
/* Enable TIM4 Preload register on ARR */
TIM_ARRPreloadConfig(TIM4, ENABLE);
/* TIM PWM1 Mode configuration: Channel */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 1500; // Servo Top-Center
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
/* Output Compare PWM1 Mode configuration: Channel1 PD.12 */
TIM_OC1Init(TIM4, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
/* Output Compare PWM1 Mode configuration: Channel2 PD.13 */
TIM_OC2Init(TIM4, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);
/* Output Compare PWM1 Mode configuration: Channel3 PD.14 */
TIM_OC3Init(TIM4, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);
/* Output Compare PWM1 Mode configuration: Channel4 PD.15 */
TIM_OC4Init(TIM4, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);
/* TIM Interrupts enable */
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
/* TIM4 enable counter */
TIM_Cmd(TIM4, DISABLE /*ENABLE*/);
}
/**************************************************************************************/
int main(void)
{
RCC_Configuration();
GPIO_Configuration();
NVIC_Configuration();
TIM4_Configuration();
while(1); // Infinite Loop, work done under interrupt
}
2013-10-04 06:13 PM
Thanks but i am getting this error
Error[Li005]: no definition for ''SystemCoreClock'' [referenced from C:\Users\Mubin\Downloads\fromScratch\IAR\Debug\Obj\main.o]2013-10-04 06:26 PM
I'm not an IAR user, you will need to review the Template projects within the STM32F3-Discovery firmware library. Clone one of those and paste the example code into the ''main.c''component.
If you build a project from scratch you're going to have to specify the include paths for the libraries, the defines used for the board, and drop/add the library source files into the project. SystemCoreClock should be exported from system_stm32f3xx.c2013-10-04 06:31 PM
i fixed the systemcoreclock problem, but i am still at a dead end, still cant run my motor, thats what have been happening with my previous programs, i thought there must be something wrong with my code but i think its the hardware problem.
Any suggestions tho?2013-10-04 06:59 PM
I would start by evaluating the signal with a scope. Then using a common ground with the servo, and the control signal from the appropriate GPIO pin.
2013-10-04 07:08 PM
i am currently using the above program you wrote and using pin D14 i am driving the motor's pwm, the ground for the both motor and the board is common and the output at the programmed pins is a constant 2.94V.
I erased the program from the chip, took voltage readings and found that the pins used for the output are giving constant 2.94 V when programmed and a 1.5 V when there is no program in the memory.2013-10-04 07:25 PM
I'd probably use the debugger, and confirm the code is actually running. Perhaps you could also toggle an LED, or otherwise indicate that initialization has completed.