ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

三相交流电压表完整程序解析:从MCU采样到RMS算法实战

三相交流电压表完整程序解析:从MCU采样到RMS算法实战 简介整套三相交流电压表程序设计方案面向嵌入式开发、电力监控及电子测量学习者解决三相电压信号采集、计算、显示与报警等完整链路。压缩包内共15个文件以C语言源码、头文件、Keil工程文件、编译目标文件、HEX烧录文件及DSK仿真磁盘为主另含列表文件与备份文件便于阅读、编译和烧录调试整体仅46KB轻量易用。已有706人学习浏览。程序覆盖ADC数据采集、同步采样、有效值与线/相电压计算、相位分析、过欠压报警、数据显示与记录等关键模块适合以51单片机或类似平台为载体的实验室项目开发。源码结构清晰函数划分明确可直接移植到现有监控板卡通过研读可快速掌握三相电压测量的工程实现思路并二次改造用于配电柜监测或教学演示对提升电力系统自动化监控能力有直接参考价值。 做电气设备维护和配电柜项目的朋友应该都跟三相交流电压表打过交道。这种仪表看着不起眼但没有它整个配电系统的电压状态就跟睁眼瞎一样。我这次拿到的是一份“电测仪表(三相交流电压表完整程序).rar”压缩包里是一套可以直接拿去用的三相交流电压表程序配合常见的单片机开发板就能跑起来。别小看这个题目三相电压的采集、有效值计算、相序判断、显示刷新每一块单独拎出来都够新手琢磨一阵子而这份完整程序恰好把整条链路串通了。这篇东西适合两类人看一类是做电力仪表、配电监控相关项目的单片机开发者想参考一套能实际跑通的程序框架另一类是刚接触交流采样被真有效值算法和隔离方案搞得一头雾水的同学。我会把这套程序背后的设计思路、关键代码逻辑、硬件接线要点和实际调试中容易踩的坑挨个拆开讲清楚保证你拿到压缩包之后不仅能编译通过还能在硬件上稳定运行。1. 项目概述与整体设计思路1.1 三相交流电压表解决什么问题三相交流电压表是电测仪表里最基础的设备之一专门用来实时测量三相供电系统的线电压和相电压。现场的三相电通常是A、B、C三根火线加一根零线相与相之间是线电压标准380V相与零线之间是相电压标准220V三相互相之间差120度相位角。配电柜里装了它值班人员才能随时知道哪一相电压偏高、哪一相欠压、是不是缺相了。这个项目把“完整程序”放在压缩包里意味着它是个“拿到就能改、改完就能烧”的样板工程。程序里通常包含三相电压采样、真有效值计算、相序判断、按键切换显示模式和OLED/LCD显示驱动这几个核心模块。相比买一个成品电压表自己做一套的好处是能灵活接入自己的系统比如把电压数据通过串口发给上位机或者加上继电器做超限断电控制。1.2 方案选型为什么用MCU直接采样而不是专用计量芯片做三相电压测量行业里常见两条路线一条是专用的电能计量芯片比如HLW8032、BL0940这类内部集成了ADC和功率计算逻辑开发者不用管算法细节直接读寄存器拿数据另一条就是这套程序采用的方案——MCU内置ADC直接采样用软件算法计算有效值。两条路我都走过说实话专用芯片省事但有个前提是你的需求跟芯片内置的逻辑完全匹配。可一旦你想做的事情超出了芯片的固定功能比如要自定义显示界面、要加相序判断、要根据电压波动做保护逻辑就得另想办法。这套程序走的是MCU方案用一颗常见的ARM Cortex-M内核单片机STM32F103或者国产GD32系列都行自带多通道ADC配合电压互感器或电阻分压把380V交流电降到ADC可采集的低压信号再用软件算RMS值。优势很明显折腾空间大、代码完全可控、成本低。1.3 程序整体架构与模块划分打开这个工程代码整体是“主循环定时中断”的经典结构。ADC采样放在定时器触发的中断里这样可以保证每周波采样的点数固定不会因为主循环里显示刷新或按键扫描而抖动。主循环负责干活中断负责按时采集两者通过标志位通信这套架构是单片机处理连续数据流的标准姿势也是整个程序跑得稳的关键。程序模块大致分成ADC驱动配置采样通道和触发方式、采样数据处理均值滤波、RMS计算、参数标定比例系数、零点校准、显示驱动OLED屏或LCD1602、按键输入切换显示相序/线电压/相电压。有的版本还会加过压欠压报警输出。理解了模块划分再去看代码就不会觉得乱改起来也知道去哪找。2. 核心算法与关键代码实现2.1 交流采样的原理从380V到ADC可读的小电压单片机ADC很娇气参考电压基本都是3.3V或者5V你要是把380V直接怼进去板子瞬间冒烟。所以前端必须做降压处理。工程里常用的做法是电压互感器PT降压或者高阻值电阻分压。电阻分压简单便宜但跟电网之间没有电气隔离安全性差一些电压互感器把强电和弱电隔离开抗干扰能力强做仪表类产品基本都选互感器方案。互感器一般输出的是毫安级电流信号比如2mA/2mA规格初级串一个电阻接380V次级并一个采样电阻转成电压最后再经过运放调理电路把信号偏移到ADC输入范围的正中间。因为交流信号有正半周和负半周如果不加直流偏置负半周会被ADC截掉程序里需要把采集到的ADC值减去这个直流偏置还原出真实的交流波形。这个“减去零偏”的细节很多新手第一次做交流采样都会遗漏导致计算结果完全不对。2.2 真有效值RMS算法核心采样逻辑交流电压表的“灵魂”在于真有效值计算。因为电网波形不一定是纯净的正弦波可能是带畸变的用峰值除以根号2去估算有效值误差会比较大。标准做法是RMS算法对信号在整数个周期内进行离散采样把每个采样点的值平方求和再取平均再开方公式是Vrms sqrt( (1/N) * Σ(vi^2) )其中N是一个周期内的采样总点数vi是第i个采样点的电压值。从数学原理上说这个算法对任意波形都成立所以叫“真有效值”。程序实现时要注意两点一是N必须覆盖整数个信号周期否则会引入截断误差二是v必须先用浮点数或定点数计算出实际电压值再参与平方和运算。下面是核心计算代码的简化版本逻辑跟工程里的实际代码是一致的#define SAMPLE_NUM 128 // 每个周期采样点数 #define ADC_REF_VOLT 3.3f // ADC参考电压 #define ADC_RESOLUTION 4096 // 12位ADC float calc_rms(uint16_t *adc_buf, uint16_t zero_offset) { uint64_t sum_sq 0; for (uint16_t i 0; i SAMPLE_NUM; i) { float voltage (adc_buf[i] - zero_offset) * ADC_REF_VOLT / ADC_RESOLUTION; sum_sq (uint64_t)(voltage * voltage * 1000.0f); } float rms sqrtf((float)sum_sq / SAMPLE_NUM / 1000.0f); return rms; }这里我故意把平方和用了整数累加再转浮点避免每次循环都调用浮点乘法导致速度下降。实际工程里如果要追求极致效率还能用arm_dsp库里的函数比如arm_rms_f32()一个函数调用就能算完。但在小型单片机上直接用数学库的sqrtf就够了注意算完后获得的RMS值对应的是互感器次级或分压后的电压还得再乘回变比才是真实的三相电压值。2.3 采样时序与每周波点数选择1个周期的采样次数决定了测量精度和MCU的负载。50Hz工频信号的周期是20ms如果每周波采128个点那么每个点之间的时间间隔是20ms/128≈156.25us换算成采样频率就是6400Hz。程序里用定时器中断来触发ADC采样设好定时器的重装载值就能精确控制这个采样间隔。选128点是根据经验来的既保证了足够高的精度又不会让中断太频繁影响主循环干活。如果你把点数提高到256精度提升并不明显但MCU每秒钟要进256*5012800次中断对主循环的拖累就大了。反过来如果每周波只采32个点对于有谐波畸变的波形RMS算法误差会明显增大。注意定时器中断跟ADC采样触发最好用硬件联动也就是定时器更新事件直接触发ADC启动转换转换完成再进DMA中断这样采样间隔完全不受CPU执行其它代码的影响能确保等间隔采样。这也是程序里推荐的做法纯靠软件延时去凑采样间隔的方案精度不理想。2.4 相序判断的实现思路三相电最怕的故障之一是相序接反如果电机带了相序保护功能还好有些老设备没有保护一反转就把机械结构给憋坏。这套程序里也带了相序判断逻辑本质是在检测三相电压的过零点顺序。正常正序情况下A相过零点先出现经过120度相位角后B相过零再过120度C相过零如果顺序反了说明相序错误程序就会在屏幕上打出FAULT提示。实现手段有两条路硬件过零检测电路比较器输出方波单片机捕获上升沿或者软件过零判断在采样数组里找跨过偏置值的点。硬件方式准确、抗干扰好但多占电路软件方式省成本但实时性差一些。工程里两种方式都有人用你要是拿这套程序改产品建议优先用硬件捕获代码逻辑会简单得多。3. 完整工程结构与实操部署3.1 压缩包解压与工程文件组织拿到“完整程序.rar”第一件事当然是解压。这里提醒一下很多下载站会给压缩包加密或者附带广告程序解压前最好先用杀毒软件扫一遍别让文件里夹带的乱七八糟的dll和exe混进你电脑。用WinRAR、7-Zip或者Bandizip都能解压如果提示密码一般下载页会注明密码通常是网址或者固定的分享码别信那种让你关注公众号才能获取密码的套路单纯程序分享没必要这样。解压后的典型目录长这样项目根目录下有USER/存放main.c、stm32f1xx_it.c等主程序文件、HARDWARE/每块硬件的驱动比如OLED、ADC、按键、CORE/启动文件、内核相关代码、SYSTEM/串口、延时、中断分组等系统级封装、OBJ/编译生成的hex文件。看到这个结构基本就能确定是正点原子或类似风格的工程模板比较规整。3.2 从源码到能跑编译环境配置这个工程默认是Keil MDK环境。打开后缀为.uvprojx的工程文件之前先确认你的Keil版本别太旧Keil MDK5打开是老工程会自动提示迁移一般选“OK”让它迁移就行。如果工程提示找不到芯片型号需要去Pack Installer里装对应的器件支持包比如STM32F1系列就装Keil.STM32F1xx_DFP。编译前有几点要检查C/C编译器选项里的宏定义比如STM32F10X_HD是否跟你手上的芯片容量匹配Include Paths里有没有漏掉HARDWARE、SYSTEM这些头文件目录。这些地方配不对一编译就会爆出一堆“头文件找不到”的错。把工程里的路径一个个加上去基本上就能编译通过了。3.3 硬件接线与程序参数的对应关系程序跑起来之前硬件接线必须跟代码里的引脚定义对上。拿常见的OLED显示方案来说用I2C接口的话SDA和SCL要接到代码里oled.h定义的GPIO上三相电压采样板来的三路信号分别接入ADC的三个通道引脚。每个引脚对应到哪个ADC通道在adc.c里会写死比如PA0对应ADC1_IN0、PA1对应ADC1_IN1、PA2对应ADC1_IN2接线的时候得照着这个表来。接线完成后还要检查互感器变比和分压电阻的数值跟程序里的标定系数是否一致。这个很关键程序里通常会有一个电压比例系数VOLT_RATIO比如Vr Vrms * RATIO。如果你换了一个变比的互感器或者改了采样电阻这个系数必须按新的硬件参数重新算一遍。计算公式很简单假设互感器初级串了120kΩ限流电阻输入380V时初级电流I380/120000≈3.17mA次级如果在10Ω采样电阻上输出31.7mV。MCU算出的电压是31.7mV真实电压是380V那么RATIO 380 / 0.0317 ≈ 11987。代码里填上这个数显示的电压值就准了。3.4 烧录与上电调试的完整流程程序编译通过后会生成hex文件位于OBJ目录下。烧录方式看你的调试器ST-Link用STM32 ST-LINK Utility或者Keil自带的下载功能J-Link用J-Flash。Keil里配置好调试器型号点击下载按钮就能把程序写进单片机。注意下载前要把板子的BOOT0引脚设置成从Flash启动不然程序跑不起来。第一次上电别急着接三相电。先把程序单独烧进板子用万用表量一下OLED屏有没有供电看屏幕有没有显示初始界面。确认基本功能正常后用可调变压器从低压开始慢慢升压比如先从100V开始对比程序显示值和标准万用表读数看看偏差有多大。这个过程就是标定也是整个项目里最花时间的环节。4. 常见问题排查与实测经验4.1 显示值一直跳变不稳定这个现象很常见多半是采样端有干扰或者滤波没有做好。先检查互感器次级输出端的滤波电容一般会接一个0.1uF的瓷片电容如果没接高频噪声会被ADC原样采进来。另一个原因是采样没有做软件滤波比如中值滤波或滑动平均滤波程序里实现也不难连续采5次去掉最大最小值再取平均数据会稳很多。还有一点特别容易忽略DMA采集三相数据时如果三路通道的采样顺序跟代码里期望的不一致或者DMA传输半完成中断和完成中断的处理写反了数据就会错位显示值自然乱跳。建议先把三路ADC的原始值直接打印到串口用串口助手观察波形看是不是周期性的正弦样子是的话再谈后续算法不是的话先修硬件和DMA配置。4.2 显示电压比实际电压偏低且随电压升高偏差越大这种“比例性偏差”基本可以判定是分压系数问题。最常见的原因是你以为用的是120kΩ电阻实际焊接的时候用错了或者电阻精度不高。另一个原因是ADC参考电压不是精确的3.3V很多板子上的3.3V实际可能只有3.25V这1.5%的误差在分压比放大的情况下会被放大。解决办法是拿高精度万用表实测板子的参考电压然后把程序里的ADC_REF_VOLT改成实际值。如果偏低的情况只出现在某一相那大概率是那一相的前端运放偏置电压和其他两路不一致。这就要检查运放电路里的偏置电阻保证三路零偏值一致。程序标定的时候可以把每路的零点单独记录不要用一个统一值。4.3 程序编译报错开发环境各种“命令找不到”很多第一次打开工程的同学会在电脑上遇到一些环境问题。比如在命令行里敲个命令提示“不是内部或外部命令”多半是环境变量Path没配好。Keil本身倒不需要命令行但如果你后续要配合脚本自动化编译就得把C:\Keil_v5\ARM\ARMCC\bin加到系统Path里面去。另外如果下载的时候提示找不到ST-Link设备或者连接失败多半是驱动没装好去ST官网装个ST-Link驱动就好。这类问题看似跟项目无关但实际上卡住不少人。我的建议是先把环境理干净再折腾代码否则环境问题跟代码问题混在一起排查起来非常痛苦。4.4 实际项目中很容易忽视的几个隐患最后聊几点不写在教程里但实际项目会吃亏的细节。一是接线端子一定要做隔离和绝缘处理。三相电压表要直接接380V强电强电端和弱电端之间的距离要保持好PCB上要开隔离槽防止爬电。测试的时候就算是用小变压器供电也千万别用普通的杜邦线去戳强电安全第一。二是校准的时候一定要多取几个测试点。我习惯分别用100V、220V、380V三档校准最少测三个点再画一条校准曲线看是不是线性的。如果只有单点校准在电压范围两头误差会比较大。三是程序里的保护逻辑建议提前加。完整程序可能只做了测量显示没做超限报警。自己加也很简单在RMS计算结果出来之后跟预设的上限下限比较超过就点亮报警LED或控制继电器实测下来在电压不稳的场合很实用。5. 结束语一套能打底子的完整工程这套三相交流电压表程序我从解压到编译、烧录、标定走了一遍整体工程质量很扎实。它最大的价值不是那些漂亮的OLED界面而是把交流采样从硬件调理到软件算法这条完整的链路打通了。新手照着工程抄一遍理解ADC中断采样、RMS计算、互感器变比换算这些关键思路比单纯看教材上的公式管用得多。最后再分享一个小技巧如果你打算在这个基础上做自己的产品先把标定系数的存储位置放到EEPROM或者Flash末尾做成可以通过串口指令修改。这样出厂校准的时候就不用反复重新编译烧录程序生产线上能省下大量时间。本文还有配套的精品资源点击获取
返回列表