1.可按键设置上中下限
2.有声光报警
3.有风扇
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include <reg51.h>
- #include <intrins.h>
- #include <math.h>
- #include "main.h"
- char code LED_display[14] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xBF,0XFF,0x89,0XC7}; //共阳数码管段码
- // 0 1 2 3 4 5 6 7 8 9 - H L
- char code bit_sel[4] = {0x01,0x02,0x04,0x08};
- char dis[4];
-
- unsigned char TL0_temp; /*暂存TL0的初值*/
- unsigned char TH0_temp; /*暂存TH0的初值*/
- #define INT_CLOCK 5 /*INT_CLOCK为定时值,单位为ms ,此处定义为5ms*/
- #define CRY_FREQUENCY 12000000 /*CRY_FREQUENCY为晶振频率,单位为Hz*/
- bit flag = 0; //0-正温度 1-负温度
- sbit key1 = P3^2; //设置按键
- sbit key2 = P3^3; //增量按键
- sbit key3 = P3^4; //减量按键
- bit bKey1,bKey2,bKey3;
- uchar countSet = 0;
- sbit ledRed = P1^0; //红灯
- sbit ledYellow = P1^1; //黄灯
- sbit ledGreen = P1^2; //绿灯
- sbit fan = P1^6; //风扇
- sbit beep = P1^5; //蜂鸣器
- char shutDowmH = 85; //关机温度
- char SetH = 65; //高温上限
- char SetL = 30; //低温下限
- char alarm = 0;
- sbit DQ=P3^6; /* 18B20数据引脚*/
- #define temp_h P3|=0x40//单片机向DS18B20输出高电平
- #define temp_l P3&=0xbf//单片机向DS18B20输出低电平
- void delay(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- void Timer0_init()
- {
- unsigned long T0_temp; /*暂存T0的初始值 */
- T0_temp = 65536-((INT_CLOCK *CRY_FREQUENCY /1000)/12); /*T0初始值计算公式,参考教科书*/
- TL0_temp = T0_temp & 0xff;
- TH0_temp = T0_temp >> 8;
- TL0 = TL0_temp;
- TH0 = TH0_temp;
- TMOD |= 0x01;
- TR0 = 1;
- ET0 = 1;
- EA = 1; /*开定时器0中断*/
- }
- void INT0_Init()
- {
- EX0 = 1;
- IT0 = 1;
- }
- void delay1ms(unsigned int ms)//延时1毫秒(不够精确的)
- {
- unsigned int i,j;
- for(i=0;i<ms;i++)
- for(j=0;j<100;j++);
- }
- void keyScan()
- {
-
- if(!key2)
- {
- delay1ms(300);
- if(!key2)
- bKey2 = 1;
- }
- if(!key3)
- {
- delay1ms(300);
- if(!key3)
- bKey3 = 1;
- }
- }
- //数码管显示温度值
- void displayTemp(uint temp)
- {
- uchar i;
- if(countSet == 0) //显示实际的测试温度
- {
- if(flag == 1) //负温度
- {
-
- dis[0] = 11;
- dis[1] = 10;
- dis[2] = temp/100;
- dis[3] = temp%100/10;
- }
- else //正温度
- {
-
- dis[0] = 11;
- dis[1] = temp/1000;
- dis[2] = temp%1000/100;
- dis[3] = temp%1000%100/10;
- }
- }
- else if(countSet == 1) //显示设置的温度下限
- {
- dis[0] = 1; //显示'1'
-
- dis[1] = 10;
- dis[2] = SetL/10;
- dis[3] = SetL%10;
-
-
- }
- else if(countSet == 2) //显示设置的温度上限
- {
- dis[0] = 2; //显示'2'
-
- dis[1] = 10;
- dis[2] = SetH/10;
- dis[3] = SetH%10;
- }
- else if(countSet == 3) //显示设置的关机温度
- {
- dis[0] = 3; //显示'3'
-
- dis[1] = 10;
- dis[2] = shutDowmH/10;
- dis[3] = shutDowmH%10;
- }
- }
- /***********ds18b20延迟子函数(晶振12MHz )*******/
- void delayms(uint x)//延时1ms
- {
- uint y,z;
- for(y=x;y>0;y--)
- for(z=110;z>0;z--);
- }
- /**********ds18b20初始化函数**********************/
- void Ds18b20_reset()//DS18B20初始化
- {
- uchar count;
- uint i=2200;
- temp_l;
- for(count=240;count>0;count--);//延时480us
- temp_h;
- while(DQ&&(i>0)) i--;
- for(count=240;count>0;count--);//延时480us
- }
- /***********ds18b20读一个字节**************/
- uchar Ds18b20_read()//从DS18B20读一个字节
- {
- uchar i,count,dat;
- for(i=8;i>0;i--)
- {
- dat>>=1;
- temp_l;
- for(count=1;count>0;count--);
- temp_h;//此语句必须有,参考datasheet的P15
- for(count=1;count>0;count--);
- if(DQ)
- dat|=0x80;
- for(count=30;count>0;count--);
- }
- return dat;
- }
- /*************ds18b20写一个字节****************/
- void Ds18b20_write(uchar dat)//向DS18B20写一个字节
- {
- uchar count;
- uchar i;
- for(i=8;i>0;i--)
- {
- temp_l;
- for(count=1;count>0;count--);
-
- if(dat&0x01==0x01)
- temp_h;
- else
- temp_l;
- for(count=30;count>0;count--);
- temp_h;
- dat>>=1;
- }
- }
- /**************读取ds18b20当前温度************/
- uint ReadTemperature(void)
- {
- uint dat;
- uchar dat1,dat2;//保存读出的温度
- Ds18b20_reset();
- Ds18b20_write(0xcc);
- Ds18b20_write(0x44);//发送温度转换命令
- delayms(1000);//延时1s,等待温度转换完成
- Ds18b20_reset();
- Ds18b20_write(0xcc);
- Ds18b20_write(0xbe);//发送读温度寄存器命令
- dat1=Ds18b20_read();
- dat2=Ds18b20_read();
- if(dat2 >= 240) //负温度
- {
- dat=(~(dat2*256+dat1)+1)*(0.0625*10);
- flag = 1;
- }
- else //正温度
- {
- flag = 0;
- dat=(dat2*256+dat1)*(0.0625*10);
- }
- return dat;
- }
- void main()
- {
-
- uint temp;
- Timer0_init(); //定时器0初始化
- INT0_Init();
- EA = 1; //开总中断
- fan = 0;
- countSet = 0;
- while(1)
- {
- if(countSet == 0)
- temp = ReadTemperature(); //采集DS18B20的温度值
- if(flag == 1) //负温度
- {
- ledYellow = 0; //黄灯亮
- ledRed = 1;
- ledGreen = 1;
- displayTemp(temp); //显示温度
- fan = 0;//风扇关闭
- alarm = 0;
- }
- else
- {
- if(temp/10 > shutDowmH)
- {
- dis[0] = 11;
- dis[1] = 11;
- dis[2] = 11;
- dis[3] = 11; //数码管熄灭
- ledYellow = 1; //灯全熄灭
- ledRed = 1;
- ledGreen = 1;
- fan = 0; //风扇停转
- alarm = 0;
- }
- else if(temp/10 > SetH)
- {
- displayTemp(temp); //显示温度
- ledYellow = 1; //指示灯变红
- ledRed = 0;
- ledGreen = 1;
- fan = 1; //风扇开启
- alarm = 1;
- }
- else if(temp/10 > SetL)
- {
- displayTemp(temp); //显示温度 或者设置
- ledYellow = 1; //指示灯变绿
- ledRed = 1;
- ledGreen = 0;
- fan = 1; //风扇开启
- alarm = 0;
- }
- else
- {
- displayTemp(temp); //显示温度
- ledYellow = 0; //指示灯变黄
- ledRed = 1;
- ledGreen = 1;
- fan = 0; //风扇关闭
- alarm = 0;
- }
- }
- keyScan();
- if(bKey2) //温度加
- {
- bKey2 = 0;
- if(countSet == 1) //设置低温
- {
- if(SetL < SetH)
- SetL++;
- }
- if(countSet == 2) //设置高温
- {
- if(SetH < shutDowmH)
- SetH++;
- }
- if(countSet == 3) //设置关机温度
- {
- if(shutDowmH < 99)
- shutDowmH++;
- }
- }
- if(bKey3) //温度减
- {
- bKey3 = 0;
- if(countSet == 1) //设置低温
- {
- if(SetL > 0)
- SetL--;
- }
- if(countSet == 2) //设置高温
- {
- if(SetH > SetL)
- SetH--;
- }
- if(countSet == 3) //设置关机温度
- {
- if(shutDowmH > SetH)
- shutDowmH--;
- }
- }
-
- }
- }
- unsigned char count_5ms = 0;
- unsigned int count_5s = 0;
- void T0_interrupt(void) interrupt 1
- {
- TH0 += TH0_temp;
- TL0 += TL0_temp;
-
- count_5ms++;
- if(count_5ms >= 4)
- count_5ms = 0;
- P2 = 0X00;
- P0 = LED_display[dis[count_5ms]];
- P2 = bit_sel[count_5ms];
- if(alarm == 1)
- {
-
- if(count_5s < 1000)
- {
- count_5s++;
- beep = !beep;
- }
- }
- else
- count_5s = 0;
- }
- /*
- 外部中断0服务处理函数,记录“设置”按键按下的次数
- */
- void int_int0() interrupt 0
- {
- countSet++;
- if(countSet > 3)
- countSet = 0;
- }
复制代码
所有资料51hei提供下载:
CPU温度控制(1).zip
(103.31 KB, 下载次数: 307)
|