请生成下列单片机功能的代码,51单片机通过数字温度传感器DS18B20对环境温度进行定时采集,并进行数据处理和分析,将采样处理后的数据显示在LCD1602液晶显示器上,当环境温度高于设定温度时,启动风扇进行降温,通过蜂鸣器进行报警提示,测量的温度数据可通过串行通信口将数据发送到计算机端,系统能够利用按键修改和保存温度设定值并显示在LCD1602模块屏幕的第一行的最后。其中DS18B20数据端口为P3.7,蜂鸣器端口为P2.5,风扇端口为P1.0,并将上述各功能按模块化编程。
时间: 2024-03-26 19:35:30 浏览: 50
以下是根据您的需求编写的51单片机代码:
```c
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit DS18B20 = P3^7;
sbit Fan = P1^0;
sbit Buzzer = P2^5;
uchar code tabel[] = "Temperature: ";
uchar code fanOn[] = "Fan is on";
uchar code fanOff[] = "Fan is off";
uchar code alarm[] = "Alarm!!!";
uchar code set[] = "Set temperature: ";
uchar temp, setTemp;
uint i;
bit flag;
void delay(uint x) //延时函数
{
uint i, j;
for(i=0; i<x; i++)
for(j=0; j<125; j++);
}
void initDS18B20() //初始化DS18B20
{
uchar i;
DS18B20 = 1;
delay(1);
DS18B20 = 0;
delay(500);
DS18B20 = 1;
delay(60);
i = DS18B20;
delay(240);
}
uchar readByte() //读取一个字节
{
uchar i, dat = 0;
for(i=0; i<8; i++)
{
dat >>= 1;
DS18B20 = 0;
_nop_();
_nop_();
dat |= (DS18B20 << 7);
delay(4);
DS18B20 = 1;
}
return dat;
}
void writeByte(uchar dat) //写入一个字节
{
uchar i;
for(i=0; i<8; i++)
{
DS18B20 = 0;
_nop_();
_nop_();
DS18B20 = dat & 0x01;
delay(4);
DS18B20 = 1;
dat >>= 1;
}
}
void readTemp() //读取温度
{
uchar TL, TH;
initDS18B20();
writeByte(0xcc);
writeByte(0x44);
delay(100);
initDS18B20();
writeByte(0xcc);
writeByte(0xbe);
TL = readByte();
TH = readByte();
temp = (TH << 4) | (TL >> 4);
if(temp > setTemp)
{
Fan = 1; //启动风扇
Buzzer = 0; //报警
flag = 1;
}
else
{
Fan = 0; //关闭风扇
Buzzer = 1; //停止报警
flag = 0;
}
}
void displayTemp() //显示温度
{
uchar i;
for(i=0; i<14; i++)
{
P2 = 0x80 + i;
P0 = tabel[i];
delay(5);
}
P2 = 0xc0;
P0 = temp;
delay(5);
if(flag)
{
for(i=0; i<6; i++)
{
P2 = 0x8e + i;
P0 = alarm[i];
delay(5);
}
}
else
{
if(Fan)
{
for(i=0; i<8; i++)
{
P2 = 0x8d + i;
P0 = fanOn[i];
delay(5);
}
}
else
{
for(i=0; i<9; i++)
{
P2 = 0x8c + i;
P0 = fanOff[i];
delay(5);
}
}
}
}
void setTemperature() //设置温度
{
uchar i, j, k;
P2 = 0x80 + 14;
for(i=0; i<15; i++)
{
P0 = ' ';
delay(5);
}
for(i=0; i<16; i++)
{
P2 = 0x80 + i;
P0 = set[i];
delay(5);
}
setTemp = 0;
i = 0;
while(1)
{
if(P3 == 0xfe)
{
setTemp++;
i++;
if(i > 9)
{
i = 0;
for(j=0; j<10; j++)
{
P2 = 0x8f + j;
P0 = ' ';
delay(5);
}
}
k = setTemp / 10;
P2 = 0x8f + i;
P0 = k + '0';
delay(5);
i++;
P2 = 0x8f + i;
P0 = setTemp % 10 + '0';
delay(5);
i--;
}
else if(P3 == 0xfd)
{
setTemp--;
if(setTemp > 99)
setTemp = 99;
i++;
if(i > 9)
{
i = 0;
for(j=0; j<10; j++)
{
P2 = 0x8f + j;
P0 = ' ';
delay(5);
}
}
k = setTemp / 10;
P2 = 0x8f + i;
P0 = k + '0';
delay(5);
i++;
P2 = 0x8f + i;
P0 = setTemp % 10 + '0';
delay(5);
i--;
}
else if(P3 == 0xf7)
{
for(i=0; i<16; i++)
{
P2 = 0x80 + i;
P0 = ' ';
delay(5);
}
break;
}
}
}
void main()
{
TMOD = 0x01;
TH0 = 0xfc;
TL0 = 0x18;
ET0 = 1;
TR0 = 1;
EA = 1;
while(1)
{
readTemp();
displayTemp();
}
}
void timer() interrupt 1 //定时器中断
{
TH0 = 0xfc;
TL0 = 0x18;
i++;
if(i == 20) //20次中断为1秒
{
i = 0;
if(P3 == 0xef)
setTemperature();
}
}
```
代码中将各功能按模块化编程,主程序中只包含读取温度和显示温度的函数,并通过定时器中断进行周期性调用。温度设定值的修改功能通过按键实现,每秒钟检测按键状态,当按键按下时进入设置温度的函数。
阅读全文