尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

基于51单片机的智能断路器保护系统设计与Proteus仿真实现

基于51单片机的智能断路器保护系统设计与Proteus仿真实现 简介一套基于51单片机Proteus仿真的多功能断路器开发设计资料面向单片机课程设计、电子竞赛及嵌入式入门者解决过压、欠压、过流、温度异常时的实时监测与自动断电保护问题。系统以51单片机为核心配合LCD1602液晶显示和按键操作可完成智能断路器的功能演示与二次开发。压缩包共59个文件大小68.13MB涵盖C语言源码、头文件、hex烧录文件、Proteus仿真图DSN、Altium Designer原理图SchDoc、元件清单Excel、操作演示视频及PDF预览文档从软件代码到硬件电路均有覆盖。目前已有58人学习下载适合需要快速搭建同类项目或理解断路器保护逻辑的读者。资料内还附带针对Proteus变压器仿真报错的偷懒替代方案能有效降低仿真失败概率配套视频和原理图便于对照理解电压、电流、温度的采集与判断流程可直接移植和修改。1. 断不了的电为什么一个断路器要上单片机你可能见过配电箱里那种热磁式断路器双金属片弯到一定程度就跳闸。但这个设计不一样——它用 STC89C52 这类 51 单片机实时盯着电压、电流和温度过压、欠压、过流、过热四个条件只要命中一个就主动切断负载。反直觉的地方在于Proteus 里仿真这个系统最容易翻车的不是 C 语言逻辑而是变压器模型。很多人把代码调通了却卡在变压器仿真报错上误以为是自己电路画错了。这套开发包的价值就在于它把这个问题绕了过去并且给出了完整的 Proteus 仿真图、Keil 源码、AD 原理图和演示视频适合正在做 51 单片机课设、或者想把传统断路器改造成数字化采集原型的人。下面我按采样链路、软件调度、仿真排错的顺序把这个项目拆开讲。2. 采样链路设计从 220V 到 ADC0832 的量程匹配2.1 电压通道变压器降压后还要过电阻分压电网侧的 220V 交流不能直接进单片机ADC0832 的模拟输入范围是 0~5V直接接必烧。常见做法是先用变压器把 220V 降到 5~9V 的交流再经过整流桥和滤波电容变成直流然后通过电阻分压网络把电压压到 2~4V 之间给 ADC 留出裕量。这里要强调一个容易被忽略的点分压电阻的阻值选择不是随便算的。假设整流滤波后是 5V 直流你希望 ADC 满量程对应 300V 交流留出 30% 的过压检测余量那 5V 对应的分压比就是 300/220 ≈ 1.36 倍余量。我一般取分压电阻 R110kΩ、R23.3kΩ算下来输出约 1.24V220V这个电压落在 ADC 线性度最好的区间。需要改量程时优先动 R2 而不是 R1因为 R1 太大容易引入噪声。2.2 电流通道互感器加采样电阻别直接用 ADC 量电流采样用电流互感器CT二次侧输出的是电流信号必须并联一个采样电阻转成电压。这个电阻的选值决定了电流检测的灵敏度。比如额定电流 5A 的 CT变比 1000:1二次侧电流 5mA如果你希望满量程 3V 输出采样电阻就是 3V/5mA 600Ω。实际取 510Ω 或 620Ω 都可以用 Proteus 仿真时调到满量程不削顶就行。采样电阻上出来的电压带交流纹波必须加一阶 RC 低通滤波。截止频率我习惯设在 100Hz 左右R10kΩ、C0.1μF算下来截止频率约 159Hz能把 50Hz 基波保留、高次谐波滤掉一大部分。注意滤波电容不要太大否则响应变慢断路器就真的变成慢断了。2.3 ADC0832 双通道轮流采样ADC0832 是 8 位双通道 ADC正好用 CH0 采电压、CH1 采电流温度可以接到 CH2——但 0832 只有两个输入通道所以温度信号要么和电流通道分时复用要么用 4051 模拟开关扩展。这个项目里温度检测用的是 NTC 热敏电阻加固定电阻分压接到 ADC0832 的一个通道采样率不需要高1 秒刷一次足够。表典型采样通道参数通道信号来源分压/转换ADC 输入范围采样周期CH0变压器次级整流滤波10k3.3k 分压0~5V20msCH1电流互感器 采样电阻620Ω 采样0~5V20msCH2/NTC10kΩ 分压3.3k 上拉 NTC0~5V500msNTC 接法注意一点分压电阻要放在高端、NTC 放在低端这样温度升高时 ADC 读数变大判断过热的逻辑更直观——温度越高NTC 阻值下降分压点电压上升。3. 软件架构主循环、ADC 读取与保护逻辑优先级3.1 主循环框架定时采样不让保护逻辑阻塞这个系统的软件核心不是中断多复杂而是要让采样、显示、按键、保护判断各干各的互不阻塞。我拆解出来的代码结构是主循环里用while(1)轮询标志位Timer0中断里置adc_flag主循环检测到标志后去采 ADC、算数值、再判断阈值。// 主循环调度框架 void main(void) { Timer0_Init(); // 定时 20ms产生采样节拍 LCD1602_Init(); while(1) { if(adc_flag) // 20ms 到开始一次采样 { adc_flag 0; voltage Read_ADC0832(CH0); // 读电压通道 current Read_ADC0832(CH1); // 读电流通道 temp Read_ADC0832(CH2); // 读温度通道 Process_Protection(); // 阈值判断 继电器控制 Display_Update(); // 刷新 LCD Key_Scan(); // 扫描按键 } } }这个框架的好处是采样周期恒定不会因为 LCD 刷屏慢导致保护响应延迟。Process_Protection()必须在Display_Update()之前调用——如果显示用掉了 50ms而此时电流已经过流晚一步断电可能就让负载烧了。保护好于显示这个顺序不能反。3.2 ADC0832 的时序读取代码ADC0832 用三线制 SPI 兼容时序时钟由单片机产生。它有个特点前三个时钟周期写 DI 配置通道之后 DI 变为高阻DO 输出转换结果。读数据时要先假装写一个停止位然后才能读取。很多刚从 0809 转过来的人在这卡住。// 读取 ADC0832 单通道数据 unsigned char Read_ADC0832(unsigned char ch) { unsigned char i, dat 0; CS 0; CLK 0; DI 1; _nop_(); // 起始位 CLK 1; _nop_(); CLK 0; DI 1; _nop_(); // SGL1单通道模式 CLK 1; _nop_(); CLK 0; DI ch; _nop_(); // ODDch选择 CH0 或 CH1 CLK 1; _nop_(); CLK 0; DI 1; _nop_(); // 停止位之后 DI 释放 CLK 1; _nop_(); CLK 0; for(i 0; i 8; i) // 读取 8 位数据 { dat 1; CLK 1; _nop_(); dat | DO; // 在时钟高电平时采样数据 CLK 0; _nop_(); } CS 1; return dat; }注意第三个CLK 1; CLK 0;之前的DI chch 为 0 选 CH0为 1 选 CH1。这里最容易错的是把 ch 定义成通道编号而 0832 的 ODD 位决定的是输入引脚对。写代码时最好注释清楚Read_ADC0832(0)读的是电压通道Read_ADC0832(1)读的是电流通道。如果读回来永远是 0xFF 或 0x00先检查 CS 拉低时序再用示波器看 CLK 是否有上升沿——Proteus 里虚拟示波器可以挂上去直接看。3.3 阈值判断与优先级过流必须最优先保护逻辑不是简单的四个 if 并列而是有优先级过流和过压必须立刻断电欠压可以延迟几十毫秒避免电网瞬间波动误跳过热可以延迟更长。原因很简单过流可能烧线缆过压可能击穿绝缘这两个必须毫秒级响应欠压对阻性负载影响小但电机类负载欠压运行会发热所以也要保护只是允许一点延迟。void Process_Protection(void) { if(current_ma OVER_CURRENT) // 过流阈值单位 mA { Relay OFF; // 立即断电 buzzer ON; // 驱动蜂鸣器 LCD_ShowString(Over Current!); } else if(voltage_mv OVER_VOLTAGE) // 过压阈值 { Relay OFF; LCD_ShowString(Over Voltage!); } else if(voltage_mv UNDER_VOLTAGE) // 欠压阈值 { under_voltage_cnt; if(under_voltage_cnt 5) // 连续 5 次采样100ms才动作 { Relay OFF; LCD_ShowString(Under Voltage!); } } else if(temp_c OVER_TEMP) // 温度阈值单位 0.1°C { Relay OFF; LCD_ShowString(Over Temp!); } else { Relay ON; // 正常状态恢复供电 under_voltage_cnt 0; buzzer OFF; } }阈值用宏定义放在头文件里。值怎么定看前面那个表假设 ADC 参考电压 5V8 位分辨率就是 5/255 ≈ 19.6mV 每 LSB。如果分压后 220V 对应 1.24V那 1 LSB 对应的原边电压就是 220 / (1.24 / 0.0196) ≈ 3.48V。所以要设过压阈值 242V就是242 / 3.48 ≈ 70写成宏#define OVER_VOLTAGE 70。每次换算都要带这个比例系数这是最容易出 bug 的地方。under_voltage_cnt这个变量是消抖用的它的存在让欠压保护不会因为负载启动瞬间的电压跌落而误跳。同理温度采样值我做了 4 次滑动平均再判断避免热敏电阻的接触噪声导致误报警。4. Proteus 仿真变压器报错的根因与偷懒方案4.1 为什么 Proteus 的变压器模型总报错Proteus 的变压器元件TRAN-2P2S 之类仿真时经常报Transformer primary current too high或者直接不收敛。原因是 Proteus 的变压器模型用的是理想变压器加非线性电感当负载侧电流突变或者仿真步长不合适时电感电流会瞬间冲高求解器直接发散。这不是你的电路问题是软件数值计算的问题。常见触发场景有三种一是负载侧接了整流大电容上电瞬间电容相当于短路冲击电流远大于变压器额定电流求解器崩掉。二是仿真步长设置太小Proteus 在细微时间步长里反复迭代电感微分方程数值不收敛。三是变压器绕组的电阻值设置不合理——零电阻或接近零电阻导致电流无约束增长。我验证下来的解决顺序是先把仿真步长从默认的 10ms 改成 1ms 甚至 500us在菜单 System Animation Options 里改绝大多数报错会消失。如果还报就给变压器副边串一个 0.1Ω 的小电阻限制冲击电流尖峰。再不行才考虑换模型。4.2 偷懒仿真方案的取舍用可控直流源替代变压器这套资源里的偷懒仿真图绕开了变压器直接用 DC 电源接到采样分压电路的输入端用一个电位器模拟电压波动。你旋转电位器时单片机读到的电压值会跟着变一旦超过阈值继电器就跳——这完美覆盖了我们验证保护逻辑的需求。图偷懒方案信号链DC 源 → 电位器 → 分压网络 → ADC0832 → 51 单片机 → 继电器 → LED/蜂鸣器这个方案的学习价值在哪它把交流侧真实波形和控制逻辑验证解耦了。做课设时你只需要让老师看到电压超过 242V 时断路器跳闸而不是我复现了一个工频正弦波。但代价是你验证不了整流滤波的波形真实度更验证不了交流采样时的真有效值计算。如果想要更接近真实用 AC 电源加整流桥自己搭一个简单的交流采样前端然后用TRANSFORMER也不迟——但会频繁炸仿真。4.3 仿真资源清单与关键器件选型表Proteus 器件清单器件Proteus 关键字参数设置作用单片机AT89C51 / STC89C52晶振 12MHz主控ADCADC0832参考电压 5V双通道采样LCDLM016L16x2 字符屏显示电位器POT-LIN10kΩ 或 50kΩ模拟电压/温度变化继电器RELAY线圈 5V触点 SPST控制通断蜂鸣器BUZZER5V 有源报警NTCTHERMISTOR10kΩ25°C温度传感POT-LIN 是 Proteus 里最常用的线性电位器双击可以调节阻值百分比。仿真时把电位器滑动端接到 ADC 输入调节百分比就等于调节模拟量大小。我习惯同时放三个电位器分别标注 Voltage AdjustCurrent AdjustTemp Adjust运行仿真时直接拖滑块比改代码改源文件高效得多。4.4 排错对照表仿真现象与处理手段现象可能原因处理变压器报 primary current too high次级大电容上电冲击副边串 0.1Ω 电阻仿真速度极慢步长太细或器件过多去掉示波器步长调到 1msLCD 无显示但有背光对比度引脚悬空LCD 的 V0 接 1kΩ 到 GND按键无反应端口没有上拉使能 P0 内部上拉或外接 10k 排阻继电器一直吸合阈值宏定义错误检查电流比较的单位是否一致ADC 读值恒为 0CS 时序提前释放确保 CS 在整个读过程保持低电平这六条是我在自己仿真时踩过的坑尤其是 LCD 对比度这个Proteus 里的 LM016L 如果 V0 不接地显示会出现方块但是不出字符很容易误判成代码问题。5. 一阶校正技巧用两点线性插值把 ADC 读数变成实际值代码里voltage Read_ADC0832(CH0)拿到的只是 0~255 的整数不能直接拿来和阈值比较。前面我提到用比例系数换算但真实情况下分压电阻有误差、ADC 有偏移误差算出来的结果可能偏 5% 以上。我一般会写一个两点校正的线性插值函数// 两点校正在 Proteus 里分别设置两个已知输入值 // 记录 ADC 输出然后做线性映射 unsigned int Adc_To_Voltage(unsigned char adc_val) { // 校正点1ADC值 adc1 对应 实际电压 v1 // 校正点2ADC值 adc2 对应 实际电压 v2 #define ADC_POINT1 51 // 实际电压约 1.0V #define VOLT_POINT1 1000 // 单位 mV #define ADC_POINT2 204 // 实际电压约 4.0V #define VOLT_POINT2 4000 // 单位 mV unsigned int volt 0; // 斜率 (v2 - v1) / (adc2 - adc1)按 10 倍放大避免小数 volt (unsigned int)(adc_val - ADC_POINT1) * (VOLT_POINT2 - VOLT_POINT1) * 10 / (ADC_POINT2 - ADC_POINT1); volt volt / 10 VOLT_POINT1; return volt; }这个函数把 ADC 的 0~255 线性映射到实际电压值单位 mV。两个校正点怎么取一个取在额定值 70% 处一个取在过压阈值上方一点这样实际工作区间内映射误差最小。改变硬件分压比后只需要重新标定ADC_POINT1和ADC_POINT2两个值不用改判断逻辑——这比在Process_Protection()里直接乘比例系数好维护得多。注意一个细节volt的中间计算乘了 10 又除回是为了保留一位小数精度。如果用整数直接算(204-51)去除(4000-1000)是整除精度直接丢到 20mV 以上。这个先放大再缩小的写法在 51 这种 8 位单片机上不算浪费因为总共就几次整数乘法运算量远小于一次 LCD 刷屏。最后验证方法也给你在 Proteus 里把电位器旋转到 50% 位置读一下 LCD 显示值再用虚拟电压表实测 ADC 引脚的电压对照一下换算结果。两者差值在 ±30mV 以内校正就过关了。用同样的方法标定电流通道和温度通道三个通道都标完这台多功能断路器才算真正能拿出去演示——注意标定电流通道时用电流互感器的次级电压作为标准值不要在 Proteus 里硬造一个 20A 的电流源那反而容易让仿真卡死。本文还有配套的精品资源点击获取
返回列表