在逆变电路中,过零点和相位(正半周还是负半周)的低成本方法原理、及实现和工程实践 📅 发布时间:2026/9/11 19:16:32 👁 浏览次数: 摘要:本文提出一种基于硬件电路的过零与相位检测方法,通过高通滤波、半波整流和比较器整形将交流信号转换为方波,由单片机中断完成过零与相位检测;给出完整的 STM32 并网逆变实战案例,涵盖定时器输入捕获与 DA 同步输出代码;并通过实测数据验证方案在过零精度、相位对齐和频率测量方面的可行性。一、引言在逆变电源、电能计量和相位同步等应用中,准确检测交流信号的过零点和相位是系统稳定运行的基础。现有方案多依赖 ADC 采样加软件算法,存在实时性不足、受采样率和量化误差影响大等问题。以 50Hz 工频信号为例,若 ADC 采样率为 10kHz(每周期 200 点),相邻采样间隔为 100μs,对应相位分辨率约 1.8 度;若采样率降至 2kHz(每周期 40 点),相位分辨率进一步恶化至约 9 度。同时,12 位 ADC 在 3.3V 满量程下的量化步长约 0.8mV,叠加在过零附近的斜率上会引入额外的过零时刻抖动,典型相位误差可达 0.5~2 度,难以满足并网逆变对相位同步(通常要求误差小于 3 度,工程上更期望小于 1 度)的严格要求。此外,ADC 采样加软件算法需要周期性占用 CPU 进行采样、滤波和过零插值计算,实时性受采样周期和算法执行时间制约,在电网频率波动或谐波干扰下容易产生检测延迟。针对上述问题,本文提出一种基于硬件电路的过零与相位检测方法,通过高通滤波、半波整流和比较器整形将交流信号转换为方波,由单片机上升沿/下降沿中断完成检测,并给出完整的 STM32 并网逆变实战案例,兼顾精度、实时性与工程可落地性。为更直观地评估本文方案的适用性,下面从实时性、精度、成本、抗干扰能力和实现复杂度五个维度,将本文提出的硬件过零检测方案与现有 ADC 采样加软件算法方案进行系统对比。对比维度硬件过零检测(本文方案)ADC 采样加软件算法实时性过零事件由比较器输出边沿直接触发硬件中断,响应延迟为微秒级且确定性强,几乎不受采样周期制约。依赖 ADC 采样周期和软件算法执行时间,存在固有延迟;采样率越低,检测延迟越大,实时性相对较弱。精度过零时刻由硬件边沿直接触发,配合定时器输入捕获可达微秒级分辨率,实测相位误差小于 0.05 度。受 ADC 采样率、量化误差和插值算法影响,典型相位误差 0.5~2 度,精度通常低于硬件方案。成本需增加比较器、二极管、电阻电容等分立元件,BOM 成本略高,但无需额外运算资源。仅需 ADC 通道和软件处理,几乎不增加硬件成本,但会占用单片机 CPU 和存储资源。抗干扰能力经高通滤波和比较器整形,对噪声有一定抑制能力,但比较器翻转点附近仍可能受毛刺干扰,需配合软件消抖。可通过数字滤波、均值或过零插值算法抑制噪声,抗干扰能力较强,但算法复杂度相应增加。实现复杂度硬件电路简单、原理清晰,软件仅需中断检测和周期计算,整体实现难度较低。无需额外硬件,但需设计采样调度、数字滤波和过零插值算法,软件实现复杂度较高。综合来看,本文的硬件过零检测方案在实时性和精度上具有明显优势,适合并网逆变等对过零时刻要求严格的场景。但该方案也存在一定的适用边界:其一,比较器翻转点依赖基准电压和输入幅值,当输入信号幅值过低(如峰值低于 3V)或谐波含量较大时,翻转点抖动会明显增大,检测精度下降;其二,硬件方案对元器件精度和 PCB 布局较为敏感,基准电压漂移和电阻电容误差会引入额外相位偏差,需要配合精密元件和软件校准;其三,该方案主要针对工频正弦信号设计,对非正弦波形或频率剧烈变化的场合适应性有限。因此,在电网谐波严重、输入幅值波动大或对成本极为敏感的场合,可考虑采用硬件检测为主、软件滤波为辅的混合方案,以兼顾精度、实时性与工程可落地性。二、电路原理AC交流信号,经C1/R1高通滤波器后,再经过一个二极管D1进行半波整流,后经过电阻R2输入到LM393U1的同相输入端,U1的负端接一个0.1V的基准电压,U1的输出端上拉一个电阻R3。50Hz或60Hz的交流信号,经过滤波和电平转换输出一个0~5V的方波信号,串联一个电阻R4输入到单片机(如ATTlNY26,STM32,8051F系列)的中断脚,软件利用上升沿中断便可检测到零点,相位和交流信号周期及频率。1. 高通滤波器(C1/R1)交流信号首先经过由C1和R1组成的高通滤波器,用于隔离直流分量并保留交流成分。典型取值:C1取0.1μF,R1取100kΩ,此时截止频率约为16Hz,可有效通过50Hz/60Hz工频信号并抑制低频噪声。输入的正弦波经过该环节后,波形保持正弦形状,仅直流偏置被滤除,信号幅值基本不变。2. 半波整流(D1)滤波后的交流信号经二极管D1进行半波整流。D1选用1N4148开关二极管,正向压降约0.7V。整流后,负半周被削去,仅保留正半周波形,输出为脉动的半波正弦信号。该信号幅值约为输入峰值减去二极管压降,例如输入峰值5V时,输出峰值约4.3V。3. 比较器整形(LM393)半波整流后的信号经电阻R2(典型取值10kΩ)输入到LM393比较器的同相输入端,反相输入端接0.1V基准电压。LM393输出端通过上拉电阻R3(典型取值10kΩ)接至5V电源。当同相输入端电压高于0.1V时,输出翻转为高电平;低于0.1V时输出为低电平。这样,半波正弦信号被整形为0~5V的方波信号,方波的高电平宽度对应交流信号的正半周。4. 单片机中断检测(R4)下面补充基于 STM32 的相位检测代码示例。该示例通过比较器输出方波与参考信号计算相位差:利用定时器输入捕获分别记录方波上升沿和参考信号上升沿的时间戳,两者时间差除以信号周期再乘以 360 度,即可得到相位差。#include "stm32f1xx_hal.h" /* 全局变量:保存方波上升沿时间戳(单位:us) / volatile uint32_t wave_edge_tick = 0; / 全局变量:保存参考信号上升沿时间戳(单位:us) / volatile uint32_t ref_edge_tick = 0; / 全局变量:保存交流信号周期(单位:us) / volatile uint32_t ac_period_us = 0; / 全局变量:保存计算得到的相位差(单位:度) */ volatile float phase_diff_deg = 0.0f; /** @brief 方波上升沿中断服务函数(比较器输出) @note 记录方波上升沿时间戳,并计算信号周期 / void EXTI0_IRQHandler(void) { / 1. 清除中断标志位,防止重复触发 */ if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_0) != RESET) { __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_0); /* 2. 获取当前时间戳(微秒级) */ uint32_t now = HAL_GetTick() * 1000; /* 3. 计算相邻两次上升沿的时间间隔,即交流信号周期 / if (wave_edge_tick != 0) { ac_period_us = now - wave_edge_tick; } wave_edge_tick = now; } } /* @brief 参考信号上升沿中断服务函数 @note 记录参考信号上升沿时间戳,用于相位差计算 / void EXTI1_IRQHandler(void) { / 1. 清除中断标志位 / if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_1) != RESET) { __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_1); / 2. 记录参考信号上升沿时间戳 / ref_edge_tick = HAL_GetTick() * 1000; } } /* @brief 计算方波与参考信号之间的相位差 @note 相位差 = (时间差 / 周期) * 360 度 / void calc_phase_diff(void) { / 1. 若周期或时间戳无效,则直接返回 / if (ac_period_us == 0 || wave_edge_tick == 0 || ref_edge_tick == 0) { phase_diff_deg = 0.0f; return; } / 2. 计算方波上升沿与参考信号上升沿的时间差 / uint32_t delta = (wave_edge_tick ref_edge_tick) ? (wave_edge_tick - ref_edge_tick) : (ref_edge_tick - wave_edge_tick); / 3. 时间差除以周期得到相位比例,再乘以 360 度得到相位差 / phase_diff_deg = ((float)delta / (float)ac_period_us) * 360.0f; / 4. 将相位差归一化到 0~360 度范围 */ if (phase_diff_deg 360.0f) { phase_diff_deg -= 360.0f; } }上述代码中,EXTI0_IRQHandler捕获比较器输出方波的上升沿并记录时间戳,同时计算交流信号周期;EXTI1_IRQHandler捕获参考信号的上升沿并记录时间戳。在calc_phase_diff()中,用两个上升沿的时间差除以信号周期,再乘以 360 度即可得到相位差。关键步骤包括:清除中断标志位防止重复触发、记录时间戳、计算周期、以及将相位差归一化到 0~360 度范围。实际工程中建议使用定时器输入捕获获取更高精度的时间戳。下面给出基于 STM32 的上升沿中断检测过零点的 C 语言示例。代码使用外部中断 EXTI 检测比较器输出方波的上升沿,并在中断服务函数中记录时间戳,通过相邻两次上升沿的时间差计算交流信号的周期与频率。#include "stm32f1xx_hal.h" /* 全局变量:记录上一次上升沿的时间戳(单位:us) / static uint32_t last_tick = 0; / 全局变量:保存计算得到的交流信号周期(单位:us) */ volatile uint32_t ac_period_us = 0; /** @brief EXTI 上升沿中断服务函数 @note 比较器输出方波的上升沿对应交流信号过零点, 每次进入中断即检测到一个过零点。 / void EXTI0_IRQHandler(void) { / 1. 清除中断标志位,防止重复触发 */ if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_0) != RESET) { __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_0); /* 2. 获取当前时间戳(微秒级) */ uint32_t now = HAL_GetTick() * 1000; /* 此处以 ms 转 us 为例 */ /* 3. 计算相邻两次上升沿的时间间隔,即交流信号周期 */ if (last_tick != 0) { ac_period_us = now - last_tick; } last_tick = now; } } /** @brief 根据周期计算频率(单位:Hz) @retval 交流信号频率 / float get_ac_frequency(void) { / 周期单位为 us,转换为秒后取倒数得到频率 */ if (ac_period_us == 0) { return 0.0f; } return 1000000.0f / (float)ac_period_us; }上述代码中,EXTI0_IRQHandler为上升沿中断服务函数,每次方波从低电平跳变为高电平时触发一次,对应一个过零点。通过HAL_GetTick()获取系统时间戳并记录相邻两次中断的间隔,即可得到交流信号的周期,进而由周期倒数计算出频率。实际工程中建议使用定时器输入捕获或硬件时间戳以获得更高精度。下面给出基于 STM32 的下降沿中断检测过零点的 C 语言示例。代码使用外部中断 EXTI 检测比较器输出方波的下降沿,并在中断服务函数中记录时间戳,通过相邻两次下降沿的时间差计算交流信号的周期与频率。#include "stm32f1xx_hal.h" /* 全局变量:记录上一次下降沿的时间戳(单位:us) */ static uint32_t last_fall_tick = 0; /* 全局变量:保存计算得到的交流信号周期(单位:us) */ volatile uint32_t ac_period_us = 0; /** * @brief EXTI 下降沿中断服务函数 * @note 比较器输出方波的下降沿对应交流信号的过零点, * 每次进入中断即检测到一个过零点。 */ void EXTI0_IRQHandler(void) { /* 1. 清除中断标志位,防止重复触发 */ if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_0) != RESET) { __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_0); /* 2. 获取当前时间戳(微秒级) */ uint32_t now = HAL_GetTick() * 1000; /* 此处以 ms 转 us 为例 */ /* 3. 计算相邻两次下降沿的时间间隔,即交流信号周期 */ if (last_fall_tick != 0) { ac_period_us = now - last_fall_tick; } last_fall_tick = now; } } /** @brief 根据周期计算频率(单位:Hz) @retval 交流信号频率 / float get_ac_frequency(void) { / 周期单位为 us,转换为秒后取倒数得到频率 */ if (ac_period_us == 0) { return 0.0f; } return 1000000.0f / (float)ac_period_us; }上述代码中,EXTI0_IRQHandler为下降沿中断服务函数,每次方波从高电平跳变为低电平时触发一次,对应一个过零点。通过HAL_GetTick()获取系统时间戳并记录相邻两次中断的间隔,即可得到交流信号的周期,进而由周期倒数计算出频率。实际工程中建议使用定时器输入捕获或硬件时间戳以获得更高精度。比较器输出的方波信号经电阻R4(典型取值1kΩ)串联后送入单片机中断引脚。R4起限流保护作用,防止外部干扰或误接损坏单片机引脚。单片机配置为上升沿中断触发,每当方波从低电平跳变为高电平时触发一次中断,该上升沿对应交流信号的过零点。通过记录相邻两次中断的时间间隔,即可计算出交流信号的周期和频率,进而实现相位检测。5. 元件清单与典型取值为方便读者快速查阅和采购,下表汇总了本电路各主要元件的名称、型号/典型取值及作用说明。元件名称型号/典型取值作用说明C1耦合电容0.1μF与 R1 组成高通滤波器,隔离直流分量并保留交流成分。R1滤波电阻100kΩ与 C1 共同决定高通截止频率(约 16Hz),抑制低频噪声。D1整流二极管1N4148对滤波后的交流信号进行半波整流,削去负半周,保留正半周。R2输入限