start2 PWM+ADC掉电检测

一、PWM(Pulse Width Modulation(脉宽调制))

周期固定,高电平时间可变,通过调节高电平占空比等效调节平均电压,实现电机调速、LED 调光。

不是直接给电机一个变化的电压,而是:

快速地打开、关闭电源,通过控制"打开时间比例"改变平均电压。

1.PWM一个周期

例如:PWM频率:

复制代码
#define PWM_FREQ 15000

表示:一分钟内没有,是:每秒15000个周期。

2、PWM占空比是什么?

占空比:就是一个周期内:开机时间占多少比例

等效电压原理(直流电机调速核心)

直流电机等效电压 = 电源电压 × 占空比

3、PWM和继电器的分工

**继电器:**控制方向

例如:上升:

复制代码
24V+
 |
电机+
 
电机-
 |
GND

下降:反过来。

**PWM:**控制速度

例如:上升:PWM:

复制代码
20%
↓
40%
↓
80%

速度:

复制代码
慢
↓
快

4. ATIM 定时器 PWM1 模式(你代码 ATIM_OCMODE_PWM1

计数逻辑(向上计数 ATIM_COUNTING_UP

计数器从 0 → 999 循环:

  1. 计数值 < 比较值 g_uCurDuty:引脚输出高
  2. 计数值 ≥ 比较值:引脚输出低

例:Duty=300 0~299 → 高;300~999 → 低

极性 ATIM_OCPOLARITY_NONINVERT 不反转

匹配高电平驱动电机驱动芯片,不需要反向电平。

影子缓存 BufferState=ENABLE

开启预装载,修改占空比不会中途撕裂波形,PWM 边缘平滑无毛刺,电机不抖动。

二、ADC掉电检测

ADC(模数转换器)掉电检测是一种常见的硬件保护机制,用于在系统电源异常跌落时,及时检测并保存关键数据或执行安全关机操作。

1. 基本原理

通过ADC实时监测电源电压(如3.3V、5V等),当检测到电压低于预设阈值时,触发中断或标志,通知MCU进行紧急处理。

2. 电压分压计算

若直接测量高于ADC参考电压的电源(如29V),需使用电阻分压网络。例如:

已知:电源电压 Vsource = 29V,分压电阻 R1 = 100kΩ,R2 = 10kΩ。

则ADC输入电压 VADC = Vsource × R2 / (R1 + R2) = 29V × 10 / (100 + 10) ≈ 2.64V。

3. ADC采样值计算

以CW32系列MCU为例,其ADC为12位,参考电压 VREF = 3.3V。

满量程数字值 = 212 - 1 = 4095。

当 VADC = 2.64V 时,ADC采样值 ≈ (2.64V / 3.3V) × 4095 ≈ 3275。

因此,可设置掉电阈值对应的ADC采样值(如3275),当采样值低于此阈值时,判定为掉电。

cs 复制代码
#define ADC_FULL 4095.0f
#define ADC_REF  3.3f

#define R_UP   100000.0f
#define R_DOWN 10000.0f

float Power_GetVoltage(uint16_t adc)
{
    float vadc;
    vadc = adc * ADC_REF / ADC_FULL;

    return vadc * (R_UP+R_DOWN) / R_DOWN;
}
掉电判断,假设掉电低于20V
cs 复制代码
#define POWER_OFF_VOLTAGE 20.0f

void Power_Check(void)
{
    float voltage;
    voltage = Power_GetVoltage(ADC_Value);
    if(voltage < POWER_OFF_VOLTAGE)
    {
        PowerFail_Handler();
    }
}

掉电处理流程:

29V下降→ADC检测→PowerFail_Handler()→关闭电机→关闭PWM→释放继电器→保存高度→等待复位

缓启动 / 缓停止实现思路(适配你的继电器 + PWM 调速架构)

核心原理

  1. PWM 占空比阶梯式缓慢上升(缓启动),阶梯式缓慢下降(缓停止),避免 29V 母线瞬间大电流冲击,同时配合之前 20V 低压防误判、7A 堵转保护。
  2. 采用 10ms PID 任务周期,每次步进固定增量STEP_DUTY,上限最大占空比MAX_DUTY,下限 0 停机。
  3. 区分 3 种运行状态:加速上升、匀速、减速停机,和堵转 / 低压故障互斥,故障时直接清零 PWM 不缓停。

4. 实现步骤

  1. 配置ADC通道、采样时间、参考电压等参数。
  2. 启动ADC连续采样或定时采样。
  3. 在ADC转换完成中断或主循环中读取采样值。
  4. 比较采样值与预设阈值,若低于阈值则置位掉电标志。
  5. 在掉电标志有效时,保存关键数据至非易失存储器(如Flash、EEPROM),或执行安全关机流程。

5. 注意事项

  • 分压电阻精度和温漂会影响检测精度。
  • 需考虑电源跌落速度与ADC采样/处理速度的匹配。
  • 可加入软件滤波(如滑动平均)避免误触发。
  • 阈值应留有一定余量,避免临界振荡。
cs 复制代码
// M1电流计算:扣除空载零点偏移80
float Current_M1_GetAmp(void)
{
    uint16_t uRaw = GetFilterAdc(M1_CUR_CH, &g_tM1Current);
		// 核心修复:减去空载ADC零点偏移80,解决停机虚电流
    int16_t iAdcCorrect = (int16_t)uRaw - CURRENT_OFFSET_ADC;
    if(iAdcCorrect < 0)
        iAdcCorrect = 0; // 消除负电流
    float fAdc = (float)iAdcCorrect;
    // 公式完全匹配hw 3.3V基准,电压换算:采样值/4095 * 3.3V基准
    float fVol = fAdc / ADC_RESOLUTION * ADC_REF_VOLT;
		// 运放21倍放大、0.02Ω采样电阻 计算真实电流
    g_tM1Current.fCurAmp = fVol / OP_AMP_GAIN / CURRENT_SHUNT_R;
    return g_tM1Current.fCurAmp;
}
// M1独立过流判定,100ms防抖
uint8_t M1_IsBlockProtect(void)
{
		// 电流超过7A堵转阈值
    float fCurr = Current_M1_GetAmp();
    if(fCurr >= BLOCK_CURRENT)
    {
        uM1OverCnt++;
				// 10ms任务周期,累计100次=1秒判定堵转
        if(uM1OverCnt >= OVER_CURRENT_TIME)
            return 1;// 触发堵转
    }
    else
        uM1OverCnt = 0;// 电流正常计数器清零
    return 0;
}

推挽输出(Push-Pull)

GPIO 内部有两个 MOS 管:

  • 上管(PMOS):接 VDD (3.3V)
  • 下管(NMOS):接 GND

两种工作状态

  1. 输出高电平 上管导通、下管截止 → 引脚直接拉到 3.3V,驱动能力强,能输出电流(灌电流)
  2. 输出低电平 下管导通、上管截止 → 引脚直接拉到 GND,吸收外部电流(拉电流)

对比开漏输出(OD)

开漏只有下拉 NMOS,高阻态,只能外部上拉才能输出高; 推挽高低都有驱动能力,电机、继电器、PWM 输出必须用推挽。

适用场景

  • PWM 定时器复用输出(PA8/PA9)
  • 继电器控制引脚
  • LED、电机驱动、普通数字 IO

缺点

两个管子不能同时导通(会电源对地短路),软件不能同时输出高低,你的继电器代码先全断开再延时切换就是规避这个风险。

PWM 高低电平需要强驱动输出,开漏输出无法输出高电平,PWM 波形失效,电机不转。 同时开启PA08_DIGTAL_ENABLE()关闭模拟功能,开启定时器复用外设功能。

相关推荐
炸膛坦客2 小时前
单片机/C/C++八股:(二十四)编译文件( .bin 和 .hex ,包括 .elf 和 .axf )
c语言·c++·单片机
Yunhoa2 小时前
51单片机(DS18B20 数字温度传感器)
单片机·嵌入式硬件·51单片机
zlinear数据采集卡4 小时前
2mV纹波的代价:硬核拆解ZLinear模拟前端放大器与正负可调电源设计
arm开发·单片机·嵌入式硬件·fpga开发·架构·开源
Wallystech-Linda4 小时前
Exploring WiFi 7 Module Designs for Next-Generation Wireless Applications
嵌入式硬件
不上岸的旱鸭子6 小时前
PCB设计
单片机·pcb工艺
吠品6 小时前
多语言支持,从后台到前端我都趟过哪些坑
stm32·单片机·嵌入式硬件
炸膛坦客6 小时前
单片机/C/C++八股:(二十三)#define 和 typedef 的区别
c语言·c++·单片机
zlinear数据采集卡7 小时前
硅片里的“自动纠错“:硬核拆解LHAMP188自动归零技术原理与三种封装的PCB布局实战
arm开发·单片机·嵌入式硬件·fpga开发·开源
2401_888859717 小时前
STM32H7外部flash(W25Q128)+SPI+DMA读写
stm32·单片机·嵌入式硬件