找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 11062|回复: 10
打印 上一主题 下一主题
收起左侧

单片机智能温控风扇仿真程序—有非常详细的自创代码与很多图的代码解释

  [复制链接]
跳转到指定楼层
楼主
我的单片机智能温控风扇制作,优点是比较详细(尤其是代码的解释),可能对论坛同好来说不值一提,不管怎样,分享一下。我上传了c文件、hex、还有uvproj和pdsprj的仿真。还有doc和pdf。

最后也做出来了实际电路。
第一次发帖,不知道说啥,发几张图吧。

1.完成电路原理图的设计:本设计以STC89C52 单片机作为控制核心,采用高精度温度传感器DS18B20 检测环境温度,把经过ADC 转换模块输出的数字温度信号发送给STC89C52 单片机进行处理,在LCD 显示屏上显示当前环境温度值和用按键预设的每个档位温度值,并采用PWM 脉宽调制方式改变直流风扇电机的转速。系统结构如图 1系统结构所示。
图 1系统结构

2.用Proteus软件画电路原理图,设计相关硬件,并通过Keil编辑C语言程序,并将编译后生成的HEX文件放在所画的硬件电路中仿真。
3.仿真成功后,焊接与调试电路板。
4.安装驱动,将程序烧录至单片机,观察并调试直至达到设计要求。
二、设计要求
1.读取DB18B20温度传感器数据
2.风扇根据温度变化自动调节转速档位:当前温度在小于下限为0档;在上下
限之间为1档,大于上限为2档。
3.              按一次K1进入温度上限设置,K2,K3设置温度的增加或者减少;按两次K1进入温度下限设置,K2,K3设置温度的增加或减少;按三次K1退出设置模式。
4.              1602显示屏显示当前温度、设置温度的上下限,风扇当前档位,进入设置模式后在相应位置用光标显示。
三、设计过程(包括设计仿真图)
  • STC89C52 单片机最小系统
这张图显示了:单片机最小系统理应有的晶振和复位电路,这芯片里有ROM和RAM,所以也不加入片外的数据存储器和程序存储器了。
本实验要用的三个按钮资源接在了P3.5,P3.6,P3.7口,同时连接时线与接在单片机外部中断口INT0之上,这里我用了触发中断,原因就是硬件可以自动清零,而且电平中断的硬件设置还是比较麻烦的。(此处灵感来自于单片机原理与应用及C51程序设计第三版清华大学出版社的例题7.9)
电机 P3.3口处,可以看到标签为motorDC;温度传感器P3.4,可以看见DSPORT标签。
LCD的数据口是P1,可以看见我用总线连接,自动标好了D7-D0,对应了LCD的8根数据线。P2.5,P2.6,P2.7对应了LCD的RS,RW,E这三个端口。


程序主函数大致意义如下:
外部中断0初始化
液晶初始化
循环以下:
              小灯显示
液晶显示
风扇转动
读取温度
读取按钮
计算挡位
中断程序:
              按钮设置

小灯显示
1.LED0
LED0用来显示按钮1也就是设置按钮按了几下:
void led(){
              if(flag==0) LED0=0;
              if(flag==1) LED0=1;
              if(flag==2) {LED0=1;delay(250);LED0=0;delay(250);LED0=1;}}
flag
意义
0
默认是0,按钮没按,或者已经按了3下,小灯泡不亮
1
按了一下设置按钮,小灯泡亮,意味进入了上限温度调整状态
2
按了两下设置按钮,小灯泡闪烁,意味进入了下限温度调整状态

2.LED1
void int0() interrupt 0 {
              LED1=0;
              keySet();
              delay(500);
              LED1=1;
}
LED1:只要你按了任何一个键,意味着进入了中断,LED1都会闪一下

