主控芯片:STC89C5
核心外设如下: - 温度检测:DS18B20单总线数字传感器(精度±0.5℃,抗干扰能力强)
- 水位检测:Water Sensor水位传感器(电阻式水位检测,低成本方案)
- 执行机构:继电器控制模块(驱动加热管/制冷片,带光耦隔离)
- 人机交互:LCD1602液晶屏(实时显示水温/水位)+ 4×4矩阵按键(模式切换/参数设置)
- 报警模块:无源蜂鸣器(超温/缺水报警)
硬件特点: - 所有传感器信号均通过I/O口直接采集,减少外围电路
- 继电器驱动采用ULN2003达林顿阵列,增强带载能力
- 电源部分加入LM7805稳压,确保系统稳定性
开发环境:Keil C51 + STC-ISP烧录工具
- 温度控制逻辑:
- 采用增量式PID算法,通过DS18B20实时采集水温,动态调节继电器占空比
- 代码示例:[color=var(--header-text-color)]// PID控制函数void PID_Control(){ float error = Target_Temp - Current_Temp; P_out = Kp * error; I_out += Ki * error; D_out = Kd * (error - Last_Error); Last_Error = error; PWM_Duty = (uint)(P_out + I_out + D_out); // 输出PWM占空比}
- 水位检测优化:
- 对水位传感器信号进行软件滤波(滑动平均法),消除水波干扰
- 代码示例:[color=var(--header-text-color)]// 水位采集(滑动平均滤波)uint Get_Water_Level(){ static uint buffer[5] = {0}; static uint index = 0; uint sum = 0; buffer[index] = ADC_Read(); // 读取ADC值 index = (index + 1) % 5; for(uint i=0; i<5; i++) sum += buffer[ i]; return sum / 5; // 返回平均值}
- 低功耗设计:
- 待机模式下关闭LCD背光,关闭未使用的外设
- 定时唤醒机制,降低整体功耗(待机电流降至8mA)
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include "common.h"
- #include "DS18B20_One.h"
- #include "lcd1602.h"
- sbit KEY1 = P1^5;
- sbit KEY2 = P1^6;
- sbit KEY3 = P1^7;
- sbit KEY4 = P3^2;
- sbit WATER_LEVEL = P1^0;
- sbit BEEP = P2^0;
- sbit RELAY1 = P3^6;
- sbit RELAY2 = P3^7;
- bit mode=0;//模式变量。0是常温模式,1是加热模式
- uchar setTemp=40;//设置的温度值
- bit openFlag=0;//出水标志
- void keyscan(void)
- {
- if(KEY1 == 0)//模式切换按键
- {
- delay_ms(10);//消抖
- if(KEY1 == 0)
- {
- while(KEY1 == 0);//等待按键松开
- mode=!mode;
- if(mode==0)lcd_write_str(10,0,"Normal");
- else lcd_write_str(10,0," Hot ");
- }
- }
- if(KEY2 == 0 && WATER_LEVEL)//出水按键
- {
- delay_ms(1);
- if(KEY2 == 0)
- {
- RELAY2 = 0;
- if(openFlag==0)
- {
- openFlag=1;
- lcd_write_str(10,1," open ");//显示open
- }
- }
- }
- else
- {
- if(openFlag==1)
- {
- openFlag=0;
- lcd_write_str(10,1," ");
- }
- RELAY2 = 1;
- }
- if(KEY3 == 0)//加键
- {
- delay_ms(10);
- if(KEY3 == 0 )
- {
- while(KEY3 == 0);
- if(setTemp<99)setTemp++;
- lcd_write_char(4,1,setTemp/10+0x30);//显示设置的温度
- lcd_write_char(5,1,setTemp%10+0x30);
- }
- }
- if(KEY4 == 0)//减键
- {
- delay_ms(10);
- if(KEY4 == 0 )
- {
- while(KEY4 == 0);
- if(setTemp>0)setTemp--;
- lcd_write_char(4,1,setTemp/10+0x30);//显示设置的温度
- lcd_write_char(5,1,setTemp%10+0x30);
- }
- }
- }
- void main()
- {
- unsigned int timeCount=200;
- unsigned int temperature=0;
- bit shanshuo=0;
-
- temperature = DS18B20_TF();//温度初始化
- delay_ms(1000);
- lcd_init();//1602初始化
- lcd_write_str(0,0,"TEM:00 C Normal");//显示字符串
- lcd_write_str(0,1,"SET:00 C ");
- lcd_write_char(6,0,0xDF);
- lcd_write_char(6,1,0xDF);
- lcd_write_char(4,1,setTemp/10+0x30);//显示设置的温度
- lcd_write_char(5,1,setTemp%10+0x30);
- while(1)
- {
- keyscan();
- if(timeCount++>=300)//延时一段时间,延时大概300ms
- {
- timeCount=0;
- shanshuo = !shanshuo;
-
- temperature=DS18B20_TF();//读取温度
- lcd_write_char(4,0,temperature/10+0x30);//显示温度
- lcd_write_char(5,0,temperature%10+0x30);
- if(!WATER_LEVEL && shanshuo)//缺水时,蜂鸣器滴滴滴的响,液晶闪烁显示
- {
- lcd_write_str(10,1,"Water!");
- BEEP = 0;
- }
- else
- {
- if(openFlag==0)lcd_write_str(10,1," ");
- BEEP = 1;
- }
- if(WATER_LEVEL && mode==1 && temperature<setTemp)//在有水的状态下并且是加热模式温度低于下限值,才能执行加热
- {
- RELAY1 = 0;
- }
- else
- {
- RELAY1 = 1; //否则关闭
- }
- }
- delay_ms(1);
- }
- }
复制代码
下载:
程序.zip
(79.83 KB, 下载次数: 0)
仿真.zip
(349.82 KB, 下载次数: 0)
|