📋 项目概述
这是一个完整的智能鱼缸自动补水系统,使用 AI8051U 单片机实现全自动水位控制。系统通过三个水位传感器监测水位状态,自动控制水泵进行补水,并具备完善的三重保护机制。
🎯 实现功能
- 自动检测水位低于下限
- 自动启动水泵补水
- 水位达到上限自动停止
- 异常情况报警提示
- 看门狗防死机
⚙️ 技术参数
- 芯片:AI8051U(C251内核)
- 水位检测:3路低电平有效
- 控制输出:1路继电器驱动
- 补水时间:最长45秒
- 看门狗:约1秒溢出周期
🔌 硬件连接
系统使用3个水位传感器检测水位,配合1个继电器控制水泵。以下是详细的引脚定义:
引脚定义表
| 引脚 | 功能 | 说明 |
|---|---|---|
| P01 | 低水位传感器 | 水位低于下限时触发(低电平有效) |
| P02 | 中水位传感器 | 水位达到中部时触发(低电平有效) |
| P03 | 高水位传感器 | 水位达到上限时触发(低电平有效) |
| P20 | 补水继电器 | 0=启动水泵,1=停止水泵 |
| P27 | 报警输出 | 异常时输出低电平驱动报警 |
硬件连接示意图
┌─────────────────────────────────────────────────────────────────┐
│ 智能鱼缸补水系统 │
│ 硬件连接示意图 │
└─────────────────────────────────────────────────────────────────┘
┌──────────────┐ ┌──────────────┐
│ AI8051U │ │ 鱼 缸 │
│ 开发板 │ │ │
├──────────────┤ │ ══════════ │ ← 高水位传感器(P03)
│ │ ┌───────────┐ │ ══════════ │ ← 中水位传感器(P02)
│ P01 ◄───────┼────│ 低水位 │ │ ══════════ │ ← 低水位传感器(P01)
│ P02 ◄───────┼────│ 中水位 │ │ │
│ P03 ◄───────┼────│ 高水位 │ │ ~~~ │
│ │ └───────────┘ │ (鱼) │
│ P20 ────────┼────┐ │ ~~~ │
│ │ │ ┌────────┐ ┌─────┐ │ │
│ P27 ────────┼────┴──│ 继电器 │─── │水泵 │ │ ▓▓▓ │
│ │ └────────┘ └─────┘ │ (水) │
└──────────────┘ └──────────────┘
接线说明:
┌────────────────────────────────────────────────────────────────┐
│ 水位传感器(浮球式): │
│ ├── 公共端(COM) ──► 接开发板 GND │
│ ├── 低水位(LOW) ──► 接 P01(通过10K上拉电阻到VCC) │
│ ├── 中水位(MID) ──► 接 P02(通过10K上拉电阻到VCC) │
│ └── 高水位(HIGH) ──► 接 P03(通过10K上拉电阻到VCC) │
│ │
│ 补水继电器模块: │
│ ├── VCC ──► 开发板 5V │
│ ├── GND ──► 开发板 GND │
│ ├── IN ──► 开发板 P20 │
│ └── COM ──► 水泵电源正极 │
│ NO ──► 水泵电源负极(继电器闭合时导通) │
│ │
│ 报警LED: │
│ ├── 正极 ──► P27(串联470Ω电阻) │
│ └── 负极 ──► GND │
└────────────────────────────────────────────────────────────────┘
💡 传感器工作原理
水位传感器采用浮球式机械开关,当水位上升到触发位置时,浮球触动微动开关,使其导通。由于电路设计上使用低电平有效,所以传感器导通时对应引脚为低电平(0),未触发时为高电平(1)。
⚙️ 工作原理
控制逻辑流程
1
系统初始化
配置所有IO端口为双向模式,初始化水泵为停止状态,启动看门狗定时器
2
读取水位状态
实时读取P01、P02、P03三个水位传感器的状态(低电平=到达该水位)
3
判断补水条件
只要高水位未触发(P03=1),就启动水泵补水,直到高水位传感器触发
4
执行保护检测
在补水过程中持续监测三重保护条件,发现异常立即停泵并报警
5
循环执行
每次循环结束前喂狗(清零看门狗计数器),防止系统复位
水位与传感器状态对应关系
| 水位状态 | 低水位(P01) | 中水位(P02) | 高水位(P03) | 水泵动作 |
|---|---|---|---|---|
| 水位过低 | 1 (未触) | 1 (未触) | 1 (未触) | 启动补水 |
| 水位偏低 | 0 (触发) | 1 (未触) | 1 (未触) | 启动补水 |
| 水位适中 | 0 (触发) | 0 (触发) | 1 (未触) | 启动补水 |
| 水位正常 | 0 (触发) | 0 (触发) | 0 (触发) | 停止补水 |
🛡️ 三重保护机制
为了确保系统在各种异常情况下都能安全运行,本系统设计了三重保护机制:
🛑 第一重保护:高水位触发立即停泵(硬保护)
当高水位传感器触发时,立即关闭水泵。这是最直接的物理保护,不依赖任何软件逻辑。
- 触发条件:
P03 == 0(高水位到达) - 执行动作:
P20 = 1(停止水泵) - 保护目的:防止水溢出鱼缸
⚠️ 第二重保护:中水位超时强制停泵(软保护)
当中水位触发后,如果在规定时间内未检测到高水位,则判断高水位传感器失效,强制停泵报警。
- 触发条件:中水位触发后等待超过
MAX_LOW_HOLD(10秒) - 执行动作:停止水泵 + 置位报警标志
alarm_flag = 1 - 保护目的:防止高水位传感器故障导致无限补水
⚠️ 第三重保护:总补水时间超时停泵(超时保护)
如果水泵持续运行时间超过最大允许时间,则判断系统异常(水泵故障、管路漏水等),强制停泵报警。
- 触发条件:连续补水时间超过
MAX_WATER_TIME(45秒) - 执行动作:停止水泵 + 置位报警标志
alarm_flag = 1 - 保护目的:防止水泵故障、管路破裂等导致水灾
✅ 看门狗保护
看门狗定时器用于防止程序死循环或跑飞。如果主循环卡死无法喂狗,约1秒后看门狗会复位系统。
- 配置:256分频,约1秒溢出周期
- 喂狗位置:主循环开头,每次迭代必须执行
- 保护目的:防止程序异常导致无法响应
📝 代码详解
1. 头文件与宏定义
ai8051u.h - 芯片头文件
/************************** 智能鱼缸自动补水系统 ************************** * 芯片:AI8051U(C251内核) * 传感器(低电平有效): * P01 – 低水位(水位低于下限) * P02 – 中水位(水位达到中部) * P03 – 高水位(水位达到上限) * 执行器: * P20 – 补水继电器(0=启动,1=停止) ************************************************************************/ #include "ai8051u.h" // AI8051U寄存器定义 #include "ai_usb.h" // USB库(保留未使用)
2. 超时阈值定义
阈值定义
/*--------------------- 超时阈值定义(需实际标定) ---------------------*/ // 假设主循环周期约1ms,正常补水30秒,则: #define MAX_WATER_TIME 45000 // 最长补水时间 45秒(1.5倍冗余) #define MAX_LOW_HOLD 10000 // 中水位触发后等待高水位的超时 10秒 /*--------------------- 看门狗配置 ---------------------*/ // WDT_CONTR 寄存器位定义(STC标准) #define WDT_ENABLE 0x80 // 使能看门狗 #define WDT_CLR 0x08 // 清零看门狗计数器 #define WDT_PRESCALE 0x04 // 预分频:256分频(约1秒溢出,需根据时钟调整) // 喂狗宏 - 每次调用都会重置看门狗计数器 #define FEED_WDT() WDT_CONTR = WDT_ENABLE | WDT_CLR | WDT_PRESCALE
3. 主函数 - 初始化部分
main() 函数 - 初始化
/*--------------------- 主函数 ---------------------*/ void main(void) { // ***** 所有变量定义必须放在函数开头(C89规则) ***** unsigned char pump_status = 0; // 水泵状态:0=停止,1=运行 unsigned int water_time = 0; // 本次补水累计循环次数 unsigned int low_hold_time = 0; // 中水位触发后的等待计数 unsigned char alarm_flag = 0; // 报警标志(1=报警) unsigned char low, mid, high; // 传感器状态暂存(用于赋值) // ---------- 端口初始化:全部设为准双向模式 ---------- P0M0 = 0; P0M1 = 0; P1M0 = 0; P1M1 = 0; P2M0 = 0; P2M1 = 0; P3M0 = 0; P3M1 = 0; P4M0 = 0; P4M1 = 0; P5M0 = 0; P5M1 = 0; // ---------- 水泵初始状态:停止(继电器高电平断开) ---------- P20 = 1; // ---------- 看门狗初始化 ---------- WDT_CONTR = WDT_ENABLE | WDT_PRESCALE | WDT_CLR;
4. 主函数 - 主循环逻辑
main() 函数 - 主循环
// ---------- 主循环 ---------- while(1) { // 喂狗(每次循环必须执行,防止复位) FEED_WDT(); // 读取三个水位传感器(低电平表示到达该水位) low = P01; mid = P02; high = P03; /************* 第一重保护:高水位触发立即停止 *************/ if (high == 0) // 高水位已到达(传感器导通) { P20 = 1; // 关闭补水 pump_status = 0; // 标记停止 water_time = 0; // 清除补水计时 low_hold_time = 0; // 清除等待计数 alarm_flag = 0; // 清除报警(水位正常) continue; // 跳过后续逻辑,开始下一循环 } /************* 第二重保护:中水位作为辅助上限 *************/ // 当中水位触发后,若长时间未检测到高水位,则判断高水位传感器失效 if (mid == 0) // 中水位已到达 { low_hold_time++; // 累计中水位保持时间 if (low_hold_time > MAX_LOW_HOLD) // 超时 { P20 = 1; // 强制停泵 pump_status = 0; alarm_flag = 1; // 置报警标志 water_time = 0; continue; } } else // 中水位未触发(水位低于中水位) { low_hold_time = 0; // 清零等待计数 } /************* 第三重保护:总补水时间超限 *************/ // 若水泵持续运行超过最大允许时间,认为系统异常 if (pump_status == 1) // 当前正在补水 { water_time++; // 累计补水时间 if (water_time > MAX_WATER_TIME) // 超时 { P20 = 1; // 强制停泵 pump_status = 0; alarm_flag = 1; water_time = 0; continue; } } /************* 正常补水逻辑(满足三条需求) *************/ // 只要高水位未触发(high == 1),就启动补水 if (high == 1) // 高水位未到达 { P20 = 0; // 启动水泵 pump_status = 1; // 标记运行 } else { P20 = 1; pump_status = 0; } /************* 报警输出(可选) *************/ if (alarm_flag) P27 = 0; else P27 = 1; } }
💾 完整代码
以下是本项目的完整源代码,可以直接复制使用或下载到本地编译。
water_refill.c - 智能鱼缸自动补水系统完整代码
/************************** 智能鱼缸自动补水系统 **************************
* 芯片:AI8051U(C251内核)
* 传感器(低电平有效):
* P01 – 低水位(水位低于下限)
* P02 – 中水位(水位达到中部)
* P03 – 高水位(水位达到上限)
* 执行器:
* P20 – 补水继电器(0=启动,1=停止)
*
* 控制需求:
* 1. 三个均未触发(水位低于低水位)→ 启动补水,直至高水位触发停止。
* 2. 仅低水位触发(水位在低-中之间)→ 启动补水,直至高水位触发停止。
* 3. 低+中水位触发(水位在中-高之间)→ 启动补水,直至高水位触发停止。
*
* 保护机制(三重):
* ① 高水位触发立即停泵(硬保护)
* ② 中水位触发后长时间未到高水位 → 认为高水位失效,强制停泵报警
* ③ 总补水时间超限 → 水泵/管路异常,强制停泵报警
*
* 看门狗:启用,溢出周期约1秒,主循环喂狗。
************************************************************************/
#include "ai8051u.h" // AI8051U寄存器定义
#include "ai_usb.h" // USB库(保留未使用)
/*--------------------- 超时阈值定义(需实际标定) ---------------------*/
// 假设主循环周期约1ms,正常补水30秒,则:
#define MAX_WATER_TIME 45000 // 最长补水时间 45秒(1.5倍)
#define MAX_LOW_HOLD 10000 // 中水位触发后等待高水位的超时 10秒
/*--------------------- 看门狗配置 ---------------------*/
// WDT_CONTR 寄存器位定义(STC标准)
#define WDT_ENABLE 0x80 // 使能看门狗
#define WDT_CLR 0x08 // 清零看门狗计数器
#define WDT_PRESCALE 0x04 // 预分频:256分频(约1秒溢出,需根据时钟调整)
// 喂狗宏
#define FEED_WDT() WDT_CONTR = WDT_ENABLE | WDT_CLR | WDT_PRESCALE
/*--------------------- 主函数 ---------------------*/
void main(void)
{
// ***** 所有变量定义必须放在函数开头(C89规则) *****
unsigned char pump_status = 0; // 水泵状态:0=停止,1=运行
unsigned int water_time = 0; // 本次补水累计循环次数
unsigned int low_hold_time = 0; // 中水位触发后的等待计数
unsigned char alarm_flag = 0; // 报警标志(1=报警)
unsigned char low, mid, high; // 传感器状态暂存(用于赋值)
// ---------- 端口初始化:全部设为准双向模式 ----------
P0M0 = 0; P0M1 = 0;
P1M0 = 0; P1M1 = 0;
P2M0 = 0; P2M1 = 0;
P3M0 = 0; P3M1 = 0;
P4M0 = 0; P4M1 = 0;
P5M0 = 0; P5M1 = 0;
// ---------- 水泵初始状态:停止(继电器高电平断开) ----------
P20 = 1;
// ---------- 看门狗初始化 ----------
WDT_CONTR = WDT_ENABLE | WDT_PRESCALE | WDT_CLR;
// ---------- 主循环 ----------
while(1)
{
// 喂狗(每次循环必须执行,防止复位)
FEED_WDT();
// 读取三个水位传感器(低电平表示到达该水位)
low = P01;
mid = P02;
high = P03;
/************* 第一重保护:高水位触发立即停止 *************/
if (high == 0) // 高水位已到达(传感器导通)
{
P20 = 1; // 关闭补水
pump_status = 0; // 标记停止
water_time = 0; // 清除补水计时
low_hold_time = 0; // 清除等待计数
alarm_flag = 0; // 清除报警(水位正常)
continue; // 跳过后续逻辑,开始下一循环
}
/************* 第二重保护:中水位作为辅助上限 *************/
// 当中水位触发后,若长时间未检测到高水位,则判断高水位传感器失效
if (mid == 0) // 中水位已到达
{
low_hold_time++; // 累计中水位保持时间
if (low_hold_time > MAX_LOW_HOLD) // 超时
{
P20 = 1; // 强制停泵
pump_status = 0;
alarm_flag = 1; // 置报警标志
water_time = 0;
continue;
}
}
else // 中水位未触发(水位低于中水位)
{
low_hold_time = 0; // 清零等待计数
}
/************* 第三重保护:总补水时间超限 *************/
// 若水泵持续运行超过最大允许时间,认为系统异常(水泵/管路故障)
if (pump_status == 1) // 当前正在补水
{
water_time++; // 累计补水时间
if (water_time > MAX_WATER_TIME) // 超时
{
P20 = 1; // 强制停泵
pump_status = 0;
alarm_flag = 1;
water_time = 0;
continue;
}
}
/************* 正常补水逻辑(满足三条需求) *************/
// 只要高水位未触发(high == 1),就启动补水
// 此条件覆盖:
// - 三个都未触发(low=1, mid=1, high=1)→ 补水(需求1)
// - 仅低水位触发(low=0, mid=1, high=1)→ 补水(需求2)
// - 低+中触发(low=0, mid=0, high=1)→ 补水(需求3)
if (high == 1) // 高水位未到达
{
P20 = 0; // 启动水泵
pump_status = 1; // 标记运行
// water_time 会在下一轮循环中由第三重保护累加
}
else
{
// 高水位触发(理论上已被第一重拦截,此处作为备胎)
P20 = 1;
pump_status = 0;
}
/************* 报警输出(可选) *************/
// 若报警标志置1,可点亮LED或通过USB上报
if (alarm_flag) P27 = 0; else P27 = 1;
}
}
使用说明
- 将
ai8051u.h和ai_usb.h头文件放到工程目录 - 使用 Keil C51 或 SDCC 编译器编译
- 通过 ISP 工具烧录到 AI8051U 芯片
- 根据实际补水时间调整 MAX_WATER_TIME 和 MAX_LOW_HOLD 阈值
- P27 可连接蜂鸣器或 LED 用于报警提示