2017-08-28 04:19 AM
Hey guys! I'm trying to write custom firmware for
http://www.st.com/en/motor-drivers/stspin32f0.html
and I'm desperately stuck:(
STSPIN32f0 is a system-in-package based on
STM32F031C6.
My code works fine on
STM32F031C6.
My code fails miserably both on my custom
STSPIN32f0 board and on
http://www.st.com/en/evaluation-tools/steval-spin3201.html
.What I'm trying to achieve is pretty simple: I configure TIM1 in 6-PWM mode. On
STM32F031C6 I can see 6 signals exactly as expected, on STSPIN32f0 I can see nothing.
Does anyone have experience with STSPIN32f0 please? Can anyone please give me any hint(s)? Can anyone please share their working code samples?
Solved! Go to Solution.
2017-08-31 12:57 AM
Hi,
I see two issues:
P.S. Even if the STSPIN32F0 embeds an actual STM32F031C6 microcontroller, you can find more experts about it in the 'Motor Control' forum of the Community
2017-08-28 04:22 AM
Just in case here is my code:
int main(void)
{ RCC->AHBENR |= RCC_AHBENR_GPIOAEN | // enable clock for GPIOA RCC_AHBENR_GPIOBEN; // enable clock for GPIOBRCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // enable timer 2
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // enable timer 1 TIM1->ARR = 0xA0; // tim1 period // over-current config (pin A-11) GPIOA->MODER |= (0x01 << GPIO_MODER_MODER11_Pos); // output GPIOA->OSPEEDR |= (0x01 << GPIO_OSPEEDR_OSPEEDR11_Pos); // medium speed GPIOA->PUPDR |= (0x01 << GPIO_PUPDR_PUPDR11_Pos); // pull-up GPIOA->ODR &= ~(1 << 11); // set zero//
TIM1->CCMR1 |= TIM_CCMR1_OC1PE | // Output compare on channel 1 preload enable (for pin B-13, low-side 1)
(0x06 << TIM_CCMR1_OC1M_Pos) | // Output compare on channel 1 mode = 110 (PWM mode 1) TIM_CCMR1_OC2PE | // Output compare on channel 2 preload enable (for pin B-14, low-side 2) (0x06 << TIM_CCMR1_OC2M_Pos); // Output compare on channel 2 mode = 110 (PWM mode 1) TIM1->CCMR2 |= TIM_CCMR2_OC3PE | // Output compare channel 3 preload enable (for pin A-10, high-side and pin B-15, low-side) (0x06 << TIM_CCMR2_OC3M_Pos); // Output compare 3 mode = 110 (PWM mode 1) GPIOA->MODER |= (0x02 << GPIO_MODER_MODER8_Pos) | // alternative function for pin A-8 (pwm channel 1, positive) (0x02 << GPIO_MODER_MODER9_Pos) | // alternative function for pin A-9 (pwm channel 2, positive) (0x02 << GPIO_MODER_MODER10_Pos); // alternative function for pin A-10 (pwm channel 3, positive) GPIOB->MODER |= (0x02 << GPIO_MODER_MODER13_Pos) | // alternate function for pin B-13 (PWM channel 1, negative) (0x02 << GPIO_MODER_MODER14_Pos) | // alternate function for pin B-14 (PWM channel 2, negative) (0x02 << GPIO_MODER_MODER15_Pos); // alternate function for pin B-15 (PWM channel 3, negative) GPIOA->OSPEEDR |= GPIO_OSPEEDR_OSPEEDR8 | // high speed for pin A-8 (pwm channel 1, positive) GPIO_OSPEEDR_OSPEEDR9 | // high speed for pin A-9 (pwm channel 2, positive) GPIO_OSPEEDR_OSPEEDR10; // high speed for pin A-10 (pwm channel 3, positive) GPIOB->OSPEEDR |= GPIO_OSPEEDR_OSPEEDR13 | // high speed for pin B-13 (pwm channel 1, negative) GPIO_OSPEEDR_OSPEEDR14 | // high speed for pin B-14 (pwm channel 2, negative) GPIO_OSPEEDR_OSPEEDR15; // high speed for pin B-15 (pwm channel 3, negative) GPIOA->AFR[1] |= (0x02 << GPIO_AFRH_AFSEL8_Pos) | // for pin A-8 alternative funciton 2 (0x02 << GPIO_AFRH_AFSEL9_Pos) | // for pin A-9 alternative funciton 2 (0x02 << GPIO_AFRH_AFSEL10_Pos); // for pin A-10 alternative funciton 2 GPIOB->AFR[1] |= (0x02 << GPIO_AFRH_AFSEL13_Pos) | // for pin B-13 alternative funciton 2 (0x02 << GPIO_AFRH_AFSEL14_Pos) | // for pin B-14 alternative funciton 2 (0x02 << GPIO_AFRH_AFSEL15_Pos); // for pin B-15 alternative funciton 2TIM1->CCR3 = 0xA; // duty cycle of tim1 channel 3
TIM1->CCR2 = 0xA; // duty cycle of tim1 channel 2 TIM1->CCR1 = 0xA; // duty cycle of tim1 channel 1 TIM1->CR1 |= (0x01 << TIM_CR1_CMS_Pos); // centre-aligned mode 1 - up&down TIM1->RCR = 0x3; // repetition counter TIM1->BDTR |= TIM_BDTR_MOE | // main output enable TIM_BDTR_OSSR | // Off-state selection for Run mode TIM_BDTR_OSSI | // Off-state selection for Idle mode 0x02; // 2-count dead-time TIM1->CR1 |= TIM_AUTORELOAD_PRELOAD_ENABLE; // enable timer 1 preloadTIM1->CCER |= TIM_CCER_CC1E | // enable channel 1, positive
TIM_CCER_CC2E | // enable channel 2, positive TIM_CCER_CC3E | // enable channel 3, positive TIM_CCER_CC1NE | // enable channel 1, negative TIM_CCER_CC2NE | // enable channel 2, negative TIM_CCER_CC3NE; // enable channel 3, negativeTIM1->EGR |= TIM_EGR_UG; // force update event
TIM1->CR1 |= TIM_CR1_CEN; // enable timer 1 while (1) { }}2017-08-31 12:57 AM
Hi,
I see two issues:
P.S. Even if the STSPIN32F0 embeds an actual STM32F031C6 microcontroller, you can find more experts about it in the 'Motor Control' forum of the Community
2017-09-01 06:28 AM
Enrico, thank you very much! Your answer helped me to fix the problem. Here is my version that confirmed to work. It has 1uS dead-time.
void initPwm()
{ RCC->AHBENR |= RCC_AHBENR_GPIOAEN | // enable clock for GPIOA RCC_AHBENR_GPIOBEN | // enable clock for GPIOB RCC_AHBENR_GPIOFEN; // enable clock for GPIOFRCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // enable timer 1
TIM1->ARR = 0xA00; // tim1 period// tim1 config channel
TIM1->CCMR1 |= TIM_CCMR1_OC1PE | // Output compare on channel 1 preload enable (for pin B-13, low-side 1)
(0x06 << TIM_CCMR1_OC1M_Pos) | // Output compare on channel 1 mode = 110 (PWM mode 1) TIM_CCMR1_OC2PE | // Output compare on channel 2 preload enable (for pin B-14, low-side 2) (0x06 << TIM_CCMR1_OC2M_Pos); // Output compare on channel 2 mode = 110 (PWM mode 1) TIM1->CCMR2 |= TIM_CCMR2_OC3PE | // Output compare channel 3 preload enable (for pin A-10, high-side and pin B-15, low-side) (0x06 << TIM_CCMR2_OC3M_Pos); // Output compare 3 mode = 110 (PWM mode 1) // GPIOA GPIOA->MODER |= (0x02 << GPIO_MODER_MODER8_Pos) | // alternative function for pin A-8 (pwm channel 1, positive) (0x02 << GPIO_MODER_MODER9_Pos) | // alternative function for pin A-9 (pwm channel 2, positive) (0x02 << GPIO_MODER_MODER10_Pos) | // alternative function for pin A-10 (pwm channel 3, positive) (0x01 << GPIO_MODER_MODER11_Pos); // output for pin A-11 (overcurrent control) GPIOA->OSPEEDR |= GPIO_OSPEEDR_OSPEEDR8 | // high speed for pin A-8 (pwm channel 1, positive) GPIO_OSPEEDR_OSPEEDR9 | // high speed for pin A-9 (pwm channel 2, positive) GPIO_OSPEEDR_OSPEEDR10 | // high speed for pin A-10 (pwm channel 3, positive) (0x01 << GPIO_OSPEEDR_OSPEEDR11_Pos); // medium speed for pin A-11 (overcurrent control) GPIOA->AFR[1] |= (0x02 << GPIO_AFRH_AFSEL8_Pos) | // for pin A-8 alternative funciton 2 (0x02 << GPIO_AFRH_AFSEL9_Pos) | // for pin A-9 alternative funciton 2 (0x02 << GPIO_AFRH_AFSEL10_Pos); // for pin A-10 alternative funciton 2 GPIOA->PUPDR |= (0x01 << GPIO_PUPDR_PUPDR11_Pos); // pull-up for pin A-11 (overcurrent control) // GPIOB GPIOB->MODER |= (0x02 << GPIO_MODER_MODER13_Pos) | // alternate function for pin B-13 (PWM channel 1, negative) (0x02 << GPIO_MODER_MODER14_Pos) | // alternate function for pin B-14 (PWM channel 2, negative) (0x02 << GPIO_MODER_MODER15_Pos); // alternate function for pin B-15 (PWM channel 3, negative) GPIOB->OSPEEDR |= GPIO_OSPEEDR_OSPEEDR13 | // high speed for pin B-13 (pwm channel 1, negative) GPIO_OSPEEDR_OSPEEDR14 | // high speed for pin B-14 (pwm channel 2, negative) GPIO_OSPEEDR_OSPEEDR15; // high speed for pin B-15 (pwm channel 3, negative) GPIOB->AFR[1] |= (0x02 << GPIO_AFRH_AFSEL13_Pos) | // for pin B-13 alternative funciton 2 (0x02 << GPIO_AFRH_AFSEL14_Pos) | // for pin B-14 alternative funciton 2 (0x02 << GPIO_AFRH_AFSEL15_Pos); // for pin B-15 alternative funciton 2// GPIOF
GPIOF->MODER |= (0x01 << GPIO_MODER_MODER6_Pos) | // output mode for pin F-6 (standby mode) (0x01 << GPIO_MODER_MODER7_Pos); // output mode for pin F-7 (standby mode) GPIOF->PUPDR |= (0x01 << GPIO_PUPDR_PUPDR6_Pos) | // pull-up for pin F-6 (0x01 << GPIO_PUPDR_PUPDR7_Pos); // pull-up for pin F-7 // over-current config (pin A-11)GPIOA->BRR = (1 << 11); // reset pin 11 (overcurrent does not effect gate driver directly)
GPIOF->BSRR = (1 << 7); // disable stand-by mode TIM1->CCR3 = 0x800; // duty cycle of tim1 channel 3 TIM1->CCR2 = 0x400; // duty cycle of tim1 channel 2 TIM1->CCR1 = 0x600; // duty cycle of tim1 channel 1 TIM1->CR1 |= (0x01 << TIM_CR1_CMS_Pos); // center-aligned mode 1 - up&down TIM1->RCR = 0x3; //repetition counter TIM1->BDTR |= TIM_BDTR_MOE | // main output enable TIM_BDTR_OSSR | // Off-state selection for Run mode TIM_BDTR_OSSI | // Off-state selection for Idle mode 0x08; // 1uS dead-time TIM1->CR1 |= TIM_AUTORELOAD_PRELOAD_ENABLE; // enable timer 1 TIM1->CCER |= TIM_CCER_CC1E | // enable channel1, positive TIM_CCER_CC2E | // enable channel2, positive TIM_CCER_CC3E | // enable channel3, positive TIM_CCER_CC1NE | // enable channel 1, negative TIM_CCER_CC2NE | // enable channel 2, negative TIM_CCER_CC3NE; // enable channel 3, negativeTIM1->CR1 |= TIM_CR1_CEN; // enable timer 1
}