【智能温控风扇】
一、设计任务
设计内容
以单片机作为核心控制器件,选取DS18B20温度传感器作为数字温度计,实时测量并反应实际温度,编写程序,采集实时温度并通过数码管显示当前温度,通过按键设置的温度上、下限,将其与实际温度的比较结果,作为控制风扇的开关及档位的依据:
当实际温度低于所设温度下限时,风扇关闭,为0档;
当实际温度高于温度下限,低于温度上限时,风扇转速一般,为1档;
当温度高于温度上限时,风扇转速最快,为2档;设计目的
完成基于单片机的温控风扇的课程设计作品,通过课程设计中对原理图、PCB图、PTOTEUS仿真等的实际操作,熟悉相关开发软件,了解设计流程,加深对单片机、DS18B20的了解;此外,熟悉焊接流程,学会调试,加强动手能力。
二、硬件介绍
硬件组成
电路板、STC89C52单片机、DS18B20、12M晶振、六角自锁开关、三极管若干、电容若干、电阻若干、开关若干、导线若干、风扇等
主要功能描述
1)STC89C52单片机
核心控制器件,执行程序代码,接收从DS18B20传回的实时温度,并输出信号控制数码管的显示,根据扫描按键的通断情况执行相应的设置温度上限、设置温度下限的功能切换,根据接收到的实际温度与设置温度上、下限的比较结果,输出信号控制风扇的档位
2)DS18B20温度传感器
实时测量实际温度,并通过相关协议,将测量到的实际温度反映给单片机
3)六角自锁开关
是整个电路的电源总开关
4)三极管
E、B、C三脚分别与电源、与单片机I/O口(经电阻)、与数码管位选或风扇正极相连,相当于电力开关,使电路得以依据单片机I/O口输出信号的高低实现三极管的通断,从而控制数码管显示的选位及风扇档位的调节
5)电容及12M晶振
瓷片电容与晶振构成单片机的外部振荡信号,是单片机实际应用中最小系统的组成部分;电解电容接在电源与地之间,起滤波的作用
6)电阻
起保护电阻的作用,控制单片机输出端口上的电流大小,防止因电流过大对电路造成损坏、控制数码管段选中的电流大小,防止因电流变化等问题影响电路及数码管的显示亮度;此外,在PROTEUS仿真中,需要在位选出接入电阻,方可进行正常仿真,但实际设计中不需要这里的电阻
DS18B20简介
DS18B20内部结构图
DS18B20特性:
1)独特的单线接口 只需 1 个接口引脚即可通信
2)多点 multidrop 能力使分布式温度检测应用得以简化
3)不需要外部元件
4)可用数据线供电
5)不需备份电源
6)测量范围从-55 至+125 增量值为 0.5 等效的华氏温度范围是-67 F至257 F
7)增量值为 0.9 F
8)以 9 位数字值方式读出温度
9)在1秒(典型值)内把温度变换为数字
10)用户可定义的非易失性的温度告警设置
11)告警搜索命令识别和寻址温度在编定的极限之外的器件 温度告警情况
12)应用范围包括恒温控制 工业系统 消费类产品 温度计或任何热敏系统
DS1820数字温度计以9位数字量的形式反映器件的温度值,独特的单线接口 只需 1 个接口引脚即可通信,信息经过单线接口送入 DS1820 或从 DS1820 送出 因此从中央处理器到 DS1820 仅需连接一条线(和地)。DSl820 的测量范围从-55 到+125 增量值为 0.5 可在 l s(典型值)内把温度变换成数字。读、写和完成温度变换所需的电源可以由数据线本身提供,而不需要外部电源。
在单线端口条件下,必须先建立 ROM 操作协议,才能进行存储器和控制操作。因此,控制器必须首先提供下面 5 个 ROM 操作命令之一:
1)读 ROM,2)匹配 ROM,3)搜索 ROM,4)跳过 ROM,5)报警搜索。
三、系统原理
原理图、PROTEUS仿真图、PCB图、3D立体图及实际电路连接图
温控风扇原理图
PROTEUS仿真图
PCB图
实际电路连接图程序设计
1)主程序
在进行主程序的初始化之后,获取当前温度,而后进入while循环,调用自动温控程序;自动温控函数里,先调用显示子程序,显示实际温度,随后扫描按键,若无按键按下,则直接比较实际温度与温度上、下限的大小,调节电机档位,也就是风扇的转速。
2)温度获取子程序
对DS18B20进行初始化,将采集得到的温度信息写入寄存器,而后启动温度转换,调用相关子程序,读取温度寄存器数据,并经由公式转换,求得实际温度,传入单片机,作为调节风扇档位的依据。
3)显示子程序
根据信号依次做出位选与段选操作,并调用延时子程序,方便用户观察数据。
4)按键扫描子程序
根据各端口的电平高低,判断按键是否按下,并进入相应的子程序,调节温度的上限或下限,对温度上、下限进行加、减设置。
5)程序代码
#include<reg51.h>#include<intrins.h> //包含头文件#define uchar unsigned char#define uint unsigned int //宏定义sbit dj=P2^3;//电机控制端接口sbit DQ=P2^4;//温度传感器接口//按键接口/sbit key1=P2^0;//设置温度sbit key2=P2^1;//温度加sbit key3=P2^2;//温度减//sbit w1=P3^7;sbit w2=P3^6;sbit w3=P3^5;sbit w4=P3^4;//数码管的四个位/共阴数码管段选//uchar table[22]={0xD7,0x11,0xCD,0x5D,0x1B,0x5E,0xDE,0x15,0xDF,0x5F,0x9F,0xDA,0xC6,0xD9,0xCE,0x8E, 0x08,0xC2,0x9B,0x00,0xFF,0x97};uint wen_du;//温度变量 uint shang,xia; //对比温度暂存变量uchar dang;//档位显示uchar flag;uchar d1,d2,d3;//显示数据暂存变量void delay(uint ms) //延时函数,大约延时25x12us{uchar x;for(ms;ms>0;ms--)for(x=120;x>0;x--);}/***********ds18b20延迟子函数(晶振12MHz )*******/ void delay_18B20(uint i){while(i--);}/**********ds18b20初始化函数**********************/void Init_DS18B20() {uchar x=0;DQ=1;//DQ复位delay_18B20(8); //稍做延时DQ=0;//单片机将DQ拉低delay_18B20(80); //精确延时 大于 480usDQ=1;//拉高总线delay_18B20(14);x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败delay_18B20(20);}/***********ds18b20读一个字节**************/ uchar ReadOneChar(){uchar i=0;uchar dat=0;for (i=8;i>0;i--){DQ=0; // 给脉冲信号dat>>=1;DQ=1; // 给脉冲信号if(DQ)dat|=0x80;delay_18B20(4);}return(dat);}/*************ds18b20写一个字节****************/ void WriteOneChar(uchar dat){uchar i=0;for (i=8;i>0;i--){DQ=0;DQ=dat&0x01;delay_18B20(5);DQ=1;dat>>=1;}}/**************读取ds18b20当前温度************/void ReadTemperature(){uchar a=0;uchar b=0;uchar t=0;Init_DS18B20();WriteOneChar(0xCC);// 跳过读序号列号的操作WriteOneChar(0x44); // 启动温度转换delay_18B20(100); // this message is very importantInit_DS18B20();WriteOneChar(0xCC); //跳过读序号列号的操作WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度delay_18B20(100);a=ReadOneChar();//读取温度值低位b=ReadOneChar();//读取温度值高位wen_du=((b*256+a)>>4); //当前采集温度值除16得实际温度值}void display()//显示温度{w1=0;P1=~table[d1];delay(10); //第1位P1=~0x00;w1=1;delay(1);w2=0;P1=~table[16];delay(10);//第2位P1=~0x00;w2=1;delay(1);w3=0;P1=~table[d2]; delay(10);//第3位P1=~0x00;w3=1;delay(1);w4=0;P1=~table[d3];delay(10);//第4位P1=~0x00;w4=1;delay(1);}void zi_keyscan()//自动模式按键扫描函数{if(key1==0) //设置键按下{delay(10); //延时去抖if(key1==0)flag=1;//再次判断按键,按下的话进入设置状态while(key1==0);//松手检测 //按键释放}while(flag==1) //进入设置上限状态{d1=18;d2=shang/10;d3=shang%10; //显示字母H 和上限温度值display(); //调用显示函数if(key1==0) //判断设置键是否按下{delay(10); //延时去抖if(key1==0)flag=2;//按键按下,进入设置下限模式while(key1==0);//松手检测}if(key2==0) //加键按下{delay(10); //延时去抖if(key2==0) //加键按下{shang+=1;//上限加5if(shang>=100)shang=100; //上限最大加到100}while(key2==0);//松手检测}if(key3==0) //减键按下{delay(10); //延时去抖if(key3==0) //减键按下{shang-=1;//上限减1if(shang<=10)shang=10; //上限最小减到10}while(key3==0);//松手检测} }while(flag==2) //设置下限{d1=17;d2=xia/10;d3=xia%10; //显示字母L 显示下限温度值display(); if(key1==0){delay(10);if(key1==0)flag=0;while(key1==0);//松手检测}if(key2==0){delay(10);if(key2==0){xia+=1;if(xia>=99)xia=99;}while(key2==0);//松手检测}if(key3==0){delay(10);if(key3==0){xia-=1;if(xia<=0)xia=0; }while(key3==0);//松手检测} }}void zi_dong()//自动温控模式{uchar i;d1=dang;d2=wen_du/10;d3=wen_du%10; //显示档位,显示当前温度值zi_keyscan();//按键扫描函数display(); //调用显示函数if(wen_du<xia){dj=1;dang=0;}//低于下限 档位为0 电机停止if((wen_du>=xia)&&(wen_du<=shang))//温度大于下限,小于上限{dang=1; //档位置1for(i=0;i<3;i++){dj=0;display();zi_keyscan();} //PWM通过延时得到for(i=0;i<6;i++){dj=0;display();zi_keyscan();} }if(wen_du>shang){dj=0;dang=2;}//高温全速,档位置2}void main() //主函数{uchar j;dj=0; //电机开shang=30;xia=20; //初始上下限值for(j=0;j<80;j++) //先读取温度值,防止开机显示85ReadTemperature();while(1)//进入while循环{ReadTemperature(); //读取温度值for(j=0;j<100;j++)zi_dong();//自动温控模式}}
/download/qq_42253057/18814019