1.基本要求
(1)能数字显示被测温度,测量温度范围0~100
(2)分辨率不低于0.5度
(3)带有计时和时间显示功能
(4)有高低两路限温控制输出接口控制外部电路。实际制作时可以用发光二极管模拟现实
(5)高低两路限温控制可在0~100范围内独立设计
(6)当温度达高低两限控制点声光报警
单片机源程序如下:
- /*预处理命令*/
- #include<reg52.h> //包含单片机寄存器的头文件
- #include<intrins.h> //包含_nop_()函数定义的头文件
- #define uchar unsigned char
- #define uint unsigned int
- #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
- sbit IRIN=P3^2; //红外接收器数据线
- sbit sclk = P1^0; //时钟
- sbit dio = P1^1;
- sbit ce = P1^2;
- sbit wela = P2^7;
- sbit dula = P2^6;
- sbit beep=P2^3;
- //sbit mscl = P2^1; // 24c02
- //sbit msda = P2^0;
- sbit msda=P2^0; //IO口定义
- sbit mscl=P2^1;
- sbit DS=P2^2;
- sbit DS1=P2^4;
- sbit led1=P3^0;
- sbit led2=P3^1;
- sbit led3=P3^3;
- sbit led4=P3^4;
- uint p;
- uint wendu=0,wendu1=0;
- uchar flag,h1,h2,m1,m2,h3,h4,m3,m4;
- uint htemp = 30; //高温限
- uint ltemp = 5 ; // 低温限
- uint htemp1 = 30; //高温限
- uint ltemp1 = 5 ; // 低温限
- bit hmodel ; // 高温设置
- bit lmodel ; // 低温设置
- bit hmodel1 ; // 高温设置
- bit lmodel1 ; // 低温设置
- unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
- 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
- unsigned char code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd, //加点的数码管
- 0x87,0xff,0xef};
- uchar IRCOM[7];
- uchar pin=0,pinjian;
- void dsreset(void);
- void tmpwritebyte(uchar dat);
- uint tmp();
- void dsreset1(void);
- void tmpwritebyte1(uchar dat);
- uint tmp1();
- void write_1302(uchar add,dat);
- uchar read_1302(uchar add);
- void display(uchar a,uchar b,uchar c,uchar d,uchar e,uchar f,uchar g,uchar h);
- void delay1ms();
- void delay(unsigned char x) ;
- void delayds(uint z);
- void delay1(int ms);
- void display1(uchar a,uchar b);
- void fanhui(); //7号
- void displayall();//2号
- void displayall1();//3号
- void huicha();//4号
- /*******************************************************************/
- /*24c02 初始化程序*/
- void delay_24c02()
- {
- uchar i;
- for(i=10;i--;i>0);
- }
- /*地址 A2A1A0 = 000*/
- /* 0x00 ,0x01 存放 第一路的高低温限
- 0x02,0x03 存放 第二路的高低温限
- 以后每两个相邻单元分别存放测试时间和温度值 (时间在前)*/
- void init_24c02()
- {
- msda = 1;
- delay_24c02();
- mscl = 1;
- delay_24c02();
- }
- /*24c02启动程序*/
- void start_24c02()
- {
- msda = 1;
- delay_24c02();
- mscl = 1;
- delay_24c02();
- msda = 0;
- delay_24c02();
- }
- /*24c02停止程序*/
- void stop_24c02()
- {
- msda = 0;
- delay_24c02();
- mscl = 1;
- delay_24c02();
- msda = 1;
- delay_24c02();
- }
- /*24c02的回应函数*/
- void respons() //回应信号
- {
- uchar i=0;
- mscl=1;
- delay_24c02();
- while((msda==1)&&(i<250))i++;
- mscl=0;
- delay_24c02();
- }
- void writebyte(uchar date)// 写一个字节
- {
- uchar i,temp;
- temp=date;
- for(i=0;i<8;i++)
- {
- temp=temp<<1;
- mscl=0;
- delay_24c02();
- msda=CY;
- delay_24c02();
- mscl=1;
- delay_24c02();
- }
- mscl=0;
- delay_24c02();
- msda=1;
- delay_24c02();
- }
- uchar readbyte() //读一个字节
- {
- uchar i,j,k;
- mscl=0;
- delay_24c02();
- msda=1;
- for(i=0;i<8;i++)
- {
- mscl=1;
- delay_24c02();
- if(msda==1)
- j=1;
- else
- j=0;
- k=(k<<1)|j;
- mscl=0;
- delay_24c02();
- }
- delay_24c02();
- return k;
- }
- //指定地址写一个字节数据
- void write_add(uchar address,uchar info)
- {
- start_24c02();
- writebyte(0xa0);
- respons();
- writebyte(address);
- respons();
- writebyte(info);
- respons();
- stop_24c02();
- }
- //指定地址读一个字节数据
- uchar read_add(uchar address)
- {
- uchar dd;
- start_24c02();
- writebyte(0xa0);
- respons();
- writebyte(address);
- respons();
- start_24c02();
- writebyte(0xa1);
- respons();
- dd=readbyte();
- stop_24c02();
- return dd;
- }
- void main()
- {
- unsigned int a;
- uchar A1,A2,A3;
- uint A2t;
- uchar hour,minute,second;
- uchar ho,min,h01,h02,m01,m02;
- led1=0;led2=0;led3=0;led4=0;
- IRIN=1; //I/O口初始化
- IE=0x81; //允许总中断中断,使能 INT0 外部中断
- TCON=TCON|0x01; //触发方式为脉冲负边沿触发
-
- while(1)
- {
- // write_1302(0x8e,0x00);
- // write_1302(0xc0,0xfe);
- // write_1302(0xc2,0xff);
- // write_1302(0x80,0x00); //sec
- // write_1302(0x82,0x00); //min
- // write_1302(0x84,0x16); //hour
- // write_1302(0x8e,0x80);
-
- // for(a=100;a>0;a--)
-
- if(hmodel==1)
- {display1(htemp/10,htemp%10);
- }
- if(lmodel==1)
- {display1(ltemp/10,ltemp%10);
- }
-
- if(flag==1)
- {
- write_1302(0x8e,0x00);
- hour=read_1302(0x85);
- minute=read_1302(0x83);
- second=read_1302(0x81);
- write_1302(0x8e,0x80);
- h1=hour/10;h2=hour%10;
- m1=minute/10;m2=minute%10;
-
- TR0=0;
- dsreset(); //温度开始转换
- delayds(1);
- tmpwritebyte(0xcc); // address all drivers on bus
- tmpwritebyte(0x44); // initiates a single temperature conversion
- for(a=10;a>0;a--)
- {
- wendu=tmp();
- A1=wendu/100;
- A2t=wendu%100;
- A2=A2t/10;
- A3=A2t%10;
- display(h1,h2,m1,m2,16,A1,A2,A3);
- //
- // TMOD=0x01; //定时器工作在方式1
- // ET0=1;
- // EA=1;
- // TH0=(65536-50000)/256; //对TH0 TL0赋值
- // TL0=(65536-50000)%256; //使定时器0.05秒中断一次
- // TR0=1; //开始计时
- //
- //
- // if(wendu>=htemp*10)
- // {
- // beep=0;
- // led1=0;
- // }
- // if(wendu<=ltemp*10)
- // {
- // beep=0;
- // led2=0;
- // }
- //
- }
-
- TMOD=0x01; //定时器工作在方式1
- ET0=1;
- EA=1;
- TH0=(65536-50000)/256; //对TH0 TL0赋值
- TL0=(65536-50000)%256; //使定时器0.05秒中断一次
- TR0=1; //开始计时
- if(wendu>=htemp*10)
- {
- beep=0;
- led1=0;
- }
- if(wendu<=ltemp*10)
- {
- beep=0;
- led2=0;
- }
-
- }
-
- if(flag==2)
- {write_1302(0x8e,0x00);
- hour=read_1302(0x85);
- minute=read_1302(0x83);
- second=read_1302(0x81);
- write_1302(0x8e,0x80);
- h3=hour/10;
- h4=hour%10;
- m3=minute/10;
- m4=minute%10;
- TR0=0;
- dsreset1(); //温度开始转换
- delayds(1);
- tmpwritebyte1(0xcc); // address all drivers on bus
- tmpwritebyte1(0x44); // initiates a single temperature conversion
- for(a=10;a>0;a--)
- {
- wendu1=tmp1();
- A1=wendu1/100;
- A2t=wendu1%100;
- A2=A2t/10;
- A3=A2t%10;
- display(h3,h4,m3,m4,16,A1,A2,A3);
- // if(wendu1>=htemp1*10)
- // {
- // beep=0;
- // led3=0;
- // }
- // if(wendu1<=ltemp1*10)
- // {
- // beep=0;
- // led4=0;
- // }
- }
- TR0=1;
- if(wendu1>=htemp1*10)
- {
- beep=0;
- led3=0;
- }
- if(wendu1<=ltemp1*10)
- {
- beep=0;
- led4=0;
- }
- }
- if(flag==3)
- {
- ho=read_add(pinjian-4);
- min=read_add(pinjian-3);
- h01=ho/10;h02=ho%10;
- m01=min/10;m02=min%10;
-
- A2t=read_add(pinjian-2)*256+read_add(pinjian-1);
- A1=A2t/100;
- A2=A2t/10%10;
- A3= A2t%10;
- display(h01,h02,m01,m02,16,A1,A2,A3);
- }
-
- }
- }
- /**********************************************************/
- void IR_IN() interrupt 0 using 0
- {
- unsigned char j,k,N=0;
- unsigned char q=0;
- EX0 = 0;
- delay(15);
- if (IRIN==1)
- {
- EX0 =1;
- return;
- }
- //确认IR信号出现
- while (!IRIN) //等IR变为高电平,跳过9ms的前导低电平信号。
- delay(1);
-
- for (j=0;j<4;j++) //收集四组数据
- {
- for (k=0;k<8;k++) //每组数据有8位
- {
- while (IRIN) //等 IR 变为低电平,跳过4.5ms的前导高电平信号。
- { delay(1);}
- while (!IRIN) //等 IR 变为高电平
- delay(1);
- while (IRIN) //计算IR高电平时长
- {
- delay(1);
- N++;
- if (N>=30)
- {
- EX0=1;
- return;
- } //0.14ms计数过长自动离开。
- } //高电平计数完毕
- IRCOM[j]=IRCOM[j] >> 1; //数据最高位补“0”
- if(N>=8)
- {
- IRCOM[j] = IRCOM[j] | 0x80; //数据最高位补“1”
- }
- N=0;
- }
- }
-
- if(IRCOM[2]!=~IRCOM[3]) // 数据出错
- {
- EX0=1;
- return;
- }
-
- IRCOM[5]=IRCOM[2] & 0x0F; //取键码的低四位
- IRCOM[6]=IRCOM[2] >> 4; //右移4次,高四位变为低四位
-
- if(IRCOM[5]>9)
- {
- IRCOM[5]=IRCOM[5]+0x37;
- }
- else
- IRCOM[5]=IRCOM[5]+0x30;
-
- if(IRCOM[6]>9)
- {
- IRCOM[6]=IRCOM[6]+0x37;
- }
- else
- IRCOM[6]=IRCOM[6]+0x30;
- q= (((IRCOM[6]&0x0f)<<4) + (IRCOM[5]&0x0f));
-
- switch(q) //判断按键键码值
- {
- /*0: 设置高温限,1:设置低温限*/
- /* 8: +1 ,9: -1 */
- case 0x16:
- hmodel =1;lmodel =0; // 进入高温限设置
- break; //串口发送0
- case 0x03:
- hmodel=0; lmodel=1 ; // 进入低温限设置
- break; //串口发送01
- case 0x18: displayall() ;break; //串口发送02
- case 0x55: displayall1();break; //串口发送03
- case 0x08: huicha();break; //串口发送04
- case 0x13: TR0=0;pinjian-=4;if(pinjian==0){pinjian=4;};
- break; //串口发送05
- case 0x51: flag=6;
- break; //串口发送06
- case 0x42: fanhui() ;TR0=1; ;break; //串口发送07
- case 0x52: // 加高低温限值
- if(hmodel==1) // 设置高温限
- {
- htemp++;
- }
- else ltemp++;
- break; //串口发送08
- case 0x41:
- if(hmodel==1)
- {
- htemp--;
- }
- else ltemp--;
- break; //串口发送09
- default :break;
- }
- EX0 = 1;
- }
- /********各种子程序*****************************/
- void fanhui()
- {
- hmodel=0;
- lmodel=0;
- flag=0;
- beep=1;
- }
- void displayall()
- {
- flag=1;
- }
- void displayall1()
- {
- flag=2;
- }
- void huicha()
- {
- flag=3;
- }
- /***************ds18b20*****************************/
- void dsreset(void) //send reset and initialization command
- {
- uint i;
- DS=0;
- i=103;
- while(i>0)i--;
- DS=1;
- i=4;
- while(i>0)i--;
- }
- bit tmpreadbit(void) //read a bit
- {
- uint i;
- bit dat;
- DS=0;i++; //i++ for delay
- DS=1;i++;i++;
- dat=DS;
- i=8;while(i>0)i--;
- return (dat);
- }
- uchar tmpread(void) //read a byte date
- {
- uchar i,j,dat;
- dat=0;
- for(i=1;i<=8;i++)
- {
- j=tmpreadbit();
- dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里
- }
- return(dat);
- }
- void tmpwritebyte(uchar dat) //write a byte to ds18b20
- {
- uint i;
- uchar j;
- bit testb;
- for(j=1;j<=8;j++)
- {
- testb=dat&0x01;
- dat=dat>>1;
- if(testb) //write 1
- {
- DS=0;
- i++;i++;
- DS=1;
- i=8;while(i>0)i--;
- }
- else
- {
- DS=0; //write 0
- i=8;while(i>0)i--;
- DS=1;
- i++;i++;
- }
- }
- }
- uint tmp() //get the temperature
- {
- float tt;
- uchar a,b;
- dsreset();
- delay(1);
- tmpwritebyte(0xcc);
- tmpwritebyte(0xbe);
- a=tmpread();
- b=tmpread();
- wendu=b;
- wendu<<=8; //two byte compose a int variable
- wendu=wendu|a;
- tt=wendu*0.0625;
- wendu=tt*10+0.5;
- return wendu;
- }
- /***************ds18b20*****************************/
- void dsreset1(void) //send reset and initialization command
- {
- uint i;
- DS1=0;
- i=103;
- while(i>0)i--;
- DS1=1;
- i=4;
- while(i>0)i--;
- }
- bit tmpreadbit1(void) //read a bit
- {
- uint i;
- bit dat;
- DS1=0;i++; //i++ for delay
- DS1=1;i++;i++;
- dat=DS1;
- i=8;while(i>0)i--;
- return (dat);
- }
- uchar tmpread1(void) //read a byte date
- {
- uchar i,j,dat;
- dat=0;
- for(i=1;i<=8;i++)
- {
- j=tmpreadbit1();
- dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里
- }
- return(dat);
- }
- void tmpwritebyte1(uchar dat) //write a byte to ds18b20
- {
- uint i;
- uchar j;
- bit testb;
- for(j=1;j<=8;j++)
- {
- testb=dat&0x01;
- dat=dat>>1;
- if(testb) //write 1
- {
- DS1=0;
- i++;i++;
- DS1=1;
- i=8;while(i>0)i--;
- }
- else
- {
- DS1=0; //write 0
- i=8;while(i>0)i--;
- DS1=1;
- i++;i++;
- }
- }
- }
- uint tmp1() //get the temperature
- {
- float tt;
- uchar a,b;
- dsreset1();
- delay(1);
- tmpwritebyte1(0xcc);
- tmpwritebyte1(0xbe);
- a=tmpread1();
- b=tmpread1();
- wendu1=b;
- wendu1<<=8; //two byte compose a int variable
- wendu1=wendu1|a;
- tt=wendu1*0.0625;
- wendu1=tt*10+0.5;
- return wendu1;
- }
- /***************ds1302*****************************/
- void write_1302(uchar add,dat)
- {
- uchar i,temp;
- temp=add;
- ce=0;
- _nop_();
- sclk=0;
- _nop_();
- ce=1;
- _nop_();
- for(i=0;i<8;i++)
- {
- sclk=0;
- _nop_();
- if((temp&0x01)==0x01)
- dio=1;
- else
- dio=0;
- temp>>=1;
- sclk=1;
- _nop_();
- }
- temp=dat;
- for(i=0;i<8;i++)
- {
- sclk=0;
- _nop_();
- if((temp&0x01)==0x01)
- dio=1;
- else
- dio=0;
- temp>>=1;
- sclk=1;
- _nop_();
- }
- ce=0;
- sclk=0;
- }
- //读出1302的时间
- uchar read_1302(uchar add)
- {
- uchar dat,dat1,i,temp;
- temp=add;
- ce=0;
- _nop_();
- sclk=0;
- _nop_();
- ce=1;
- for(i=0;i<8;i++)
- {
- sclk=0;
- _nop_();
- if((temp&0x01)==0x01)
- dio=1;
- else
- dio=0;
- temp>>=1;
- sclk=1;
- _nop_();
- }
- for(i=0;i<8;i++)
- {
- sclk=0;
- _nop_();
- if(dio)
- dat|=0x80;
- if(i<7)
- dat>>=1;
- sclk=1;
- }
- dat1=dat/16;
- dat=dat%16;
- dat=dat1*10+dat;
- ce=0;
- sclk=0;
- return dat;
- }
- /***************延时函数*****************************/
- void delay(unsigned char x) //x*0.14MS
- {
- unsigned char i;
- while(x--)
- {
- for (i = 0; i<13; i++) {}
- }
- }
- void display(uchar a,uchar b,uchar c,uchar d,uchar e,uchar f,uchar g,uchar h)
- {
- // P0=table[a];
- // dula=1;
- // dula=0;
- //
- // P0=0xfe;
- // wela=1;
- // wela=0;
- // delay(1);
- //
- // P0=table1[b];
- // dula=1;
- // dula=0;
- //
- // P0=0xfd;
- // wela=1;
- // wela=0;
- // delay(1);
- //
- // P0=table[c];
- // dula=1;
- // dula=0;
- //
- // P0=0xfb;
- // wela=1;
- // wela=0;
- // delay(1);
- //
- // P0=table[d];
- // dula=1;
- // dula=0;
- //
- // P0=0xf7;
- // wela=1;
- // wela=0;
- // delay(1);
- //
- // P0=table[e];
- // dula=1;
- // dula=0;
- //
- // P0=0xef;
- // wela=1;
- // wela=0;
- // delay(1);
- //
- // P0=table[f];
- // dula=1;
- // dula=0;
- //
- // P0=0xdf;
- // wela=1;
- // wela=0;
- // delay(1);
- //
- // P0=table1[g];
- // dula=1;
- // dula=0;
- //
- // P0=0xbf;
- // wela=1;
- // wela=0;
- // delay(1);
- //
- // P0=table[h];
- // dula=1;
- // dula=0;
- //
- // P0=0x7f;
- // wela=1;
- // wela=0;
- // delay(1);
-
- P0=table[a];
- dula=1;
- dula=0;
- P0=0xfe;
- wela=1;
- wela=0;
- delay(3);
- P0=table1[b];
- dula=1;
- dula=0;
- P0=0xfd;
- wela=1;
- wela=0;
- delay(3);
- P0=table[c];
- dula=1;
- dula=0;
- P0=0xfb;
- wela=1;
- wela=0;
- delay(3);
- P0=table[d];
- dula=1;
- dula=0;
- P0=0xf7;
- wela=1;
- wela=0;
- delay(5);
- P0=table[e];
- dula=1;
- dula=0;
- P0=0xef;
- wela=1;
- wela=0;
- delay(3);
- P0=table[f];
- dula=1;
- dula=0;
- P0=0xdf;
- wela=1;
- wela=0;
- delay(3);
- P0=table1[g];
- dula=1;
- dula=0;
- P0=0xbf;
- wela=1;
- wela=0;
- delay(3);
- P0=table[h];
- dula=1;
- dula=0;
- P0=0x7f;
- wela=1;
- wela=0;
- delay(3);
- //
- P0=0x00;
- dula=1;
- dula=0;
- P0=0x7f;
- wela=1;
- wela=0;
- delay(3);
- }
- void display1(uchar a,uchar b)
- {
- P0=table[a];
- dula=1;
- dula=0;
-
- P0=0xfe;
- wela=1;
- wela=0;
- delay(1);
-
- P0=table1[b];
- dula=1;
- dula=0;
-
- P0=0xfd;
- wela=1;
- wela=0;
- delay(1);
- P0=0xff;
- wela=1;
- wela=0;
- delay(1);
- }
- void delay1(int ms)
- {
- unsigned char y;
- while(ms--)
- {
- for(y = 0; y<250; y++)
- {
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }
- }
- }
- void time0() interrupt 1
- { unsigned i=255;
- TH0=(65536-50000)/256; //对TH0 TL0赋值
- TL0=(65536-50000)%256; //重装计数初值
- p++;
- if(p==20) //10s存一次
- {
- p=0;
- init_24c02();
- write_add(pin,h1*10+h2);
- while(i--);i=255;
- write_add(pin+1,m1*10+m2);
- while(i--);i=255;
- write_add(pin+2,wendu/256);
- while(i--);i=255;
- write_add(pin+3,wendu%256);
- while(i--);i=255;
- pin+=4;
- pinjian=pin;
- if(pin==255)
- {
- pin=0;
- }
- }
-
- }
- //************************************************************
- void delay1ms()
- {
- unsigned int i;
- for(i=8024;i>0;i--); //延时124*8+10=1002us
- }
- void delayds(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=120;y>0;y--);
- }
复制代码
所有资料51hei提供下载:
新红外.zip
(71.95 KB, 下载次数: 12)
|