25_R1_chassis/User/bsp/pwm.c

161 lines
4.9 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* Includes ----------------------------------------------------------------- */
#include "bsp\pwm.h"
#include <main.h>
#include <tim.h>
/* Private define ----------------------------------------------------------- */
/* Private macro ------------------------------------------------------------ */
/* Private typedef ---------------------------------------------------------- */
/* Private variables -------------------------------------------------------- */
/* Private function -------------------------------------------------------- */
/* Exported functions ------------------------------------------------------- */
int8_t BSP_PWM_Start(BSP_PWM_Channel_t ch) {
switch (ch) {
case BSP_PWM_IMU_HEAT:
HAL_TIM_PWM_Start(&htim10, TIM_CHANNEL_1);
break;
case BSP_PWM_BUZZER:
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_3);
break;
}
return BSP_OK;
}
/*PWM 占空比设置函数 duty_cycle(0-1)*/
int8_t BSP_PWM_Set(BSP_PWM_Channel_t ch, float duty_cycle) {
if (duty_cycle < 0.0f) duty_cycle = 0.f;
uint16_t pulse;
/* 通过PWM通道对应定时器重载值和给定占空比计算PWM周期值 */
switch (ch) {
case BSP_PWM_IMU_HEAT:
pulse = (uint16_t)(duty_cycle * (float)__HAL_TIM_GET_AUTORELOAD(&htim10));
break;
case BSP_PWM_BUZZER:
pulse = (uint16_t)(duty_cycle * (float)__HAL_TIM_GET_AUTORELOAD(&htim4));
break;
}
if (pulse > 0) {
switch (ch) {
case BSP_PWM_IMU_HEAT:
__HAL_TIM_SET_COMPARE(&htim10, TIM_CHANNEL_1, pulse);
break;
case BSP_PWM_BUZZER:
__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_3, pulse);
break;
}
}
else {
// BSP_PWM_Stop(ch);
}
return BSP_OK;
}
int8_t BSP_PWM_Stop(BSP_PWM_Channel_t ch) {
switch (ch) {
case BSP_PWM_IMU_HEAT:
HAL_TIM_PWM_Stop(&htim10, TIM_CHANNEL_1);
break;
case BSP_PWM_BUZZER:
HAL_TIM_PWM_Stop(&htim4, TIM_CHANNEL_3);
break;
}
HAL_GPIO_WritePin(IMU_HEAT_PWM_GPIO_Port, IMU_HEAT_PWM_Pin, GPIO_PIN_RESET);
return BSP_OK;
}
// 初始化蜂鸣器
void Buzzer_Init(void) {
buzzer.state = STATE_IDLE;
buzzer.mode = BUZZER_OFF;
buzzer.timer = 0;
buzzer.count = 0;
buzzer.duty = 0;
}
// 蜂鸣器任务处理 参数分别是模式音量0-1鸣叫频率ms间隔频率ms
void Buzzer_Update(BuzzerMode mode, float duty_cycle, uint16_t on_time_ms, uint16_t off_time_ms) {
// 参数校验和限制
duty_cycle = (duty_cycle < 0.0f) ? 0.0f :
(duty_cycle > 1.0f) ? 1.0f : duty_cycle;
// 设置最小10ms的时间限制
on_time_ms = (on_time_ms < 10) ? 10 : on_time_ms;
off_time_ms = (off_time_ms < 10) ? 10 : off_time_ms;
uint32_t now = HAL_GetTick();
// 更新配置参数
buzzer.on_time = on_time_ms;
buzzer.off_time = off_time_ms;
buzzer.duty = duty_cycle;
// 模式变更处理
if(mode != buzzer.mode) {
buzzer.mode = mode;
buzzer.count = 0;
buzzer.timer = now;
if(mode == BUZZER_OFF) {
BSP_PWM_Stop(BSP_PWM_BUZZER);
buzzer.state = STATE_IDLE;
return;
}
}
// 状态机处理
switch(buzzer.state) {
case STATE_IDLE:
if(buzzer.mode != BUZZER_OFF) {
BSP_PWM_Start(BSP_PWM_BUZZER);
BSP_PWM_Set(BSP_PWM_BUZZER, buzzer.duty);
buzzer.state = STATE_ON;
buzzer.timer = now;
}
break;
case STATE_ON:
if(now - buzzer.timer >= buzzer.on_time) { // 使用设置的鸣叫时间
BSP_PWM_Stop(BSP_PWM_BUZZER);
buzzer.state = STATE_OFF;
buzzer.timer = now;
buzzer.count++;
// 检查鸣叫次数
if((buzzer.mode == BUZZER_SINGLE && buzzer.count >= 1) ||
(buzzer.mode == BUZZER_DOUBLE && buzzer.count >= 2) ||
(buzzer.mode == BUZZER_TRIPLE && buzzer.count >= 3)) {
buzzer.mode = BUZZER_OFF;
buzzer.state = STATE_IDLE;
}
}
break;
case STATE_OFF:
if(buzzer.mode == BUZZER_CONTINUOUS) {
// 持续模式立即重新开始
BSP_PWM_Start(BSP_PWM_BUZZER);
BSP_PWM_Set(BSP_PWM_BUZZER, buzzer.duty);
buzzer.state = STATE_ON;
buzzer.timer = now;
}
else if(now - buzzer.timer >= buzzer.off_time) { // 使用设置的间隔时间
if(buzzer.mode != BUZZER_OFF) {
BSP_PWM_Start(BSP_PWM_BUZZER);
BSP_PWM_Set(BSP_PWM_BUZZER, buzzer.duty);
buzzer.state = STATE_ON;
buzzer.timer = now;
} else {
buzzer.state = STATE_IDLE;
}
}
break;
}
}