即得到右图的画面:
代码解析:
1. 几个端口的设置:
#define LCD1602_DATAPINS P1
sbit LCD1602_E=P2^7;
sbit LCD1602_RW=P2^6;
sbit LCD1602_RS=P2^5;
2.局部变量讲解
unsigned char printData[8] = {0,0,':',0,0,0,0,' '};            
unsigned char Prompt[4][2]= {{'U','L'},{'L','L'},{'C','T'},{'G','R'}};
这个就是等一会放8个小块的字符数组,前面两个字符会被Prompt替换。顺便一提,这几个英文字符分别为:上限(Upper Limit)和下限(Lower Limit),当前温度(Current Temperature),挡位(GeaR)。第3-7个字符等一会会被LcdDisplay() 召唤calNumPrint()给替换掉。
3.写命令/数据操作
void Lcd1602_WriteCom(uchar com); void Lcd1602_WriteData(uchar dat) ;这两个得按照这个时序图来,没什么好说的,这个是抄厂家给的例程,毫无创新,毕竟对时序不敏感。
5. void calNumPrint(int temp);
这个就是用来填入printData4-7位。
语句
意义
if(temp>0)printData[3]='+'; elseprintData[3]='-';
判断温度的正负,理论上DS18B20 的测量范围为 -55 ℃ ~+ 125 ℃
for( i=4; i<7; i++) {
dividend=1;
for( j=6-i; j>0; j--)dividend*=10;
printData[ i]=temp/dividend%10+'0';}
就是为了根据所给的温度填写4-6位,之所以有dividend和下面的一条for语句是为了安全地(虽然可能没有必要)确保只截取了一位
printData[7]=' ';
为了安全地(虽然可能没有必要)确保第7位是空格



6. void Lcd1602_Init();


初始化,main()函数用的,不加这个你开不了LCD,更别提设定LCD的种种工作模式细节。这个是厂家给的例程,意义注释有。

7. void LcdDisplay(int temp);



这个自创函数值得大说特说,1602一共16列2行,每一行放两个8列1行的小块。所以用了一个for循环for( loop=0; loop<4; loop++) 专门循环放这四个小块,每一次循环都得改提示符,然后进入选择根据当前循环分支语句,loop为0和1是温度的上下限,调用calNumPrint函数算3-7个位置究竟是什么;loop为2得换行了,然后calNumPrint算当前的温度怎么显示;3时是挡位,不是温度所以不能调用calNumPrint,我直接3-5位为空格,第6位直接算挡位显示即可。最后每轮循环把算出的printData这一个字节八位ASCII符号送入LCD1602_WriteData让LCD显示即可。
这个函数封装和调用精致,没有多余代码残余;缺点也有,有点费时间。
  • 驱动模块及风扇
电机的驱动是由NPN以及PNP两个不同类型的晶体管组成的复合管,复合后可等效为一个NPN晶体管,但是它理想情况下,能够获得两个原本两个管的乘积的放大倍数,这样就可以有足够的电流驱动集电极之上的直流电机旋转。


如何根据挡位来控制单片机的转动速率?只要单片机输出占空比可调的方波,即PWM信号即可控制电机两端的电压发生变化,从而实现电机转速的控制。占空比越大,所得到的平均电压也就越大,幅值也就越大;占空比越小,所得到的平均电压也就越小,幅值也就越小。我们利用软件延时的方法调节占空比,当高电平延时时间到的时候,对I/O口电位取反,使变成低电平,再进行延时,低电平延时时间到,再进行取反使其转化成为高电平,如此循环得到PWM信号。
  • 读取温度
1.Ds18b20ReadTemp()
语句
意义
Ds18b20ChangeTemp()
写入转换命令
Ds18b20ReadTempCom()
转换完成发出读取温度命令
tml = Ds18b20ReadByte();
tmh = Ds18b20ReadByte();            
读高低字节
currtemp = tmh;
currtemp <<= 8;
currtemp |= tml;
把两个高低字节整成一个
if(currtemp<0)
{currtemp=currtemp-1; currtemp=~currtemp;
}
tp=currtemp;
currtemp=tp*0.0625+0.5;
转化温度为摄氏度,字节是温度的补码,所以其中正负有不同的处理,并且四舍五入
2.Ds18b20ChangeTemp()
语句
意义
Ds18b20Init();

delay(1);

