系统主要设计了一个基于单片机的风扇温控仪,以单片机和DS18B20 传感器为核心,具有温度显示和控制风扇转速功能DS18B20 传感器,将检测到的温度转化为数字信号,单片机对输入的数字信号进行分析处理,当温度高于上限值时,风扇全速旋转;当温度低于下限时,风扇停转;当温度处于上限值与下限 之间时,风扇转速越慢,。图1 所示为系统设计结构框图。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
电路原理图如下:
单片机源程序如下:
- #include <reg52.h>
- #include <stdio.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit dq=P3^6;
- sbit w4=P2^6;
- sbit w3=P2^4;
- sbit w2=P2^2;
- sbit w1=P2^0;
- sbit dp=P0^7;
- sbit fs=P3^7;//风扇接口
- sbit key_shezhi=P1^5;
- sbit key_jia=P1^6;
- sbit key_jian=P1^7;
- uchar flag_0;
- uint t_max=250,t_max_1=300;
- uint count=0;
- int wendu,t;
- uchar speed; //速度变量
- void delay(uint z) //延时函数
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- /********************************/
- void pro()//按键处理函数
- {
- if(key_shezhi==0)
- {
- delay(10);
- if(key_shezhi==0)
- {
- flag_0++;
- if(flag_0>=3)
- flag_0=0;
- while(!key_shezhi) ;
- }
- }
- }
- /**********************************/
- uchar code table[]={
- 0xc0,0xf9,0xa4,0xb0, 0x99,0x92,0x82,0xf8, 0x80,0x90,0xbf//0 1 2 3......7 8 9 的字形码
- };
- uchar code table1[]={
- 0xc7,0x89 // L H 的字形码
- };
- uint temp,mm;uchar i;float f_temp;
- /***********************小延时函数*****************************/
- void delay_uint(uint q)
- {
- while(q--);
- }
- /*******************************************************
- /***********************18b20初始化函数*****************************/
- void init_18b20()
- {
- bit q;
- dq = 1; //把总线拿高
- delay_uint(1); //15us
- dq = 0; //给复位脉冲
- delay_uint(80); //750us
- dq = 1; //把总线拿高 等待
- delay_uint(10); //110us
- q = dq; //读取18b20初始化信号
- delay_uint(20); //200us
- dq = 1; //把总线拿高 释放总线
- }
- /*************写18b20内的数据***************/
- void write_18b20(uchar dat)
- {
- uchar i;
- for(i=0;i<8;i++)
- { //写数据是低位开始
- dq = 0; //把总线拿低写时间隙开始
- dq = dat & 0x01; //向18b20总线写数据了
- delay_uint(5); // 60us
- dq = 1; //释放总线
- dat >>= 1;
- }
- }
- /*************读取18b20内的数据***************/
- uchar read_18b20()
- {
- uchar i,wendu;
- for(i=0;i<8;i++)
- {
- dq = 0; //把总线拿低读时间隙开始
- wendu >>= 1; //读数据是低位开始
- dq = 1; //释放总线
- if(dq == 1) //开始读写数据
- wendu |= 0x80;
- delay_uint(5); //60us 读一个时间隙最少要保持60us的时间
- }
- return wendu; //返回数据
- }
- /*************读取温度的值 读出来的是小数***************/
- uint read_temp()
- {
- uint wendu;
- uchar low; //在读取温度的时候如果中断的太频繁了,就应该把中断给关了,否则会影响到18b20的时序
- init_18b20(); //初始化18b20
- write_18b20(0xcc); //跳过64位ROM
- write_18b20(0x44); //启动一次温度转换命令
- delay_uint(50); //500us
- init_18b20(); //初始化18b20
-
- write_18b20(0xcc); //跳过64位ROM
- write_18b20(0xbe); //发出读取暂存器命令
-
- EA = 0;
- low = read_18b20(); //读温度低字节
- wendu = read_18b20(); //读温度高字节
- EA = 1;
- wendu <<= 8; //把温度的高位左移8位
- wendu |= low; //把读出的温度低位放到value的低八位中
- wendu *= 0.625; //转换到温度值 小数
- return wendu; //返回读出的温度 带小数
- }
- void display0()
- {
- P0=0xff;//消隐
- w1=0; //选通第一位数码管
- if(speed>5) //如果speed的值>5则档位显示speed-5,比如speed=6,则显示1档
- P0=table[speed-5];//显示档位
- else //否则speed的值如果小于5,则显示0档
- P0=table[0];//显示档位
- delay(2);//延迟一会
- w1=1;//关闭第一位数码管
-
- P0=0xff;//第二位数码管的显示原理及方法同上
- w2=0;
- P0=0xbf;//显示-
- delay(2);
- w2=1;
-
- P0=0xff;
- w3=0;
- P0=table[wendu/100];//显示温度十位
- delay(2);
- w3=1;
-
- P0=0xff;
- w4=0;
- P0=table[wendu%100/10];//显示温度各位
- delay(2);
- w4=1;
- }
- void zi_dong()//自动温控模式
- {
- // 此函数的目的是将上限和下限的差值平均为5份,每一份对应一个速度值 14-25
- if(wendu<t_max) //温度小于下限
- speed=0; //速度0档
- else if(wendu>=t_max&&(wendu<(uint)((t_max_1-t_max)/4+t_max))) //温度大于下限并且小于(上限减去下限)除以4加下限
- speed=6; //6档 14-16.75 14-15
- else if((wendu>=(uint)((float)(t_max_1-t_max)/4+t_max))&&(wendu<(uint)((float)(t_max_1-t_max)/2+t_max))) //温度大于 (上限减去下限)除以4加下限 并且小于(上限减去下限)除以2加下限
- speed=7; //7档 16-19.5 16-18
- else if((wendu>=(uint)(t_max_1-t_max)/2+t_max)&&(wendu<(uint)((float)((float)(t_max_1-t_max)/4)*3+t_max))) //温度大于 (上限减去下限)除以2加下限 并且小于(上限减去下限)除以4乘以3加下限
- speed=8; //8档 19-22.25 19-21
- else if((wendu>=(uint)((float)((float)(t_max_1-t_max)/4)*3+t_max))&&wendu<t_max_1) //温度大于 (上限减去下限)除以4乘以3加下限 并且小于上限
- speed=9; //9档 22-24 22-24
- else if(wendu>=t_max_1) //大于上限
- speed=10; //10档 >25
- }
- /***************************************/
- void fengshan()
- {
- uchar m;
- if(m<speed) //m值小于speed
- fs=0; //打开风扇
- else if(m>=speed) //否则
- fs=1; //关闭风扇
- m++; //m加
- if(m>=10) //m极爱到10,也就是2ms
- m=0;
- }
- /**************************************/
- /**************************************/
- void display1()
- {
- P0=0xff;//消隐
- w1=0;//选通第一位数码管
- P0=table1[0];//显示 L
- delay(2);//延迟一会
- w1=1;//关闭第一位数码管
-
- P0=0xff;//第二位数码管显示方法及原理同上
- w2=0;
- P0=0xbf;//显示 -
- delay(2);
- w2=1;
-
- P0=0xff;
- w3=0;
- P0=table[t_max/100];//显示设置下限值的十位
- delay(2);
- w3=1;
-
- P0=0xff;
- w4=0;
- P0=table[t_max%100/10];//显示设置下限值的个位
- delay(2);
- w4=1;
- }
- /**************************************/
- void display2()
- {
- P0=0xff;
- w1=0;
- P0=table1[1];//显示 H
- delay(2);
- w1=1;
-
- P0=0xff;
- w2=0;
- P0=0xbf;//显示 -
- delay(2);
- w2=1;
-
- P0=0xff;
- w3=0;
- P0=table[t_max_1/100];//显示设置上限值得十位
- delay(2);
- w3=1;
-
- P0=0xff;
- w4=0;
- P0=table[t_max_1%100/10];//显示设置上限值得个位
- delay(2);
- w4=1;
- }
- /***************************************/
- void shezhi()
- {
- if(flag_0==1)//flag_0==0时,为正常显示。等于1时,为设置下限位值。等2时为设置上限为置
- {
- if(key_jia==0)//当设置下限位值时,按下加键
- {
- delay(10);//延迟消抖
- if(key_jia==0)//确认加键已按下
- {
- t_max=t_max+10;//对下限位值每次加10
- if(t_max>=t_max_1) //防止低温度高于高温度//如果下限位值设置时超过了上限位置
- t_max=t_max_1-10; //则让下限位值-10
- while(!key_jia);//松手检测
- }
- }
- if(key_jian==0)//如果键键按下了,同上
- {
- delay(10);
- if(key_jian==0)
- {
- t_max=t_max-10;
- while(!key_jian);
- }
- }
- }
- if(flag_0==2)//对上限位设置时
- {
- if(key_jia==0)
- {
- delay(10);
- if(key_jia==0)
- {
- t_max_1=t_max_1+10;
- while(!key_jia);
- }
- }
- if(key_jian==0)
- {
- delay(10);
- if(key_jian==0)
- {
- t_max_1=t_max_1-10;
- if(t_max_1<=t_max) //防止高温度小于低温度
- t_max_1=t_max+10;
- while(!key_jian);
- }
- }
- }
- }
- void display()
- {
- if(flag_0==0)//flag_0==0时,为正常显示。等于1时,为设置下限位值。等2时为设置上限为置
- display0();//正常显示
- else if(flag_0==1)
- display1();//设置下限时的显示
- else if(flag_0==2)
- display2(); //设置上限时的显示
- }
- void main()
- {
- while(1)
- {
-
- read_18b20();//读取温度传感器中的数据
-
- t=read_temp();//把读出的数据赋给t
- if(t>=0&&t<=1250) //温度合法范围,不在这个范围就是没有获取到合适的值
- {
- wendu=t;
- }
- pro();//按键处理
- display();//显示处理
- shezhi();//设置按键处理
- fengshan();//风扇处理
- zi_dong();//自动挡风扇处理
- }
- }
复制代码
全部资料51hei下载地址:
小风扇.7z
(269.68 KB, 下载次数: 35)
|