#include <reg51.h>
#include <intrins.h>
#include <DS18B20.h>
#define uchar unsigned char
#define uint unsigned int
#define SMGIO P0
sbit SET=P1^0; //定义设定上下限键
sbit ADD=P1^1; //定义增加键
sbit DEC=P1^2; //定义减小限键
sbit SMG1=P2^0; //定义数码管第一位
sbit SMG2=P2^1; //定义数码管第二位
sbit SMG3=P2^2; //定义数码管第三位
sbit SMG4=P2^3; //定义数码管第四位
sbit BEEP=P2^5; //定义蜂鸣器报警
uint tempValue; //变量 存储当前温度值
uint HI_Alarm=30; //初始上限
uint LO_Alarm=10; //初始下限
uchar SMG_CC[]={0x5f,0x44,0x9d,0xd5,0xc6,0xd3,0xdb,0x45,0xdf,0xd7}; //共阴极数码管0-9编码
uchar SMG_CC_DOT[]={0x7f,0x64,0xbd,0xf5,0xe6,0xf3,0xfb,0x65,0xff,0xf7}; //共阴极数码管0-9编码 带小数点
/********************************************************************/
/* 1ms延时 */
/********************************************************************/
void delayms(uint x)
{
uchar i;
while(x--)
{
for(i=150;i>0;i--);
}
}
void Display_Temperature() //显示温度
{
char smg1,smg2,smg3,smg4;
smg1=tempValue/1000; //以下表示将温度值拆分开
smg2=(tempValue-smg1*1000)/100;
smg3=(tempValue%100)/10;
smg4=tempValue%10;
if(tflag==1) //负数显示
{
SMGIO=SMG_CC[smg4]; //显示小数位
SMG4=0;
delayms(1);
SMG4=1;
SMGIO=SMG_CC_DOT[smg3]; //显示个数位
SMG3=0;
delayms(1);
SMG3=1;
if(smg2==0)
{
SMGIO=0x80; //显示十数位
SMG2=0;
delayms(1);
SMG2=1;
SMGIO=0x00; //显示百数位
SMG1=0;
delayms(1);
SMG1=1;
}
else
{
SMGIO=SMG_CC[smg2]; //显示十数位
SMG2=0;
delayms(1);
SMG2=1;
SMGIO=0x80; //显示十数位
SMG1=0;
delayms(1);
SMG1=1;
}
}
else //正数显示
{
SMGIO=SMG_CC[smg4]; //显示小数位
SMG4=0;
delayms(1);
SMG4=1;
SMGIO=SMG_CC_DOT[smg3]; //显示个数位
SMG3=0;
delayms(1);
SMG3=1;
if(smg1==0)
{
SMGIO=0x00;
SMG1=0;
delayms(1);
SMG1=1;
if(smg2==0)
{
SMGIO=0x00;
SMG1=0;
delayms(1);
SMG1=1;
}
else
{
SMGIO=SMG_CC[smg2];
SMG2=0;
delayms(1);
SMG2=1;
}
}
else
{
SMGIO=SMG_CC[smg1];
SMG1=0;
delayms(1);
SMG1=1;
SMGIO=SMG_CC[smg2];
SMG2=0;
delayms(1);
SMG2=1;
}
}
}
void Display_HI_Alarm()
{
SMGIO=0xce; //显示H
SMG1=0;
delayms(1);
SMG1=1;
SMGIO=0x80; //显示-
SMG2=0;
delayms(1);
SMG2=1;
SMGIO=SMG_CC[HI_Alarm/10]; //显示报警高值十位
SMG3=0;
delayms(1);
SMG3=1;
SMGIO=SMG_CC[HI_Alarm%10]; //显示报警高值个数位
SMG4=0;
delayms(1);
SMG4=1;
}
void Display_LO_Alarm()
{
SMGIO=0x1a; //显示L
SMG1=0;
delayms(1);
SMG1=1;
SMGIO=0x80; //显示-
SMG2=0;
delayms(1);
SMG2=1;
SMGIO=SMG_CC[LO_Alarm/10]; //显示报警高值十位
SMG3=0;
delayms(1);
SMG3=1;
SMGIO=SMG_CC[LO_Alarm%10]; //显示报警高值个数位
SMG4=0;
delayms(1);
SMG4=1;
}
void SET_KEY()
{ bit SET_FLAG=1;
if(SET==0) //设定按键按下
{
delayms(40);
if(SET==1) //延时去除抖动再次判断是否按下按键
{
while(SET_FLAG==1)
{
Display_HI_Alarm(); //设定上限温度值
if(ADD==0) //增加按键
{
delayms(40); //延时去除抖动再次判断是否按下按键
if(ADD==1)
HI_Alarm++; //温度值加一
}
if(DEC==0) //减小按键
{
delayms(40);
if(DEC==1) //延时去除抖动再次判断是否按下按键
HI_Alarm--; //温度值减一
}
if(SET==0) //以下表示 再次按下设定按键 进入设定下限程序
{
delayms(40);
if(SET==1) //延时去除抖动再次判断是否按下按键
{
while(1)
{
Display_LO_Alarm(); //设定下限温度值
if(ADD==0) //增加按键
{
delayms(40);
if(ADD==1) //延时去除抖动再次判断是否按下按键
LO_Alarm++; //温度值加一
}
if(DEC==0) //减小按键
{
delayms(40);
if(DEC==1) //延时去除抖动再次判断是否按下按键
LO_Alarm--; //温度值减一
}
if(SET==0) //设定按键按下
{
delayms(40);
if(SET==1)
{ //延时去除抖动再次判断是否按下按键
SET_FLAG=0;
break; //上下限设定完成 退出
}
}
}
}
}
}
}
}
}
void BJ_LED()
{
if(tempValue>=HI_Alarm*10||tempValue<=LO_Alarm*10) //如果温度超过上下限
BEEP=0; //蜂鸣器报警
else BEEP=1;
}
void main()
{
unsigned char i;
BEEP=1; //表示先清除报警
while(1)
{
i++;
if(i>50)
{
i=0;
tempValue=ReadTemperature(); //读取温度值
}
Display_Temperature(); //显示温度数据
BJ_LED(); //调用报警函数
SET_KEY(); //调用按键读取函数
}
}

