// #include "bsp_pwm.h" // #include "stdlib.h" // #include "memory.h" // // // 配合中断以及初始化 // static uint8_t idx; // static PWMInstance *pwm_instance[PWM_DEVICE_CNT] = {NULL}; // 所有的pwm instance保存于此,用于callback时判断中断来源 // static uint32_t PWMSelectTclk(TIM_HandleTypeDef *htim); // // /** // * @brief pwm dma传输完成回调函数 // * // * @param htim 发生中断的定时器句柄 // */ // void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) // { // for (uint8_t i = 0; i < idx; i++) // { // // 来自同一个定时器的中断且通道相同 // if (pwm_instance[i]->htim == htim && htim->Channel == (1 << (pwm_instance[i]->channel / 4))) // { // if (pwm_instance[i]->callback) // 如果有回调函数 // pwm_instance[i]->callback(pwm_instance[i]); // return; // 一次只能有一个通道的中断,所以直接返回 // } // } // } // // PWMInstance *PWMRegister(PWM_Init_Config_s *config) // { // if (idx >= PWM_DEVICE_CNT) // 超过最大实例数,考虑增加或查看是否有内存泄漏 // while (1); // PWMInstance *pwm = (PWMInstance *) malloc(sizeof(PWMInstance)); // memset(pwm, 0, sizeof(PWMInstance)); // // pwm->htim = config->htim; // pwm->channel = config->channel; // pwm->period = config->period; // pwm->dutyratio = config->dutyratio; // pwm->callback = config->callback; // pwm->id = config->id; // pwm->tclk = PWMSelectTclk(pwm->htim); // // 启动PWM // HAL_TIM_PWM_Start(pwm->htim, pwm->channel); // PWMSetPeriod(pwm, pwm->period); // PWMSetDutyRatio(pwm, pwm->dutyratio); // pwm_instance[idx++] = pwm; // return pwm; // } // // /* 只是对HAL的函数进行了形式上的封装 */ // void PWMStart(PWMInstance *pwm) // { // HAL_TIM_PWM_Start(pwm->htim, pwm->channel); // } // // /* 只是对HAL的函数进行了形式上的封装 */ // void PWMStop(PWMInstance *pwm) // { // HAL_TIM_PWM_Stop(pwm->htim, pwm->channel); // } // // /* // * @brief 设置pwm周期 // * // * @param pwm pwm实例 // * @param period 周期 单位 s // */ // void PWMSetPeriod(PWMInstance *pwm, float period) // { // __HAL_TIM_SetAutoreload(pwm->htim, period * ((pwm->tclk) / (pwm->htim->Init.Prescaler + 1))); // } // // /* // * @brief 设置pwm占空比 // * // * @param pwm pwm实例 // * @param dutyratio 占空比 0~1 // */ // void PWMSetDutyRatio(PWMInstance *pwm, float dutyratio) // { // __HAL_TIM_SetCompare(pwm->htim, pwm->channel, dutyratio * (pwm->htim->Instance->ARR)); // } // // /* 只是对HAL的函数进行了形式上的封装 */ // void PWMStartDMA(PWMInstance *pwm, uint32_t *pData, uint32_t Size) // { // HAL_TIM_PWM_Start_DMA(pwm->htim, pwm->channel, pData, Size); // } // // // 设置pwm对应定时器时钟源频率 // //tim2~7,12~14:APB1 tim1,8~11:APB2 // static uint32_t PWMSelectTclk(TIM_HandleTypeDef *htim) // { // uintptr_t tclk_temp = ((uintptr_t) ((htim)->Instance)); // if ( // (tclk_temp <= (APB1PERIPH_BASE + 0x2000UL)) && // (tclk_temp >= (APB1PERIPH_BASE + 0x0000UL))) // { // return (HAL_RCC_GetPCLK1Freq() * ( // APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos] == 0 ? 1 : 2)); // } // if ( // ((tclk_temp <= (APB2PERIPH_BASE + 0x0400UL)) && // (tclk_temp >= (APB2PERIPH_BASE + 0x0000UL))) || // ((tclk_temp <= (APB2PERIPH_BASE + 0x4800UL)) && // (tclk_temp >= (APB2PERIPH_BASE + 0x4000UL)))) // { // return (HAL_RCC_GetPCLK2Freq() * ( // APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos] == 0 ? 1 : 2)); // } // return 0; // }