/* * @Author: mypx * @Date: 2025-10-15 13:03:38 * @LastEditTime: 2025-10-17 13:37:16 * @LastEditors: mypx mypx_coder@163.com * @Description: */ #include "bsp_tec.h" #include "main.h" #include "spi.h" #include "tim.h" /* * 当前板子存在的问题: * PE8-TEC-IN1(left) TIM1_CH1N默认为PE8 * PA8-TEC-IN2(right) TIM1_CH1默认为PA9,需要映射到PA8 * 问题: * 映射只能成对映射,也就是PE8也要做映射,所以一次配置,同时使能两个管脚做不到 * 解决方法: * 1. 分别配置PE8和PA8为TIM1_CH1N和TIM1_CH1 * 2. 分别使能PE8和PA8的TIM1_CH1N和TIM1_CH1 * stm32cubemx 使能TIM1_CH1N和TIM1_CH1默认的管脚为REMAP后的管脚,感觉是bug * */ static void stop_tec_pwm(void) { // 一块关闭,避免左右搞混没关掉 HAL_TIM_PWM_Stop(&TEC_TIM, TIM_CHANNEL_1); HAL_TIMEx_PWMN_Stop(&TEC_TIM, TIM_CHANNEL_1); } static void tec_sd_disable(void) { HAL_GPIO_WritePin(GPIOA, TEC_LEFT_SD_Pin | TEC_RIGHT_SD_Pin, GPIO_PIN_RESET); } static void left_tec_sd_enable(void) { HAL_GPIO_WritePin(GPIOA, TEC_LEFT_SD_Pin, GPIO_PIN_SET); } static void right_tec_sd_enable(void) { HAL_GPIO_WritePin(GPIOA, TEC_RIGHT_SD_Pin, GPIO_PIN_SET); } // PE8-TEC-IN1(left) TIM1_CH1N, 需要做full remap static void left_tec_reconfig_pwm(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* Stop PWM outputs first to avoid both outputs being active during transition */ stop_tec_pwm(); /* Ensure GPIO clocks */ __HAL_RCC_GPIOE_CLK_ENABLE(); /* Enable TIM1 full remap if you need the remapped mapping (CubeMX generated code might expect this) Note: remap affects mapping for all TIM1 channels - do this before initializing the GPIOs */ __HAL_AFIO_REMAP_TIM1_ENABLE(); /* Deinit any previous GPIO config on PE8/PA8 to be safe */ HAL_GPIO_DeInit(GPIOE, GPIO_PIN_8); HAL_GPIO_DeInit(GPIOA, TEC_RIGHT_IN_Pin); /**TIM1 GPIO Configuration PE8 ------> TIM1_CH1N */ GPIO_InitStruct.Pin = GPIO_PIN_8; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); /* * Hardware note: main output (CH1) and complementary output (CH1N) cannot * be enabled at the same time on this board. For the 'left' mapping (PE8) * we only enable the complementary output (CH1N) and ensure CH1 is stopped. */ /* Ensure main channel is off, then start complementary output only */ HAL_TIMEx_PWMN_Start(&TEC_TIM, TIM_CHANNEL_1); } // PA8-TEC-IN2(right) TIM1_CH1,默认CH1,不需要映射 void right_tec_reconfig_pwm(void) { stop_tec_pwm(); /* Disable TIM1 remap so TIM1_CH1 maps to the default (PA8/PA9 depending on device) Do this before re-initializing the GPIO so HAL init uses the correct port/pin */ __HAL_AFIO_REMAP_TIM1_DISABLE(); /* Deinit any previous GPIO config on PE8/PA8 to be safe */ HAL_GPIO_DeInit(GPIOE, GPIO_PIN_8); HAL_GPIO_DeInit(GPIOA, TEC_RIGHT_IN_Pin); /* Re-run the post-init which will configure PA8 as AF (HAL_TIM_MspPostInit uses TEC_RIGHT_IN_Pin) */ HAL_TIM_MspPostInit(&TEC_TIM); /* * For the 'right' mapping (PA8) we only enable the main output (CH1) and * ensure the complementary output (CH1N) is stopped to avoid hardware conflict. */ HAL_TIM_PWM_Start(&TEC_TIM, TIM_CHANNEL_1); } void bsp_fan_start(void) { HAL_GPIO_WritePin(FAN_CONTROL_GPIO_Port, FAN_CONTROL_Pin, GPIO_PIN_SET); } void bsp_fan_stop(void) { HAL_GPIO_WritePin(FAN_CONTROL_GPIO_Port, FAN_CONTROL_Pin, GPIO_PIN_RESET); } void bsp_left_tec_open(void) { tec_sd_disable(); left_tec_reconfig_pwm(); left_tec_sd_enable(); } void bsp_right_tec_open(void) { tec_sd_disable(); right_tec_reconfig_pwm(); right_tec_sd_enable(); } static void left_tec_adjust_duty_cycle(uint32_t duty_cycle) { __HAL_TIM_SET_COMPARE(&TEC_TIM, TIM_CHANNEL_1, duty_cycle); } static void right_tec_adjust_duty_cycle(uint32_t duty_cycle) { __HAL_TIM_SET_COMPARE(&TEC_TIM, TIM_CHANNEL_1, duty_cycle); } void bsp_tec_cooling_open(void) { bsp_left_tec_open(); } void bsp_tec_heating_open(void) { bsp_right_tec_open(); } // pwm: 0.0 ~ 1.0 void bsp_tec_cooling_adjust(float pwm) { extern TIM_HandleTypeDef TEC_TIM; uint32_t max_period = __HAL_TIM_GET_AUTORELOAD(&TEC_TIM); left_tec_adjust_duty_cycle((uint32_t)(pwm * max_period)); } // pwm: 0.0 ~ 1.0 void bsp_tec_heating_adjust(float pwm) { extern TIM_HandleTypeDef TEC_TIM; uint32_t max_period = __HAL_TIM_GET_AUTORELOAD(&TEC_TIM); right_tec_adjust_duty_cycle((uint32_t)(pwm * max_period)); } void bsp_tec_close(void) { stop_tec_pwm(); tec_sd_disable(); } void bsp_tec_init(void) { MX_SPI3_Init(); MX_TIM1_Init(); }