// // PWM Out: generate PWM waveform to control factory // #include "pwmout.h" // Private variables static TIM_HandleTypeDef htim17; static uint32_t last_ssr_on = 0; // Initialize hardware PWM output void pwmout_init(void) { GPIO_InitTypeDef GPIO_InitStruct; __HAL_RCC_TIM17_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); // Configure LED GPIO pins GPIO_InitStruct.Pin = SSR_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; //GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // GPIO_InitStruct.Alternate = GPIO_AF1_TIM17; HAL_GPIO_Init(SSR_GPIO_Port, &GPIO_InitStruct); TIM_OC_InitTypeDef sConfigOC; TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig; htim17.Instance = TIM17; htim17.Init.Prescaler = 6000; htim17.Init.CounterMode = TIM_COUNTERMODE_UP; htim17.Init.Period = 1000; htim17.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim17.Init.RepetitionCounter = 0; if (HAL_TIM_Base_Init(&htim17) != HAL_OK) { error_assert(ERR_PERIPHINIT); } if (HAL_TIM_OC_Init(&htim17) != HAL_OK) { error_assert(ERR_PERIPHINIT); } sConfigOC.OCMode = TIM_OCMODE_TOGGLE; //TIM_OCMODE_PWM1; sConfigOC.Pulse = 200; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCNPolarity = TIM_OCNPOLARITY_LOW; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET; sConfigOC.OCNIdleState = TIM_OCIDLESTATE_SET; if (HAL_TIM_OC_ConfigChannel(&htim17, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { error_assert(ERR_PERIPHINIT); } sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE; sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE; sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF; sBreakDeadTimeConfig.DeadTime = 0; sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE; sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH; sBreakDeadTimeConfig.BreakFilter = 0; sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE; if (HAL_TIMEx_ConfigBreakDeadTime(&htim17, &sBreakDeadTimeConfig) != HAL_OK) { error_assert(ERR_PERIPHINIT); } HAL_NVIC_SetPriority(TIM1_TRG_COM_TIM17_IRQn, 0, 0); HAL_NVIC_EnableIRQ(TIM1_TRG_COM_TIM17_IRQn); HAL_TIM_OC_Start_IT(&htim17, TIM_CHANNEL_1); __HAL_TIM_ENABLE_IT(&htim17, TIM_IT_UPDATE); } // freaking integral term isn't compatible with both heating and cooling... due to the discard // functionality. this is a problem. // also duty cycling isn't working correctly... void pwmout_process(int16_t duty) { if(duty == 0) { HAL_GPIO_WritePin(SSR, 0); HAL_GPIO_WritePin(LED, 0); } if(duty < 0) duty = 0; htim17.Instance->CCR1 = duty; //duty; } // Accessor for timer handle TIM_HandleTypeDef* pwmout_get_tim(void) { return &htim17; }