Ds18b20WriteByte(0xcc);Ds18b20WriteByte(0x44);
跳过ROM命令
温度转换命令
delay(100);
等待转换成功
3.uchar Ds18b20Init()            
做为从器件的DS18B20在一上电后就一直在检测总线上是否有480-960微秒的低电平出现,如果有,在总线转为高电平后等待15-60微秒后将总线电平拉低60-240微秒做出响应存在脉冲,告诉主机本器件已做好准备。
语句
意义
DSPORT = 0;i = 100;while(i--);
首先发出一个600微秒的低电平脉冲
DSPORT = 1; 及以下语句
释放总线变为高电平,以等待温感的成功回一,否则回零
4.void Ds18b20WriteByte(uchar dat):
写周期最少为60微秒,最长不超过120微秒。写周期一开始做为主机先把总线拉低1微秒表示写周期开始。随后若主机想写0,则将总线置为低电平,若主机想写1,则将总线置为高电平,持续时间最少60微秒直至写周期结束,然后释放总线为高电平至少1微秒给总线恢复 。而DS18B20则在检测到总线被拉底后等待15微秒然后从15us到45us开始对总线采样,在采样期内总线为高电平则为1,若采样期内总线为低电平则为0。
语句
意义
重复以下步骤八次,因为要送八位
DSPORT = 0;
写入前拉低
i++;
等待
DSPORT = dat & 0x01;
从最低一位开始写
i=13; while(i--);
试图延时中
DSPORT = 1;
释放总线,恢复它至少一微秒
dat >>= 1;
试图处理下一位
5.uchar Ds18b20ReadByte()
读周期是从主机把单总线拉低1微秒之后就得释放单总线为高电平,以让DS18B20把数据传输到单总线上。作为从机DS18B20在检测到总线被拉低1微秒后,便开始送出数据,若是要送出0就把总线拉为低电平直到读周期结束。若要送出1则释放总线为高电平。主机在一开始拉低总线1微秒后释放总线,然后在包括前面的拉低总线电平1微秒在内的15微秒时间内完成对总线进行采样检测,采样期内总线为低电平则确认为0。采样期内总线为高电平则确认为1。完成一个读时序过程,至少需要60微秒才能完成。
语句
意义
重复以下步骤八次,因为要读八位
byte>>=1;
准备下一位的读取
DSPORT = 0;
读出前拉低

等待
DSPORT = 1;
释放总线,恢复它至少一微秒

等待至少六微妙
if(DSPORT) byte|=0x80;
如果这位有输入,就读入到byte上,从最低一位开始读取
delay(5);
等待
return byte;
最后得到想要的字节
6.void  Ds18b20ReadTempCom()
Ds18b20Init();
初始化
delay(1);
Ds18b20WriteByte(0xcc);Ds18b20WriteByte(0xbe);
跳过ROM命令
温度读取命令
7.各个函数之间的关系

  • 读取按钮,反应处理
1.void keySet()
nowkey
意义
0
啥按钮也没有按, default
1
按了第一个模式按钮keyset,case 1
2
按了第二个模式按钮keyadd,case 2
3
按了第三个模式按钮keyminus,case 3
此函数中根据nowkey选择不同的分支,想见表。其中,default就是nowkey==0,什么也不做,case 1情况下稍后再提,先讲一下case 2或者3究竟做了什么:
tempLim[0]是温度上限,tempLim[1]是温度下限,flag-1只可能为1或者2;
value[0]是正一,value[1]是负一,nowkey-2只可能为1或者2;
所以这里其实就是改上/下限值与+/-:用flag区分到底是上/下限值,用nowkey区分到底是+/-。最后还要检查上限不小于下限,如果下限比上限还要大,那么让上限和下限趋同。可以参考下面两张状态表理清思路。
flag
keySet()如果按了keyset
0
初始化,啥都不做时
0
flag现为1,此状态标识进入上限模式
1
flag现为2,此状态标识进入下限模式
2
flag现为0,此状态标识进入默认模式

nowkey
keyset()根据keyscan()做出判断
0
啥按钮也没有按,所以啥都不干
1
keyset模式,专职改flag
2/3
根据flag、nowkey来改上/下限值与+/-

2. uchar keyscan()

电路图可以看到三个按钮分别接了P3.5,P3.6,P3.7;同时它们线与接入外部中断零,当外部中断零检测到低电平时候,中断调用keySet(),keySet()又会召唤keyscan(),keyscan()的用处就是返回为nowkey,这是去抖处理后判断的按下的按钮符号。
  • 计算挡位


