【智能温控风扇】

一、设计任务

  1. 设计内容
    以单片机作为核心控制器件,选取DS18B20温度传感器作为数字温度计,实时测量并反应实际温度,编写程序,采集实时温度并通过数码管显示当前温度,通过按键设置的温度上、下限,将其与实际温度的比较结果,作为控制风扇的开关及档位的依据:
    当实际温度低于所设温度下限时,风扇关闭,为0档;
    当实际温度高于温度下限,低于温度上限时,风扇转速一般,为1档;
    当温度高于温度上限时,风扇转速最快,为2档;
  2. 设计目的
    完成基于单片机的温控风扇的课程设计作品,通过课程设计中对原理图、PCB图、PTOTEUS仿真等的实际操作,熟悉相关开发软件,了解设计流程,加深对单片机、DS18B20的了解;此外,熟悉焊接流程,学会调试,加强动手能力。

二、硬件介绍

  1. 硬件组成
    电路板、STC89C52单片机、DS18B20、12M晶振、六角自锁开关、三极管若干、电容若干、电阻若干、开关若干、导线若干、风扇等

  2. 主要功能描述
    1)STC89C52单片机
    核心控制器件,执行程序代码,接收从DS18B20传回的实时温度,并输出信号控制数码管的显示,根据扫描按键的通断情况执行相应的设置温度上限、设置温度下限的功能切换,根据接收到的实际温度与设置温度上、下限的比较结果,输出信号控制风扇的档位
    2)DS18B20温度传感器
    实时测量实际温度,并通过相关协议,将测量到的实际温度反映给单片机
    3)六角自锁开关
    是整个电路的电源总开关
    4)三极管
    E、B、C三脚分别与电源、与单片机I/O口(经电阻)、与数码管位选或风扇正极相连,相当于电力开关,使电路得以依据单片机I/O口输出信号的高低实现三极管的通断,从而控制数码管显示的选位及风扇档位的调节
    5)电容及12M晶振
    瓷片电容与晶振构成单片机的外部振荡信号,是单片机实际应用中最小系统的组成部分;电解电容接在电源与地之间,起滤波的作用
    6)电阻
    起保护电阻的作用,控制单片机输出端口上的电流大小,防止因电流过大对电路造成损坏、控制数码管段选中的电流大小,防止因电流变化等问题影响电路及数码管的显示亮度;此外,在PROTEUS仿真中,需要在位选出接入电阻,方可进行正常仿真,但实际设计中不需要这里的电阻

  3. 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)报警搜索。

三、系统原理

  1. 原理图、PROTEUS仿真图、PCB图、3D立体图及实际电路连接图
    在这里插入图片描述
    温控风扇原理图
    在这里插入图片描述
    PROTEUS仿真图
    在这里插入图片描述
    PCB图
    在这里插入图片描述
    实际电路连接图
  2. 程序设计
    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); //精确延时 大于 480us
  DQ=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 important
Init_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;      //上限加5
    if(shang>=100)shang=100;  //上限最大加到100
   }while(key2==0);//松手检测
  }
  if(key3==0)        //减键按下
  {
   delay(10);       //延时去抖
   if(key3==0)       //减键按下
   {
    shang-=1;      //上限减1
    if(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;           //档位置1
  for(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++)   //先读取温度值,防止开机显示85
  ReadTemperature();
while(1)     //进入while循环
{ 
  ReadTemperature(); //读取温度值
  for(j=0;j<100;j++)zi_dong();//自动温控模式
}
}

https://download.csdn.net/download/qq_42253057/18814019

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