#ifndef uint
#define uint unsigned int
#endif
#ifndef ul
#define ul unsigned long
#endif
#ifndef uchar
#define uchar unsigned char
#endif
sbit DQ=P3^6;
bit tflag;
void DS18B20_delay(uint i)
{
while(i--);
}
void Init_DS18B20(void)
{
uchar x=0;
DQ = 1;
DS18B20_delay(8);
DQ = 0;
DS18B20_delay(80);
DQ = 1;
DS18B20_delay(10);
x=DQ;
DS18B20_delay(5);
}
uchar DS18B20_ReadOneChar(void)
{
uchar i=0;
uchar dat = 0;
for (i=8;i>0;i--)
{
DQ = 0;
dat>>=1;
DQ = 1;
if(DQ)
dat |= 0x80;
DS18B20_delay(5);
}
return(dat);
}
void DS18B20_WriteOneChar(uchar dat)
{
uchar i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
DS18B20_delay(5);
DQ = 1;
dat>>=1;
}
DS18B20_delay(5);
}
uint ReadTemperature(void)
{
uchar a=0;
uint b=0;
uint t=0;
Init_DS18B20();
DS18B20_WriteOneChar(0xCC);
DS18B20_WriteOneChar(0x44);
DS18B20_delay(200);
Init_DS18B20();
DS18B20_WriteOneChar(0xCC);
DS18B20_WriteOneChar(0xBE);
a=DS18B20_ReadOneChar();
b=DS18B20_ReadOneChar();
b<<=8;
t=a+b;
if(t<0x0fff)
tflag=0;
else
{
t=~t+1;
tflag=1;
}
t=t*(0.625);
return(t);
}
加注释是吧?
#ifndef uint
#define uint unsigned int
#endif
#ifndef ul
#define ul unsigned long
#endif
#ifndef uchar
#define uchar unsigned char
#endif
sbit DQ = P3^6; // 定义温度传感器数据线接在P3引脚的第6位
bit tflag; // 温度正负标志位,为1表示负温度,为0表示正温度
// 延时函数
void DS18B20_delay(uint i)
{
while (i--);
}
// 初始化DS18B20传感器
void Init_DS18B20(void)
{
uchar x = 0;
DQ = 1; // 设置DQ引脚为高电平
DS18B20_delay(8);
DQ = 0; // 拉低DQ引脚
DS18B20_delay(80); // 等待80
DQ = 1; // 释放DQ引脚
DS18B20_delay(10); // 等待10
x = DQ; // 读取DQ引脚电平
DS18B20_delay(5);
}
// 从DS18B20中读取一个字节数据
uchar DS18B20_ReadOneChar(void)
{
uchar i = 0;
uchar dat = 0;
for (i = 8; i > 0; i--)
{
DQ = 0; // 拉低DQ引脚
dat >>= 1; // 将dat右移1位
DQ = 1; // 释放DQ引脚
if (DQ)
dat |= 0x80; // 如果DQ为高电平,则将dat的最高位置1
DS18B20_delay(5); // 等待5
}
return(dat); // 返回读取的数据
}
// 向DS18B20写入一个字节数据
void DS18B20_WriteOneChar(uchar dat)
{
uchar i = 0;
for (i = 8; i > 0; i--)
{
DQ = 0; // 拉低DQ引脚
DQ = dat & 0x01; // 设置DQ引脚为dat的最低位
DS18B20_delay(5); // 等待5
DQ = 1; // 释放DQ引脚
dat >>= 1; // 将dat右移1位
}
DS18B20_delay(5); // 等待5
}
// 读取DS18B20传感器的温度值
uint ReadTemperature(void)
{
uchar a = 0;
uint b = 0;
uint t = 0;
Init_DS18B20(); // 初始化DS18B20传感器
DS18B20_WriteOneChar(0xCC); // 跳过ROM操作
DS18B20_WriteOneChar(0x44); // 启动温度转换
DS18B20_delay(200); // 等待转换完成
Init_DS18B20(); // 再次初始化DS18B20传感器
DS18B20_WriteOneChar(0xCC); // 跳过ROM操作
DS18B20_WriteOneChar(0xBE); // 读取温度值
a = DS18B20_ReadOneChar(); // 读取温度值的低8位
b = DS18B20_ReadOneChar(); // 读取温度值的高8位
b <<= 8; // 将高8位左移8位
t = a + b; // 温度值合并
if (t < 0x0fff)
tflag = 0; // 温度为正数,标志位为0
else
{
t = ~t + 1; // 温度为负数,转换为补码形式
tflag = 1; // 温度为负数,标志位为1
}
t = t * 0.625; // 将温度值乘以0.625得到实际温度值(因为DS18B20的温度分辨率为0.625°C)
return(t); // 返回温度值
}
这段代码基本上已经是每行都有注释了,重点注释一下DS18B20的吧
#ifndef uint
#define uint unsigned int
#endif
#ifndef ul
#define ul unsigned long
#endif
#ifndef uchar
#define uchar unsigned char
#endif
sbit DQ=P3^6;
bit tflag;
void DS18B20_delay(uint i)//DS18B20时序中用到的延时
{
while(i--);
}
void Init_DS18B20(void))//DS18B20的初始化
{
uchar x=0;
DQ = 1;
DS18B20_delay(8);
DQ = 0;
DS18B20_delay(80);
DQ = 1;
DS18B20_delay(10);
x=DQ;
DS18B20_delay(5);
}
uchar DS18B20_ReadOneChar(void)//从DS18B20读取1字节
{
uchar i=0;
uchar dat = 0;
for (i=8;i>0;i--)
{
DQ = 0;
dat>>=1;
DQ = 1;
if(DQ)
dat |= 0x80;
DS18B20_delay(5);
}
return(dat);
}
void DS18B20_WriteOneChar(uchar dat)//向DS18B20写入1字节
{
uchar i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
DS18B20_delay(5);
DQ = 1;
dat>>=1;
}
DS18B20_delay(5);
}
uint ReadTemperature(void)//读取温度信息
{
uchar a=0;
uint b=0;
uint t=0;
Init_DS18B20();
DS18B20_WriteOneChar(0xCC); //发SKIP ROM命令
DS18B20_WriteOneChar(0x44); //发开始转换命令
DS18B20_delay(200);//延时
Init_DS18B20();//复位
DS18B20_WriteOneChar(0xCC); //发SKIP ROM命令
DS18B20_WriteOneChar(0xBE); //发读存储器命令
a=DS18B20_ReadOneChar(); //读取温度高位字节和地位字节
b=DS18B20_ReadOneChar();
b<<=8;//高低字节合并
t=a+b;
if(t<0x0fff)
tflag=0;
else
{
t=~t+1;
tflag=1;
}
t=t*(0.625); //转换为温度值
return(t);
}
好的,你给出的代码给你都加上注释了,如下:
#include <reg51.h> // 包含AT89C51单片机的寄存器和位定义的头文件
#include <intrins.h> // 提供汇编指令的宏定义的头文件
#include <DS18B20.h> // DS18B20温度传感器的用户定义头文件
sbit SMGIO = P2^7; // 数码管数据口引脚定义
sbit SET = P3^0; // 设定按键引脚定义
sbit ADD = P3^1; // 增加按键引脚定义
sbit DEC = P3^2; // 减小按键引脚定义
sbit SMG1 = P0^0; // 数码管第1位引脚定义
sbit SMG2 = P0^1; // 数码管第2位引脚定义
sbit SMG3 = P0^2; // 数码管第3位引脚定义
sbit SMG4 = P0^3; // 数码管第4位引脚定义
sbit BEEP = P0^4; // 蜂鸣器引脚定义
uint tempValue; // 当前温度值
uint HI_Alarm; // 上限温度值
uint LO_Alarm; // 下限温度值
uchar code SMG_CC[] = { // 共阴极数码管0-9的编码数组
0xC0, // 0
0xF9, // 1
0xA4, // 2
0xB0, // 3
0x99, // 4
0x92, // 5
0x82, // 6
0xF8, // 7
0x80, // 8
0x98 // 9
};
void delayms(uint x) { // 延时函数,单位为毫秒
while(x--) {
_nop_();
_nop_();
_nop_();
_nop_();
}
}
void Display_Temperature() { // 显示温度函数
uchar i;
if(tempValue >= 0) { // 正温度
SMG1 = SMG_CC[tempValue / 100]; // 数码管第1位显示百位
SMG2 = SMG_CC[(tempValue / 10) % 10]; // 数码管第2位显示十位
SMG3 = SMG_CC[tempValue % 10]; // 数码管第3位显示个位
SMG4 = 0x7F; // 数码管第4位显示 "℃"
} else { // 负温度
tempValue = -tempValue;
SMG1 = 0xBF; // 显示“-”
SMG2 = SMG_CC[tempValue / 100];
SMG3 = SMG_CC[(tempValue / 10) % 10];
SMG4 = SMG_CC[tempValue % 10];
}
for(i=0; i<100; i++) { // 设置动态扫描显示时间
delayms(1);
}
}
void Display_HI_Alarm() { // 显示上限报警函数
SMG1 = SMG_CC[HI_Alarm / 100];
SMG2 = SMG_CC[(HI_Alarm / 10) % 10];
SMG3 = SMG_CC[HI_Alarm % 10];
SMG4 = 0x7F; // 数码管第4位显示 "℃"
}
void Display_LO_Alarm() { // 显示下限报警函数
SMG1 = 0xBF; // 显示“-”
SMG2 = SMG_CC[LO_Alarm / 100];
SMG3 = SMG_CC[(LO_Alarm / 10) % 10];
SMG4 = SMG_CC[LO_Alarm % 10];
}
void SET_KEY() { // 设定按键函数
uchar setTime = 0;
if(SET == 0) { // 如果设定按键被按下
delayms(5); // 延时一段时间,消除抖动
if(SET == 0) { // 再次检测设定按键是否仍然被按下
while(!SET) { // 按住设定按键不松手
delayms(5);
setTime++;
if(setTime >= 40) { // 长按设定按键超过2秒,进入设定模式
while(!SET) {
delayms(200);
if(ADD == 0) { // 增加按键被按下
delayms(5);
if(ADD == 0) { // 再次检测增加按键是否仍然被按下
HI_Alarm++;
if(HI_Alarm > 125) { // 上限温度最大值为125℃
HI_Alarm = 125;
}
Display_HI_Alarm();
}
}
if(DEC == 0) { // 减小按键被按下
delayms(5);
if(DEC == 0) { // 再次检测减小按键是否仍然被按下
LO_Alarm--;
if(LO_Alarm > 125) { // 下限温度最大值为-55℃
LO_Alarm = -55;
}
Display_LO_Alarm();
}
}
}
}
}
}
}
}
void BJ_LED() { // 蜂鸣器报警函数
if(tempValue > HI_Alarm || tempValue < LO_Alarm) {
BEEP = 0; // 蜂鸣器鸣响
} else {
BEEP = 1; // 蜂鸣器不鸣响
}
}
void main() {
DS18B20_Init(); // 温度传感器初始化
while(1) {
tempValue = DS18B20_GetTemp(); // 读取温度值
Display_Temperature(); // 显示温度
BJ_LED(); // 控制蜂鸣器报警
SET_KEY(); // 读取设定按键并设置上下限温度值
}
}
简要说明一下,这段代码是用于控制温度传感器DS18B20以及数码管显示的程序。
首先包含了一些头文件,包括reg51.h、intrins.h和DS18B20.h。其中reg51.h是对单片机AT89C51的寄存器和位定义进行声明,intrins.h提供了一些汇编指令的宏定义,DS18B20.h是一个用户自定义的头文件,可能包含了一些与DS18B20温度传感器相关的函数和定义。
然后定义了一些宏和变量,如uchar表示无符号字符,uint表示无符号整数,SMGIO表示数码管的数据口,SET、ADD、DEC等表示按键的引脚,SMG1、SMG2、SMG3、SMG4等表示数码管的第1位到第4位引脚,BEEP表示蜂鸣器引脚,tempValue表示当前温度值,HI_Alarm表示上限温度值,LO_Alarm表示下限温度值,SMG_CC和SMG_CC_DOT是共阴极数码管0-9的编码数组。
接下来是一个用于延时的函数delayms,参数x表示延时的毫秒数。该函数通过循环的方式进行延时。
然后是一个用于显示温度的函数Display_Temperature。其中将温度值拆分成各个位的数字,并根据温度值的正负进行不同的显示。
接下来是两个用于显示报警上限和下限的函数Display_HI_Alarm和Display_LO_Alarm。这两个函数根据上限和下限温度值进行相应的显示。
然后是一个用于读取设定按键并设置上下限温度值的函数SET_KEY。该函数在设定按键按下时,通过增加键和减小键来调整上下限温度值。
接下来是一个用于控制蜂鸣器报警的函数BJ_LED。根据温度值是否超过上下限来设置蜂鸣器的状态。
最后是主函数main。在该函数中循环执行以下操作:读取温度值并显示、控制蜂鸣器报警、读取设定按键并设置上下限温度值。
对于DS18B20温度传感器的代码,首先对传感器进行初始化,然后通过发送指令读取温度值,并进行相应的处理。
以上是对给出的代码进行的基本解释,希望能对你有所帮助。如有更多问题,请随时提问。
DS18B20是美国DALLAS公司生产的数字温度传感器,体积小、低功耗、抗干扰能力强。可直接将温度转化成数字信号传送给单片机处理,因而可省去传统的信号放大、A/D转换等外围电路。
DS18B20测量温度范围-55~+128℃,在-10~+ 85℃范围内,测量精度可达士0.5℃,非常适合于恶劣环境的现场温度测量,也可用于各种狭小空间内设备的测温,如环境控制、过程监测过程监测、测温类消费电子产品以及多点温度测控系统。