Last active
April 24, 2018 14:38
-
-
Save NikiSchlifke/b532d345b71e13b1aab83920ecf191de to your computer and use it in GitHub Desktop.
Trying to get all 16 pwm outputs on a stm32f103rb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Trying to get all 16 pwm outputs on a stm32f103rb | |
*/ | |
#include <libopencm3/stm32/rcc.h> | |
#include <libopencm3/stm32/f1/gpio.h> | |
#include <libopencm3/stm32/f1/timer.h> | |
#define MOTOR1_PHASE_A1 GPIO8 // PA8 fixed | |
#define MOTOR1_PHASE_A2 GPIO9 // PA9 fixed | |
#define MOTOR1_PHASE_B1 GPIO10 // PA10 fixed | |
#define MOTOR1_PHASE_B2 GPIO11 // PA11 fixed | |
#define MOTOR2_PHASE_A1 GPIO0 // PA0 ok | |
#define MOTOR2_PHASE_A2 GPIO1 // PA1 ok | |
#define MOTOR2_PHASE_B1 GPIO2 // PA2 | |
#define MOTOR2_PHASE_B2 GPIO3 // PA3 | |
#define MOTOR3_PHASE_A1 GPIO6 // PC6 ok | |
#define MOTOR3_PHASE_A2 GPIO7 // PC7 ok | |
#define MOTOR3_PHASE_B1 GPIO8 // PC8 ok | |
#define MOTOR3_PHASE_B2 GPIO9 // PC9 ok | |
#define MOTOR4_PHASE_A1 GPIO6 // PB6 ok | |
#define MOTOR4_PHASE_A2 GPIO7 // PB7 ok | |
#define MOTOR4_PHASE_B1 GPIO8 // PB8 ok | |
#define MOTOR4_PHASE_B2 GPIO9 // PB9 ok | |
/** | |
* Helper function for setting PWM timers | |
* @param port_clken | |
* @param tim_clken | |
* @param timer_peripheral | |
* @param prescaler | |
* @param period | |
*/ | |
void pwm_init_timer(enum rcc_periph_clken port_clken, enum rcc_periph_clken tim_clken, uint32_t timer_peripheral, | |
uint32_t prescaler, | |
uint32_t period) { | |
rcc_periph_clock_enable(port_clken); | |
rcc_periph_clock_enable(tim_clken); | |
timer_reset(timer_peripheral); | |
timer_set_mode(timer_peripheral, | |
TIM_CR1_CKD_CK_INT, | |
TIM_CR1_CMS_EDGE, | |
TIM_CR1_DIR_UP); | |
timer_set_prescaler(timer_peripheral, prescaler); | |
timer_enable_preload(timer_peripheral); | |
timer_continuous_mode(timer_peripheral); | |
timer_set_period(timer_peripheral, period); | |
} | |
/** | |
* Helper function for setting PWM channels | |
* @param timer_peripheral | |
* @param gpio_reg | |
* @param gpio_en | |
* @param gpio_port | |
* @param gpio_pin | |
* @param cnf | |
*/ | |
void pwm_init_output_channel(uint32_t timer_peripheral, | |
uint32_t gpio_port, uint16_t gpio_pin, | |
uint8_t cnf) { | |
timer_generate_event(timer_peripheral, TIM_EGR_UG); | |
timer_enable_counter(timer_peripheral); | |
gpio_set_mode(gpio_port, GPIO_MODE_OUTPUT_50_MHZ, | |
cnf, | |
gpio_pin); | |
/* Enable all 4 peripherals*/ | |
timer_set_oc_mode(timer_peripheral, TIM_OC1, TIM_OCM_PWM1); | |
timer_enable_oc_output(timer_peripheral, TIM_OC1); | |
timer_set_oc_mode(timer_peripheral, TIM_OC2, TIM_OCM_PWM1); | |
timer_enable_oc_output(timer_peripheral, TIM_OC2); | |
timer_set_oc_mode(timer_peripheral, TIM_OC3, TIM_OCM_PWM1); | |
timer_enable_oc_output(timer_peripheral, TIM_OC3); | |
timer_set_oc_mode(timer_peripheral, TIM_OC4, TIM_OCM_PWM1); | |
timer_enable_oc_output(timer_peripheral, TIM_OC4); | |
} | |
void motor_setup(void) { | |
pwm_init_timer(RCC_GPIOA, RCC_TIM1, TIM1, 72, 2000); | |
pwm_init_timer(RCC_GPIOA, RCC_TIM2, TIM2, 72, 2000); | |
pwm_init_timer(RCC_GPIOC, RCC_TIM3, TIM3, 72, 2000); | |
pwm_init_timer(RCC_GPIOB, RCC_TIM4, TIM4, 72, 2000); | |
/* Set PWM motor output pins. */ | |
pwm_init_output_channel(TIM1, GPIOA, | |
MOTOR1_PHASE_A1 | MOTOR1_PHASE_A2 | MOTOR1_PHASE_B1 | MOTOR1_PHASE_B2, | |
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL); | |
pwm_init_output_channel(TIM2, GPIOA, | |
MOTOR2_PHASE_A1 | MOTOR2_PHASE_A2 | MOTOR2_PHASE_B1 | MOTOR2_PHASE_B2, | |
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL); | |
pwm_init_output_channel(TIM3, GPIOC, | |
MOTOR3_PHASE_A1 | MOTOR3_PHASE_A2 | MOTOR3_PHASE_B1 | MOTOR3_PHASE_B2, | |
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL); | |
pwm_init_output_channel(TIM4, GPIOB, | |
MOTOR4_PHASE_A1 | MOTOR4_PHASE_A2 | MOTOR4_PHASE_B1 | MOTOR4_PHASE_B2, | |
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL); | |
timer_set_oc_value(TIM1, TIM_OC1, 400); | |
timer_set_oc_value(TIM1, TIM_OC2, 500); | |
timer_set_oc_value(TIM1, TIM_OC3, 600); | |
timer_set_oc_value(TIM1, TIM_OC4, 700); | |
timer_set_oc_value(TIM2, TIM_OC1, 800); | |
timer_set_oc_value(TIM2, TIM_OC2, 900); | |
timer_set_oc_value(TIM2, TIM_OC3, 1000); | |
timer_set_oc_value(TIM2, TIM_OC4, 1100); | |
timer_set_oc_value(TIM3, TIM_OC1, 1200); | |
timer_set_oc_value(TIM3, TIM_OC2, 1300); | |
timer_set_oc_value(TIM3, TIM_OC3, 1400); | |
timer_set_oc_value(TIM3, TIM_OC4, 1500); | |
timer_set_oc_value(TIM4, TIM_OC1, 1600); | |
timer_set_oc_value(TIM4, TIM_OC2, 1700); | |
timer_set_oc_value(TIM4, TIM_OC3, 1800); | |
timer_set_oc_value(TIM4, TIM_OC4, 1900); | |
} | |
int main() { | |
rcc_clock_setup_in_hse_8mhz_out_72mhz(); | |
rcc_periph_clock_enable(RCC_AFIO); // Needed for remapping to work. | |
gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON, | |
AFIO_MAPR_TIM3_REMAP_FULL_REMAP | AFIO_MAPR_TIM2_REMAP_NO_REMAP | AFIO_MAPR_TIM1_REMAP_NO_REMAP); | |
motor_setup(); | |
timer_enable_break_main_output(TIM1); // Needed for TIM1 output | |
while (1) { | |
asm("NOP"); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment