自锁我的理解就是过流保护负载,电流恢复重新运行。
打嗝模式的话,我的理解就是出现临时性过载情况(如电机启动时的浪涌电流)允许短暂重试的应用场景需要保持系统运行而不是完全停机的情况。所以每当检测到过流时,系统会关闭电机并进入打嗝模式每隔 2秒尝试重启一次电机每次重启后检查电流,如果仍然过高则再次关闭。
这里我用的是滴答定时器实现非阻塞延时。与Flash内部的电流阈值进行比较。
源码如下
#include "Motor_Lock.h"
#include "sFlash.h"
static uint8_t overcurrent_flag = 0; // 过流标志
static uint32_t hiccup_start_time = 0; // 打嗝模式开始时间
static uint8_t hiccup_attempts = 0; // 重试次数计数器
#define HICCUP_INTERVAL 2000 // 重试间隔(ms)
#define MAX_HICCUP_ATTEMPTS 5 // 最大重试次数
void Motor_Current_Check(void)
{
static uint32_t lasttime = 0;
// 每10ms执行一次完整检查
if(HAL_GetTick() - lasttime >= 10)
{
lasttime = HAL_GetTick();
Analysis_data();
// 正常运行状态检测过流
if(!overcurrent_flag)
{
if(data.Current > SFData.currentThreshold)
{
overcurrent_flag = 1;
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // 关闭电机
// 初始化打嗝模式
hiccup_start_time = HAL_GetTick();
hiccup_attempts = 0;
}
}
// 打嗝模式处理
else
{
// 检查是否启用打嗝模式
if(SFData.enableHiccupMode)
{
// 计算重试间隔
if(HAL_GetTick() - hiccup_start_time >= HICCUP_INTERVAL)
{
hiccup_start_time = HAL_GetTick();
hiccup_attempts++;
// 尝试重启电机
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
// 给电机一点时间启动,然后检查电流
HAL_Delay(50); // 短暂延时,实际应用中可能需要更优雅的实现
Analysis_data();
// 如果电流仍然过高,再次关闭电机
if(data.Current > SFData.currentThreshold)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
// 达到最大重试次数后进入永久锁定
if(hiccup_attempts >= MAX_HICCUP_ATTEMPTS)
{
SFData.enableHiccupMode = 0; // 禁用打嗝模式,进入永久锁定
}
}
else
{
// 电流正常,退出打嗝模式
overcurrent_flag = 0;
hiccup_attempts = 0;
}
}
}
}
}
}
// 蓝牙触发自锁功能
void ManualMotorLockout(void)
{
overcurrent_flag = 1;
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
SFData.enableHiccupMode = 0; // 禁用打嗝模式
}
// 复位函数,启动打嗝
void ResetOvercurrentProtection(void)
{
overcurrent_flag = 0;
hiccup_attempts = 0;
SFData.enableHiccupMode = 1; // 重新启用打嗝模式
if(data.Current <= SFData.currentThreshold)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
}
}2.Motor_Lock.h
源码如下
#ifndef __Motor_Lock_H_ #define __Motor_Lock_H_ #include "main.h" void ManualMotorLockout(void); void Motor_Current_Check(void); void ResetOvercurrentProtection(void); #endif
3.蓝牙手动触发代码如下
void HandleCommand(CommandType type)
{
switch (type) {
case CMD_THRESHOLD:
{
char *param = (char *)BLE_data.receivedata + 17;
int threshold = atoi(param);
printf("Set current threshold to %d mA\r\n", threshold);
SetCurrentThreshold(threshold);
}
break;
case CMD_RECOVERY:
EnableRecoveryControl();
break;
case CMD_CAN_RUN:
StartMotor();
break;
case CMD_STOP_RUN:
StopMotor();
break;
case CMD_MODE1:
SwitchToMode1();
break;
case CMD_MODE2:
SwitchToMode2();
break;
default:
break;
}
}
int Current_Param_Project=0;
void SetCurrentThreshold(uint32_t data)
{
Flash_WriteCurrentThreshold(data);
}
void EnableRecoveryControl(void)
{
}
void StartMotor(void)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
}
void StopMotor(void)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
}
void SwitchToMode1(void)
{
ManualMotorLockout();
}
void SwitchToMode2(void)
{
ResetOvercurrentProtection();
}
我要赚赏金
