/* * inverter.c * * Created on: 25.10.2016 * Author: dehottgw */ #include #include #include #include "stm32f1xx_hal.h" #include "inverter.h" extern TIM_HandleTypeDef htim1; extern TIM_HandleTypeDef htim2; extern TIM_HandleTypeDef htim4; extern TIM_HandleTypeDef htim5; #define NUM_OF_SINE_SLOT 30 const uint32_t SLOT_WIDTH = 1500; const uint32_t FREQ_IN = 1E6; const float PI = 3.14159; uint16_t IV[NUM_OF_SINE_SLOT]; volatile uint32_t timer1Cnt; typedef struct { uint8_t slotCnt; bool running; GPIO_TypeDef *bridgePolarityPort; uint16_t bridgePolarityPin; GPIO_TypeDef *startMarkPort; uint16_t startMarkPin; IRQn_Type irqType; TIM_HandleTypeDef *handle; uint32_t channel; } timerSupport_t; #define NUM_OF_TIMER 3 volatile timerSupport_t timerSupport[NUM_OF_TIMER]; volatile uint8_t phaseOrder[NUM_OF_TIMER]; void inverterBegin() { for (uint8_t i = 0; i < NUM_OF_SINE_SLOT; i++) { float slotAngle = 180.0 / NUM_OF_SINE_SLOT; float angle = i * slotAngle; float sineValues = sinf(angle / 180 * PI); IV[i] = (uint16_t)(sineValues[i] * 0.9 * SLOT_WIDTH); } timerSupport[0].handle = &htim2; timerSupport[0].running = false; timerSupport[0].slotCnt = 0; timerSupport[0].bridgePolarityPort = BridgePolarity0_GPIO_Port; timerSupport[0].bridgePolarityPin = BridgePolarity0_Pin; timerSupport[0].irqType = TIM2_IRQn; timerSupport[0].channel = TIM_CHANNEL_1; timerSupport[0].startMarkPort = LED0_GPIO_Port; timerSupport[0].startMarkPin = LED0_Pin; __HAL_TIM_SET_AUTORELOAD(timerSupport[0].handle, SLOT_WIDTH); timerSupport[1].handle = &htim5; timerSupport[1].running = false; timerSupport[1].slotCnt = 0; timerSupport[1].bridgePolarityPort = BridgePolarity1_GPIO_Port; timerSupport[1].bridgePolarityPin = BridgePolarity1_Pin; timerSupport[1].irqType = TIM5_IRQn; timerSupport[1].channel = TIM_CHANNEL_2; timerSupport[1].startMarkPort = LED1_GPIO_Port; timerSupport[1].startMarkPin = LED1_Pin; __HAL_TIM_SET_AUTORELOAD(timerSupport[1].handle, SLOT_WIDTH); timerSupport[2].handle = &htim4; timerSupport[2].running = false; timerSupport[2].slotCnt = 0; timerSupport[2].bridgePolarityPort = BridgePolarity2_GPIO_Port; timerSupport[2].bridgePolarityPin = BridgePolarity2_Pin; timerSupport[2].irqType = TIM4_IRQn; timerSupport[2].channel = TIM_CHANNEL_1; timerSupport[2].startMarkPort = LED2_GPIO_Port; timerSupport[2].startMarkPin = LED2_Pin; __HAL_TIM_SET_AUTORELOAD(timerSupport[2].handle, SLOT_WIDTH); __HAL_TIM_SET_AUTORELOAD(&htim1, SLOT_WIDTH); } void inverterIncFrequency() { uint16_t currPsc = htim1->Instance->PSC; currPsc++; htim1->Instance->PSC = currPsc; for (uint8_t i = 0; i < NUM_OF_TIMER; i++) { timerSupport[i].handle->Instance->PSC = currPsc; } } void inverterDecFrequency() { uint16_t currPsc = htim1->Instance->PSC; currPsc--; htim1->Instance->PSC = currPsc; for (uint8_t i = 0; i < NUM_OF_TIMER; i++) { timerSupport[i].handle->Instance->PSC = currPsc; } } void inverterStart(direction_t direction) { inverterStop(); if (direction == CLOCKWISE) { phaseOrder[0] = 0; phaseOrder[1] = 1; phaseOrder[2] = 2; } else { phaseOrder[0] = 0; phaseOrder[1] = 2; phaseOrder[2] = 1; } for (uint8_t i = 0; i < NUM_OF_TIMER; i++){ timerSupport[i].slotCnt = 0; timerSupport[i].running = false; HAL_GPIO_WritePin(timerSupport[i].bridgePolarityPort, timerSupport[i].bridgePolarityPin, GPIO_PIN_RESET); __HAL_TIM_SET_COUNTER(timerSupport[i].handle, 0); } timer1Cnt = 0; __HAL_TIM_SET_COUNTER(&htim1, 0); HAL_TIM_Base_Start_IT(&htim1); __HAL_TIM_ENABLE_IT(&htim1, TIM_IT_UPDATE); } void inverterStop() { HAL_TIM_Base_Stop(&htim1); __HAL_TIM_DISABLE_IT(&htim1, TIM_IT_UPDATE); for (uint8_t i = 0; i < NUM_OF_TIMER; i++){ HAL_TIM_PWM_Stop_DMA(timerSupport[i].handle, timerSupport[i].channel); __HAL_TIM_DISABLE_IT(timerSupport[i].handle, TIM_IT_UPDATE); HAL_GPIO_WritePin(timerSupport[i].startMarkPort, timerSupport[i].startMarkPin, GPIO_PIN_RESET); } } static void startPhase(uint8_t phaseIdx) { uint8_t timerIdx = phaseOrder[phaseIdx]; if (! timerSupport[timerIdx].running) { HAL_GPIO_WritePin(timerSupport[timerIdx].startMarkPort, timerSupport[timerIdx].startMarkPin, GPIO_PIN_SET); HAL_TIM_PWM_Start_DMA(timerSupport[timerIdx].handle, timerSupport[timerIdx].channel, (uint32_t*)IV, NUM_OF_SINE_SLOT); __HAL_TIM_ENABLE_IT(timerSupport[timerIdx].handle, TIM_IT_UPDATE); timerSupport[timerIdx].running = true; } } void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { for (uint8_t i = 0; i < NUM_OF_TIMER; i++) { if (htim == timerSupport[i].handle) { timerSupport[i].slotCnt++; if (timerSupport[i].slotCnt == NUM_OF_SINE_SLOT + 2) { timerSupport[i].slotCnt = 2; HAL_GPIO_TogglePin(timerSupport[i].bridgePolarityPort, timerSupport[i].bridgePolarityPin); } } } if (htim == &htim1) { HAL_GPIO_TogglePin(Sync_GPIO_Port, Sync_Pin); if (timer1Cnt == 0) { startPhase(0); } else if (timer1Cnt == ((NUM_OF_SINE_SLOT * 2) / 3)) { startPhase(1); } else if (timer1Cnt == ((NUM_OF_SINE_SLOT * 2) * 2 / 3)) { startPhase(2); } timer1Cnt++; } }