这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 自动触发自锁/打嗝和BLE蓝牙手动触发自锁/打嗝模式实现

共1条 1/1 1 跳转至

自动触发自锁/打嗝和BLE蓝牙手动触发自锁/打嗝模式实现

菜鸟
2025-06-18 09:54:37     打赏

自锁我的理解就是过流保护负载,电流恢复重新运行。

打嗝模式的话,我的理解就是出现临时性过载情况(如电机启动时的浪涌电流)允许短暂重试的应用场景需要保持系统运行而不是完全停机的情况。所以每当检测到过流时,系统会关闭电机并进入打嗝模式每隔 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();
    }



    共1条 1/1 1 跳转至

    回复

    匿名不能发帖!请先 [ 登陆 注册 ]