一、系统方案 1、本设计采用这51单片机作为主控器。 2、DS18B20采集温度值送到液晶1602显示。 3、按键设置报警值。 4、温度控制风扇档位。
二、硬件设计 原理图如下:
三、单片机软件设计 1、首先是系统初始化 /*******************T0初始化********************/ void init_t0() { //TMOD=0x01;//定时器0工作方式1 TH0=(65536-100)/256;//赋初值定时 TL0=(65536-100)%256;//0.01ms EA=1;//开总中断 ET0=1;//开定时器0中断 TR0=1;//启动定时器0
SCON = 0X50; //UART方式1;8位UART REN = 1; //允许串行口接收数据 PCON = 0x00; //SMOD=0;波特率不加倍 TMOD = 0x21; //T1方式2,用于产生波特率 TH1 = 0xFD; //装初值 TL1 = 0xFD; TR1 = 1; //启动定时器1 EA = 1; //打开全局中断控制 ES = 1; //打开串行口中断
} 2、液晶显示程序 /******************************************************************* 写命令 ************************************************************************/ void xiemingling(unsigned char mingling) { en=0; rs=0; rw=0; P0=mingling; delayxms(5); en=1; delayxms(10); en=0; } /******************************************************************* 写数据 ************************************************************************/ void xieshuju(unsigned char shuju) { en=0; rs=1; rw=0; P0=shuju; delayxms(5); en=1; delayxms(10); en=0; } /******************************************************************* 液晶初始化 ************************************************************************/ void chushihua() { en=0; xiemingling(0x38);//设置16*2显示,5*7点阵,8位数据接口 delayxms(20); xiemingling(0x0c);//设置开显示,不显示光标 delayxms(20); xiemingling(0x06);//写一个字符后地址指针加1 delayxms(20); xiemingling(0x01);//显示清零,数据指针清零 delayxms(20); xiemingling(0x80);//指定字符显示的实际地址,,,显示位置的确定方法规定为"80H+地址码x" delayxms(20); } /***********************lcd1602上显示这字符函数************************/ void write_string(uchar hang,uchar add,uchar *p) { if(hang==1) xiemingling(0x80+add); else xiemingling(0x80+0x40+add); while(1) { if(*p == '\0') break; xieshuju(*p); p++; } } /***********************lcd1602上显示2位十进制数************************/ void write_num2(uchar hang,uchar add,uint date) { if(hang==1) xiemingling(0x80+add); else xiemingling(0x80+0x40+add); xieshuju(0x30+date/10); xieshuju(0x30+date%10); } /***********************lcd1602上显示1位十进制数************************/ void write_num1(uchar hang,uchar add,uint date) { if(hang==1) xiemingling(0x80+add); else xiemingling(0x80+0x40+add); xieshuju(0x30+date%10); } 3、DS18B20程序 /***************************初始化****************************************/ Init_DS18B20(void) { DQ = 1; //DQ复位 Delay(8); //稍做延时 DQ = 0; //将DQ拉低 Delay(90); //精确延时 大于 480us DQ = 1; //拉高总线 Delay(8); presence = DQ; //读取存在信号 Delay(100); DQ = 1; return(presence); //返回信号,0=presence,1= no presence } /***************************读一位****************************************/ uchar read_bit(void) { uchar i; DQ = 0; //将DQ 拉低开始读时间隙 DQ = 1; // then return high for (i=0; i<3; i++); // 延时15μs return(DQ); // 返回 DQ 线上的电平值 } /***************************读一个字节****************************************/ uchar ReadOneChar(void) { uchar i = 0; uchar dat = 0;
for (i=0;i<8;i++) { // 读取字节,每次读取一个字节 if(read_bit()) dat|=0x01<<i; // 然后将其左移
Delay(4); } return (dat); } /***************************写一位****************************************/ void write_bit(uchar bitval) { DQ = 0; // 将DQ 拉低开始写时间隙 if(bitval==1) DQ =1; // 如果写1,DQ 返回高电平 Delay(5); // 在时间隙内保持电平值, DQ = 1; // Delay函数每次循环延时16μs,因此delay(5) = 104μs } /***************************写一个字节****************************************/ void WriteOneChar(uchar dat) { uchar i = 0; uchar temp;
for (i=0; i<8; i++) // 写入字节, 每次写入一位 { temp = dat>>i; temp &= 0x01; write_bit(temp); } Delay(5); } /*------------------------------------------------ 单个DS18B20 读取温度 ------------------------------------------------*/ int ReadTemperature() { uchar a; uchar b; Init_DS18B20(); WriteOneChar(0xCC); // 跳过读序号列号的操作 WriteOneChar(0x44); // 启动温度转换 delayxms(10); Init_DS18B20(); WriteOneChar(0xCC); //跳过读序号列号的操作 WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度 a = ReadOneChar(); //低位 b = ReadOneChar(); //高位 t = b; t <<= 8; t |= a;
if(t < 0) //温度为负数 { flag_temp = 1; t -= 1; t = ~t; t = t * 0.0625;//温度值扩大-倍,精确到-位小数 } else { flag_temp = 0; t = t * 0.0625;//温度值扩大-倍,精确到-位小数 } return(t); } 4、核心算法程序 if(number==0) { /*根据温度控制档位*/ if(t<alarm) { dangwei = 0;
PWM1=0; TR0=0; pwm(0); //控制PWM输出,进而控制电机的速度
} else if(t<alarm+5) { dangwei = 1;
TR0=1; pwm(20); //控制PWM输出,进而控制电机的速度 } else if(t<alarm+10) { dangwei = 2;
TR0=1; pwm(50); //控制PWM输出,进而控制电机的速度 } else { dangwei = 3;
TR0=1; pwm(99); //控制PWM输出,进而控制电机的速度 } 四、 proteus仿真设计 Proteus软件是一款应用比较广泛的工具,它可以在没有硬件平台的基础上通过自身的软件仿真出硬件平台的运行情况,这样就可以通过软件仿真来验证我们设计的方案有没有问题,如果有问题,可以重新选择器件,连接器件,直到达到我们设定的目的,避免我们搭建实物的时候,如果当初选择的方案有问题,我们器件都已经焊接好了,再去卸载下去,再去焊接新的方案的器件,测试,这样会浪费人力和物力,也给开发者带来一定困惑,Proteus仿真软件就很好的解决这个问题,我们在设计之初,就使用该软件进行模拟仿真,测试,选择满足我们设计的最优方案。最后根据测试没问题的仿真图纸,焊接实物,调试,最终完成本设计的作品。
|