单片机源程序如下:
- /*
- 实验说明:
- 根据自己使用的LCD1602是否带有转接板,如果带有转接板的即为4位,需在LCD.H头文件中
- 将宏#define LCD1602_4PINS打开,我们这里使用的LCD1602是8位,所以默认将该宏注释。
- 实验接线:
- 1,LCD1602液晶模块-->单片机管脚
- 参考LCD1602液晶显示实验接线(开发攻略内在对应的实验章节内实验现象有接线说明)
- 2,红外遥控模块-->单片机管脚
- P32
- 3,蜂鸣器模块-->单片机管脚
- BEEP-->P15
- 4,LED模块-->单片机管脚
- D1-->P24
- 5,LED模块-->单片机管脚
- D1-->P24
- 6,继电器模块-->单片机管脚
- RELAY-->P14
- 7,直流电机模块-->单片机管脚
- IN1-->P10(参考直流电机实验接线)
- 8,EEPROM模块-->单片机管脚
- P20-->SDA
- P21-->SCL
- 9,DS18B20模块-->单片机管脚
- P37
-
- 实验现象:
- 首先它能显示环境的温度并能设置上下限阀值,这是最基本的功能,系统上电的时候显示的是当前环境温度
- 和设定的温度阀值,我们可以通过红外遥控键来修改温度上下限阀值。我们看,按下这个1键会进入温度阀值设置
- 界面,每按一下,切换一次阀值设置(上下阀值)界面,按第3次时,会自动回到主界面,如此循环。
- 在进入温度阀值设计界面时,可以通过2、3键对阀值进行加减,这里我们只对温度整数部分进行设置,
- 小数部分我们就不需要了,将设置好的上下限阀值保存到AT24C02(EEPROM)内,当下一次开启系统时只需
- 从AT24C02内读取保存的阀值数据,而不需要重复设置上下限阀值。这样的话,我们用3个按键就实现了温度上下
- 限阀值的设定,这是温度检测控制系统基本的功能。假如我们把温度上限设置为32°C,下限设置为30°C。
- 另外还有恒定温度的功能。当设定好上下限阀值时,系统即会把当前的温度与设定的上下限阀值对比,
- 如果高于上限温度,开启散热进行降温,同时报警;如果低于下限温度,开启加热,同时报警;
- 如果当前温度处于下限和上限温度之间时,关闭散热、加热及报警。从而可将温度控制在阀值的范围内。
- */
- #include "public.h"
- #include "lcd.h"
- #include "temp.h"
- #include "i2c.h"
- sbit led=P2^4; //报警指示灯
- sbit beep=P1^5; //蜂鸣器报警
- sbit relay=P1^4; //加热设备
- sbit moto=P1^0; //电机散热
- sbit IRIN=P3^2;
- u8 IrValue[6];
- u8 Time,K;
- char set_templ=5,set_temph=20; //设定温度上下限默认值
- u16 temp_val; //检测的实际温度
- u8 mode; //温度模式
- u8 irtime; //接收时间
- u8 startflag; //开始检测
- u8 bitnum; //bit位数
- u8 irdata[33]; //寄存没有个bit的时间
- u8 irreceok; //接收完成标志位
- u8 ircode[4]; //将接收的四个字节数据保存
- u8 irprosok; //接收数据处理标志位
- u8 irdisp[8]; //将四个字节的16进制通过转换变成十进制存储
- u8 dat1,dat2;
- u8 keynum;
- u8 motoflag;
- int motopros(u8 mode);
- void int0init()
- {
- EA=1;
- EX0=1;
- IT0=1;
- }
- void time0init()
- {
- TMOD=0X02; //设置定时器0模式2.该模式为自动装载模式
- TH0=0X00;
- TL0=0X00;//设定计数初值,每当TL0计数到255时,TH0将把自己的数据给TL0,又重新计数
- TR0=1;
- ET0=1;
- EA=1;
- }
- void irpros() //红外接收数据处理 ,区分是数据0还是1
- {
- u8 i,j,value;
- u8 k=1; //引导码去掉,所以令k=1;
- for(j=0;j<4;j++) //取出了一帧数据中的四个字节数据
- {
- for(i=0;i<8;i++) //取出了一个字节的数据
- {
- value>>=1;
- if(irdata[k]>6)
- {
- value=value|0x80;
- }
- k++;
- }
- ircode[j]=value;
- }
- irprosok=1;
- }
- void irwork() //将四个字节的数据转换成10进制数显示
- {
- irdisp[0]=ircode[0]/16;//显示高位
- irdisp[1]=ircode[0]%16;//显示低位
- irdisp[2]=ircode[1]/16;
- irdisp[3]=ircode[1]%16; //同一个遥控器此2个字节的引导码数据是不会改变的,改变的只是数据码及反码
- irdisp[4]=ircode[2]/16;
- irdisp[5]=ircode[2]%16;
- irdisp[6]=ircode[3]/16;
- irdisp[7]=ircode[3]%16;
- dat1=irdisp[4];
- dat2=irdisp[5];
- keynum++;
- }
- void Temp_DataPros()
- {
- short temp;
- u8 temp_buf[5];
- temp=Ds18b20ReadTemp();
- temp_val=temp;
- if(temp<0)
- {
- temp=-temp;
- LCD_Dispstring(2+5,0,"-");
- }
- else
- {
- LCD_Dispstring(2+5,0," ");
- }
- temp_buf[0]=temp/100+0x30;
- temp_buf[1]=temp%100/10+0x30;
- temp_buf[2]='.';
- temp_buf[3]=temp%100%10+0x30;
- temp_buf[4]='\0';
- LCD_Dispstring(2+6,0,temp_buf); //显示检测的温度xx.x
- temp_buf[0]=set_temph/10+0x30;
- temp_buf[1]=set_temph%10+0x30;
- temp_buf[2]='\0';
- LCD_Dispstring(5,1,temp_buf); //显示设定的温度上限值xx
- temp_buf[0]=set_templ/10+0x30;
- temp_buf[1]=set_templ%10+0x30;
- temp_buf[2]='\0';
- LCD_Dispstring(14,1,temp_buf); //显示设定的温度下限值xx
- }
- #define K1_MODE 1
- #define K2_ADD 2
- #define K3_DEC 3
- void KEY_Pros()
- {
- u8 key;
- u8 temph_buf[3];
- key=motopros(0);
-
- if(key==K1_MODE) //模式选择
- {
- mode++;
- LCD_Clear();
- if(mode==1)
- {
- LCD_Dispstring(0,0,"SETH: C");
- }
- else if(mode==2)
- {
- LCD_Dispstring(0,1,"SETL: C");
- }
- else
- {
- mode=0;
- LCD_Dispstring(2,0,"Temp: C");
- LCD_Dispstring(0,1,"SETH: ");
- LCD_Dispstring(9,1,"SETL: ");
- }
- }
- if(mode==1) //温度上限设置
- {
- switch(key)
- {
- case K2_ADD: //加
- set_temph++;
- if(set_temph>=80)set_temph=80;
- break;
- case K3_DEC: //减
- set_temph--;
- if(set_temph<=0)set_temph=0;
- break;
- }
- temph_buf[0]=set_temph/10+0x30;
- temph_buf[1]=set_temph%10+0x30;
- temph_buf[2]='\0';
- LCD_Dispstring(6,0,temph_buf);
- At24c02Write(0,set_temph);
- }
- else if(mode==2) //温度下限设置
- {
- switch(key)
- {
- case K2_ADD: //加
- set_templ++;
- if(set_templ>=80)set_templ=80;
- break;
- case K3_DEC: //减
- set_templ--;
- if(set_templ<=0)set_templ=0;
- break;
- }
- temph_buf[0]=set_templ/10+0x30;
- temph_buf[1]=set_templ%10+0x30;
- temph_buf[2]='\0';
- LCD_Dispstring(6,1,temph_buf);
- At24c02Write(2,set_templ);
- }
- }
- void sound()
- {
- u8 i=50;
- while(i--)
- {
- beep=!beep;
- delay(10);
- }
- }
- void TempData_Compare()
- {
- if(temp_val>set_temph*10) //实际温度高于上限值 报警 散热
- {
- led=0;
- moto=1;
- relay=0;
- sound();
- }
- else if(temp_val<set_templ*10) //实际温度低于下限值 报警 加热
- {
- led=0;
- moto=0;
- relay=0;
- sound();
- }
- else //实际温度在下限值和上限值之间 取消报警 取消加热 取消散热
- {
- moto=0;
- led=1;
- relay=1;
- }
- }
- void kai_display()
- {
- if(At24c02Read(255)!=18)
- {
- At24c02Write(0,set_temph);
- At24c02Write(2,set_templ);
- At24c02Write(255,18);
- }
- else
- {
- set_temph=At24c02Read(0);
- set_templ=At24c02Read(2);
- }
- LCD_Dispstring(2,0,"Temp: C");
- LCD_Dispstring(0,1,"SETH: ");
- LCD_Dispstring(9,1,"SETL: ");
- }
- //mode: 0-单次扫描 1-连续扫描
- int motopros(u8 mode)
- {
- static u8 key=1;
- u8 k1,k2,k3;
- if(key)
- {
- key=0;
- if((dat1==0)&&(dat2==12)) //按下第一次按键开马达
- {
- dat1=0;
- dat2=0;
- k1=0;
- return K1_MODE;
- }
-
- if((dat1==1)&&(dat2==8)) //按下第二次此按键时关闭马达
- {
- dat1=0;
- dat2=0;
- k2=0;
- return K2_ADD;
- }
- if((dat1==5)&&(dat2==14)) //按下第二次此按键时关闭马达
- {
- dat1=0;
- dat2=0;
- k3=0;
- return K3_DEC;
- }
- if((dat1==0)&&(dat2==8)) //按下第二次此按键时关闭马达
- {
- dat1=0;
- dat2=0;
- keynum=0;
- }
- }
- else if(k1==1&&k2==1&&k3==1)
- {
- key=1;
- }
- if(mode)
- {
- key=1;
- }
- return 0;
- k1=1;k2=1;k3=1;
- }
- void main()
- {
- moto=0;
- led=1;
- relay=1;
- int0init();
- time0init();
- LCD_Init();
- kai_display();
- while(1)
- {
- if(irreceok)
- {
- irreceok=0;
- irpros();
- if(irprosok)
- {
- irwork();
- }
- }
- motopros();
- if(mode==0)
- Temp_DataPros();
- KEY_Pros();
- TempData_Compare();
- }
- }
- void time0() interrupt 1
- {
- irtime++;//每进来一次就说明定时时间为256us;
- }
- void init0() interrupt 0
- {
- if(startflag)
- {
- if(irtime>32)//检测引导码,求法是用引导码时间除以一次计数时间,看看要多少次
- {
- bitnum=0;
- }
- irdata[bitnum]=irtime;
- irtime=0;
- bitnum++;
- if(bitnum==33)
- {
- bitnum=0;
- irreceok=1;//一帧红外数据接收完成标志
- }
- }
- else
- {
- startflag=1;//将开始标志位置1,等到下次进入中断即可进入if语句
- irtime=0;//将开始之前的计数器时间清零。等到下次进入中断的时候才是引导码真正的时间
- }
- }
复制代码
所有程序51hei提供下载:
智能温度检测控制系统设计.rar
(72.88 KB, 下载次数: 51)
|