根据currtemp和tempLim[0/1]也就是当前温度和上下限值判断在哪一个挡位,更改全局变量gears以作为结果:大于等于上限就开二档;小于上限,大于等于下限开一档;比下限还小就是零档。
四、设计结果(硬件实现结果图,包括各个部件)
当前温度24度,默认的上限和下限设置是35度和25度,所以当前挡位为零档,电机当前KRPM为正0.02,零档没开。D1是暗的因为没有按设置按钮。
当前温度被调整为27度,所以当前挡位为一档,电机现在走走停停。










按设置按钮(第一个按钮)一次,D1变亮。再按第二个加法按钮三下,第三个减法按钮一下,上限加一三次后又减一,结果如图UL:+037;挡位随之变1,风扇开始忽慢忽快地转动。按按钮时候可以观察到D2因为进入中断而闪动一次,不按时恢复。
再按设置按钮(第一个按钮)一次,D1开始闪动(图里面变暗是因为静态捕捉到的是变暗的时候)。再按第二个加法按钮一下,第三个减法按钮三下,下限减一三次后又加一,结果如图LL:+023;挡位不变,风扇继续忽慢忽快地转动。按按钮时候可以观察到D2因为进入中断而闪动一次,不按时恢复。
当前温度被调整为50度时候,当前挡位变为2档,电机全力旋转,LCD有相应显示。


在经过硬件、软件的单独调试之后,即可进入硬件和软件联合仿真调试的阶段。将下图中统一发放的元件进行焊接,并用杜邦线按照仿真示意图连接。


五、实验器件(器件清单)

1)              万用板(小)  一块
2)              7015风扇   一个
3)              STC89C52RC单片机最小系统板   一块
4)              1602液晶显示屏  一块
5)              10k电阻    两个   
6)              1k电阻      三个
7)              DS18B20    一个
8)              8550三极管    一个
9)              8050三极管    一个
10)              排针   20针
11)              按键    三个
12)              杜邦线   25条
13)              焊锡若干
14)              DC电源粗头电源线  一条
15)              排座  
16)              CH340下载

全部资料51hei下载地址(仿真程序):
温控风扇.zip (2.06 MB, 下载次数: 255)

单片机温控风扇的51hei设计_页面_03.jpg (191.31 KB, 下载次数: 143)

单片机温控风扇的51hei设计_页面_03.jpg

评分

参与人数 2黑币 +55 收起 理由
小当 + 5
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏20 分享淘帖 顶4 踩
回复

使用道具 举报

沙发
ID:35873 发表于 2021-3-7 10:52 | 只看该作者
不错  还有软硬件分析  易懂
回复

使用道具 举报

板凳
ID:856971 发表于 2021-3-12 20:48 | 只看该作者
请问这个如果再加一个用手机蓝牙控制该怎么做?
回复

使用道具 举报

地板
ID:929585 发表于 2021-5-31 09:41 | 只看该作者
感觉不错,很适合学习,硬件分析也很全
回复

使用道具 举报

5#
ID:911035 发表于 2021-6-2 08:42 | 只看该作者
分析的很全面,如果能增加上wifi控制是不是更好
回复

使用道具 举报

6#
ID:904368 发表于 2021-6-2 09:44 | 只看该作者
感觉已经非常好了,值得好好学习下。
回复

使用道具 举报

7#
ID:1073073 发表于 2023-6-18 13:46 | 只看该作者
分析的很详细,很好
回复

使用道具 举报

8#
ID:292518 发表于 2023-6-19 16:01 | 只看该作者
大神,能不能用STC8G1K08A?能不能改一下程序,支持一下这个IC
回复

使用道具 举报

9#
ID:469749 发表于 2023-9-9 17:44 | 只看该作者
你好,请问电路图中的U3是什么,谢谢
回复

使用道具 举报

10#
ID:469749 发表于 2023-9-9 17:55 | 只看该作者
还有一个问题,那个7015风扇是5v的还是12v的
回复

使用道具 举报

11#
ID:1120970 发表于 2024-5-16 08:43 | 只看该作者
感谢哥,分析到位!仿真元器件清单图有嘛?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表