2013-09-01 04:42 PM
The code above is part of a library to control 2 stepper motor for STM32F4. I pretend to use it with STM32F1.
1- Lines 43 to 46 configure the GPIO to Outupo with PushPull, the two lines that I added and commented are the equivalent for STM32F1? 2-Usually when programming to STM32F1 I define the GPIO to AF when want to use a timer channel on it. In that case the author configure the channels starting at line 99 but in the GPIO configuration he doesn't tell to use the AF. Is it normal in STM32F4? I already contacted the author too but if you can help me. Thanks :)
/*=============================================================================
@file stm32f_stpdrv.c
@author Paulo de Almeida
@version V1.3.0
@date 02/08/2013
@brief Stepper Driver for STM32F family
This Software is released under no garanty.
You may use this software for personal use.
Use for commercial and/or profit applications is strictly prohibited.
If you change this code, please send an email to the author.
COPYRIGHT (C) 2013 Paulo de Almeida
Contact the author at: pa@astrosite.net
Atention: This header MUST NOT BE REMOVED
Compiled under C99 (ISO/IEC 9899:1999) version
please use the ''--c99'' compiler directive
Description and Usage: See stm32f_stpdrv.h
==============================================================================*/
void
STPDRV_Init(
void
)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
SystemCoreClockUpdate();
//----- GPIO AHB1Periph clock enable
RCC_AHB1PeriphClockCmd(__GPIO2AHB1Periph(MOTOR1_STEP_PORT) , ENABLE);
RCC_AHB1PeriphClockCmd(__GPIO2AHB1Periph(MOTOR1_DIR_PORT) , ENABLE);
RCC_AHB1PeriphClockCmd(__GPIO2AHB1Periph(MOTOR2_STEP_PORT) , ENABLE);
RCC_AHB1PeriphClockCmd(__GPIO2AHB1Periph(MOTOR2_DIR_PORT) , ENABLE);
// GPIO Configuration - Step PINs & DIR PINs
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = MOTOR1_STEP_PIN;
GPIO_Init(MOTOR1_STEP_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = MOTOR1_DIR_PIN;
GPIO_Init(MOTOR1_DIR_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = MOTOR2_STEP_PIN;
GPIO_Init(MOTOR2_STEP_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = MOTOR2_DIR_PIN;
GPIO_Init(MOTOR2_DIR_PORT, &GPIO_InitStructure);
//----- API struc INIT (after GPIO init)
Motors[0].CurDelay = 0xffff;
__ResetTargetSpeed(0);
__MotorSetDir(0, dir_CW);
STPDRV_SetRamp(0, 4);
Motors[1].CurDelay = 0xffff;
__MotorSetDir(1, dir_CW);
__ResetTargetSpeed(1);
STPDRV_SetRamp(1, 4);
//----- TIM Periph clock enable
RCC_APB1PeriphClockCmd(STPDRV_TIM_APB , ENABLE);
//--- TIMx Configuration: Output Compare Timing Mode -----------------------
// TIM3 input clock (TIM3CLK) is set to 2 * APB1 clock (PCLK1), since APB1 prescaler is different from 1.
// TIM3CLK = 2 * PCLK1
// PCLK1 = HCLK / 4
// => TIM3CLK = 2 * (HCLK / 4) = HCLK / 2 = SystemCoreClock / 2
//
// Para um ''TIMx counter clock'' de 100KHz (exemplo com resolução de 10uS) o ''Prescaler'' deve ser calculado assim:
// Prescaler = (uint16_t) (TIMxCLK / 100000) - 1;
//
// O ''Period'' neste caso não interessa pois a IRQ (TIMx_IRQHandler) dos CCR (capture/compare register) controla o
// togles dos estados HiGH e LOW dos PINs do STEP
//
// A resolução do sistema é definida em ''stm32f_stpdrv.h'' no define STPDRV_TIMFREQ
//
TIM_TimeBaseStructure.TIM_Period = 65535;
TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t) ((SystemCoreClock / 2) / (STPDRV_TIMFREQ * 2)) - 1;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0000;
TIM_TimeBaseInit(STPDRV_TIM, &TIM_TimeBaseStructure);
TIM_UpdateDisableConfig(STPDRV_TIM, ENABLE);
// deve ser ENABLE pois para desactiver o Update Event o bit deve ser 1
/* Prescaler configuration */
//TIM_PrescalerConfig(STPDRV_TIM, PrescalerValue, TIM_PSCReloadMode_Immediate);
// Output Compare Toggle Mode configuration: All Channels
TIM_OCStructInit(&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;
//TIM_OCMode_Toggle
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
// Disable por defeito, API liga quando necessario
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
// Output Compare Toggle Mode configuration: Channel1 - MOTOR 1
TIM_OC1Init(STPDRV_TIM, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(STPDRV_TIM, TIM_OCPreload_Disable);
// Output Compare Toggle Mode configuration: Channel2 - MOTOR 2
TIM_OC2Init(STPDRV_TIM, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(STPDRV_TIM, TIM_OCPreload_Disable);
// Output Compare Toggle Mode configuration: Channel3 - MOTOR 1 ACELL e DECEL
TIM_OC3Init(STPDRV_TIM, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(STPDRV_TIM, TIM_OCPreload_Disable);
// Output Compare Toggle Mode configuration: Channel4 - MOTOR 2 ACELL e DECEL
TIM_OC4Init(STPDRV_TIM, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(STPDRV_TIM, TIM_OCPreload_Disable);
// Enable the TIM gloabal Interrupt
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
// USER EDIT - Mudar o nome do IRQ se o TIMER for alterado
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = IRQ_STPDRV_PrePriority;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = IRQ_STPDRV_Priority;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// TIM INT enable
// A interrupt é activada na função Motor_On()
//TIM_ITConfig(STPDRV_TIM, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE);
// TIM enable counter
TIM_Cmd(STPDRV_TIM, ENABLE);
}
2013-09-27 09:13 AM
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.