/* Includes ----------------------------------------------------------------- */ #include "buzzer_pwm.h" #include "main.h" #include "tim.h" /* Private define ----------------------------------------------------------- */ /* Private macro ------------------------------------------------------------ */ /* Private typedef ---------------------------------------------------------- */ typedef struct { TIM_HandleTypeDef* htim; uint32_t channel; } BSP_BUZZER_Config_t; /* Private variables -------------------------------------------------------- */ BSP_BUZZER_Config_t bsp_buzzer_ch={&htim4, TIM_CHANNEL_3}; //自定义蜂鸣器TIM通道 uint8_t bsp_buzzer_s_flag = 0; //蜂鸣器状态 /* Private function -------------------------------------------------------- */ /* Exported functions ------------------------------------------------------- */ /** * @brief 获取APBx定时器时钟频率 * @param *htim 定时器句柄 * @return APBx定时器时钟频率 */ int32_t BSP_BUZ_GetTIMxFrequency(TIM_HandleTypeDef *htim) { uint32_t timx_clk = 0; if (htim->Instance == TIM4) { timx_clk = HAL_RCC_GetPCLK1Freq(); if (HAL_RCC_GetPCLK1Freq() != SystemCoreClock) { timx_clk *= 2; } return timx_clk; } return BSP_ERR; } /** * @brief 使能蜂鸣器PWM通道 * @return 成功:BSP_OK 错误:BSP_ERR */ int8_t BSP_BUZZER_Start(void) { if(HAL_TIM_PWM_Start(bsp_buzzer_ch.htim, bsp_buzzer_ch.channel)!=HAL_OK){ return BSP_ERR; }else return BSP_OK; } /** * @brief 失能蜂鸣器PWM通道 * @return 成功:BSP_OK 错误:BSP_ERR */ int8_t BSP_BUZZER_Stop(void){ if(HAL_TIM_PWM_Stop(bsp_buzzer_ch.htim, bsp_buzzer_ch.channel)!=HAL_OK){ return BSP_ERR; }else return 0; } /** * @brief 设置蜂鸣器PWM占空比 * @param duty_cycle 占空比 * @return 成功:BSP_OK 错误:BSP_ERR */ int8_t BSP_BUZZER_Set_Duty_Cycle(float duty_cycle) { if (duty_cycle > 1.0f) return BSP_ERR; uint16_t pulse = duty_cycle * bsp_buzzer_ch.htim->Instance->ARR; __HAL_TIM_SET_COMPARE(bsp_buzzer_ch.htim, bsp_buzzer_ch.channel, pulse); return BSP_OK; } /** * @brief 设置蜂鸣器PWM频率 * @param psc 预分频值 * @param arr 自动重装载值 * @return 成功:BSP_OK 错误:BSP_ERR */ int8_t BSP_BUZZER_Set_Freq(uint16_t psc, uint16_t arr) { if (psc == 0 || arr == 0) return BSP_ERR; BSP_BUZZER_Stop(); __HAL_TIM_SET_PRESCALER(bsp_buzzer_ch.htim, psc); __HAL_TIM_SetAutoreload(bsp_buzzer_ch.htim, arr); __HAL_TIM_SET_COMPARE(bsp_buzzer_ch.htim, bsp_buzzer_ch.channel, bsp_buzzer_ch.htim->Instance->ARR * 0.5); // 鏇存柊鍗犵┖姣? BSP_BUZZER_Start(); return BSP_OK; } /** * @brief 设置蜂鸣器音调和音量 * @param s 蜂鸣器状态 * @param tone 音调 * @param volume 音量 * @return 成功:BSP_OK 错误:BSP_ERR */ int8_t BSP_BUZZER_Set(BSP_BUZZER_Status_t s, BSP_BUZZER_USUAL_TONE_t tone, float volume) { switch (s) { case BSP_BUZZER_ON: BSP_BUZZER_Start(); bsp_buzzer_s_flag= 1; break; case BSP_BUZZER_OFF: BSP_BUZZER_Stop(); bsp_buzzer_s_flag= 2; break; case BSP_BUZZER_TAGGLE: if (bsp_buzzer_s_flag==1) { BSP_BUZZER_Stop(); bsp_buzzer_s_flag=2; } else if(bsp_buzzer_s_flag==2) { BSP_BUZZER_Start(); bsp_buzzer_s_flag=1; } else return BSP_ERR; default: return BSP_ERR; } if(bsp_buzzer_s_flag==1) switch(tone) { case BSP_BUZZER_C5: BSP_BUZZER_Set_Freq(BSP_BUZ_GetTIMxFrequency(bsp_buzzer_ch.htim)/1000000, 1000000/BSP_BUZZER_C5); BSP_BUZZER_Set_Duty_Cycle(volume); break; case BSP_BUZZER_D5: BSP_BUZZER_Set_Freq(BSP_BUZ_GetTIMxFrequency(bsp_buzzer_ch.htim)/1000000, 1000000/BSP_BUZZER_D5); BSP_BUZZER_Set_Duty_Cycle(volume); break; case BSP_BUZZER_E5: BSP_BUZZER_Set_Freq(BSP_BUZ_GetTIMxFrequency(bsp_buzzer_ch.htim)/1000000, 1000000/BSP_BUZZER_E5); BSP_BUZZER_Set_Duty_Cycle(volume); break; case BSP_BUZZER_F5: BSP_BUZZER_Set_Freq(BSP_BUZ_GetTIMxFrequency(bsp_buzzer_ch.htim)/1000000, 1000000/BSP_BUZZER_F5); BSP_BUZZER_Set_Duty_Cycle(volume); break; case BSP_BUZZER_G5: BSP_BUZZER_Set_Freq(BSP_BUZ_GetTIMxFrequency(bsp_buzzer_ch.htim)/1000000, 1000000/BSP_BUZZER_G5); BSP_BUZZER_Set_Duty_Cycle(volume); break; case BSP_BUZZER_A5: BSP_BUZZER_Set_Freq(BSP_BUZ_GetTIMxFrequency(bsp_buzzer_ch.htim)/1000000, 1000000/BSP_BUZZER_A5); BSP_BUZZER_Set_Duty_Cycle(volume); break; case BSP_BUZZER_B5: BSP_BUZZER_Set_Freq(BSP_BUZ_GetTIMxFrequency(bsp_buzzer_ch.htim)/1000000, 1000000/BSP_BUZZER_B5); BSP_BUZZER_Set_Duty_Cycle(volume); break; default: return BSP_ERR; } return BSP_OK; } void Buzzer_On(uint16_t freq_hz, uint8_t volume) { uint32_t arr_value = (168000000 / (167 + 1) / freq_hz) - 1; // 动态计算 ARR __HAL_TIM_SET_AUTORELOAD(&htim4, arr_value); // 更新 ARR __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_3, (arr_value + 1) * volume / 100); // 设置占空比 HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_3); // 启动 PWM } // 关闭蜂鸣器 void Buzzer_Off(void) { HAL_TIM_PWM_Stop(&htim4, TIM_CHANNEL_3); }