11.05926MHz的51单片机,连接DS18B20和LCD1602以及三个按键,一个键控制显示温度设定报警值调节再按一下完成温度报警值设定,一个键调节温度报警值值加,一个键调节调节温度报警值减,显示内容为WD:采集的温度保留后两位小数并带有℃单位。按以上要求编写出程序
时间: 2023-10-10 22:05:51 浏览: 36
很高兴能为您提供帮助!以下是基于您的要求编写的示例程序,注释部分为代码解释:
```
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit DSPORT = P3^4; // DS18B20数据线连接的IO口
sbit RS = P2^6; // LCD数据/指令选择端口(低电平表示指令,高电平表示数据)
sbit RW = P2^5; // LCD读/写选择端口(低电平表示写入,高电平表示读取)
sbit EN = P2^7; // LCD使能端口(高电平有效)
sbit K1 = P1^0; // 按键1
sbit K2 = P1^1; // 按键2
sbit K3 = P1^2; // 按键3
uchar code table[] = "WD:"; // 静态显示文字
// 函数声明
void delay(uint z);
void write_com(uchar com);
void write_data(uchar dat);
void init();
void display_temp();
void adjust_alarm_temp();
// 主函数
void main()
{
uchar temp;
uchar alarm_temp = 30; // 默认温度报警值为30℃
init(); // 初始化LCD屏幕
while (1)
{
display_temp(); // 显示采集的温度
if (!K1) // 如果按键1被按下
{
adjust_alarm_temp(); // 进入调节温度报警值的函数
while (!K1); // 等待按键1被松开
}
if (!K2) // 如果按键2被按下
{
alarm_temp++; // 增加温度报警值
while (!K2); // 等待按键2被松开
}
if (!K3) // 如果按键3被按下
{
alarm_temp--; // 减少温度报警值
while (!K3); // 等待按键3被松开
}
if (temp >= alarm_temp) // 如果当前温度高于或等于温度报警值
{
write_com(0x80 + 0x40); // 将光标移到第二行
write_data('A'); // 在第二行显示字母"A",表示温度报警
}
else
{
write_com(0x80 + 0x40); // 将光标移到第二行
write_data(' '); // 在第二行显示空格
}
}
}
// 延时函数
void delay(uint z)
{
uint x, y;
for (x = z; x > 0; x--)
{
for (y = 110; y > 0; y--);
}
}
// 发送指令到LCD屏幕
void write_com(uchar com)
{
RS = 0; // 选择指令模式
RW = 0; // 写入模式
P0 = com; // 发送指令
EN = 1; // 使能
delay(5); // 延时一段时间
EN = 0; // 禁能
}
// 发送数据到LCD屏幕
void write_data(uchar dat)
{
RS = 1; // 选择数据模式
RW = 0; // 写入模式
P0 = dat; // 发送数据
EN = 1; // 使能
delay(5); // 延时一段时间
EN = 0; // 禁能
}
// 初始化LCD屏幕
void init()
{
write_com(0x38); // 8位数据接口,2行显示,5×7点阵字符,不显示光标
write_com(0x0c); // 显示器开,光标关闭,字符不闪烁
write_com(0x06); // 文字显示不动,光标自动移动
write_com(0x01); // 清除屏幕
}
// 读取温度
uchar read_temp()
{
uchar temp;
uchar i;
DSPORT = 0; // 拉低总线
delay(1); // 延时1us
DSPORT = 1; // 释放总线
delay(1); // 延时1us
i = DSPORT; // 读取DS18B20的响应脉冲
delay(1); // 延时1us
if (i == 0) // 如果DS18B20响应脉冲存在
{
DSPORT = 0; // 拉低总线,给DS18B20发送读取温度的命令
delay(1); // 延时1us
DSPORT = 1; // 释放总线
delay(1); // 延时1us
temp = DSPORT; // 读取温度的低八位
delay(1); // 延时1us
temp |= DSPORT << 8; // 读取温度的高八位
}
return temp;
}
// 显示温度
void display_temp()
{
uchar temp;
char buffer[7];
temp = read_temp(); // 读取温度
sprintf(buffer, "%d.%dC", temp / 10, temp % 10); // 将温度转换成字符串
write_com(0x80); // 将光标移到第一行第一列
for (uchar i = 0; i < 3; i++)
{
write_data(table[i]); // 显示静态文字"WD:"
}
for (uchar i = 0; i < 4; i++)
{
write_data(buffer[i]); // 显示温度字符串
}
}
// 调节温度报警值
void adjust_alarm_temp()
{
uchar alarm_temp = 30;
char buffer[4];
while (!K1) // 等待按键1被松开
{
write_com(0x80 + 0x40); // 将光标移到第二行
write_data('A'); // 在第二行显示字母"A",表示进入调节模式
write_data('T'); // 在第二行显示字母"T",表示正在调节温度报警值
write_data(':'); // 在第二行显示冒号
sprintf(buffer, "%2d", alarm_temp); // 将温度报警值转换成字符串
for (uchar i = 0; i < 2; i++)
{
write_data(buffer[i]); // 显示温度报警值字符串
}
if (!K2) // 如果按键2被按下
{
alarm_temp++; // 增加温度报警值
while (!K2); // 等待按键2被松开
}
if (!K3) // 如果按键3被按下
{
alarm_temp--; // 减少温度报警值
while (!K3); // 等待按键3被松开
}
delay(500); // 延时一段时间
}
}
```
请注意,此示例程序仅供参考,并且可能需要根据实际硬件和软件环境进行调整。如果您有任何疑问,请随时提出。