温度实时检测预警系统(STC89C51RC+DS18B20)
前言:这是很简单的一个作业,只用了一个DS18B20温度传感器;但事情总归是一步一步来,从简单的开始。
目的:通过本次作业,对传感器的工作原理和过程有一个大致的了解,以便后续进一步的学习与提升。
工具:win11
操作界面、keil5
IDE、stc-isp
烧录软件、QX-MCS51
开发板、DS18B20
温度传感器。
实现功能:
- 实时采集周围的温度信息并进行显示;
- 根据应用环境不同可通过按键设置不同的预警上下限。
一、软件功能模块设计
1.1 延时函数
//1.代码:
void delay(uint x)
{
uint a,b;
for(a=x;a>0;a--)
for(b=10;b>0;b--);
}
/*2.说明:
- 定义了一个名为delay的函数,用于在单片机程序中产生延时;
延时函数在很多情况下是必需的,因为单片机的处理速度远高于外部设备,如传感器和显示器。
- 函数的声明:void delay(uint x);
这意味着函数delay接受一个无符号整数x作为参数,这个参数决定了延时的长度。
- 这段代码使用了两个嵌套循环来产生延时。外层循环变量a从x开始递减,直到a等于0为止。
每次外层循环迭代,内层循环变量b都会执行10次循环;
内层循环每次循环都会执行一个空操作,即什么也不做,仅仅等待10个时钟周期。
因此,如果x是延时长度,那么实际的延时时间是x * 10个时钟周期。
*/
1.2 初始化温度传感器接口
//1.代码:
void ds_reset(void)
{
uint i;
DS=0;
i=100;
while(i>0)i--;
DS=1;
i=4;
while(i>0)i--;
}
/*2.说明:
- 定义了一个名为ds_reset的函数,用于初始化DS18B20温度传感器的接口;
DS18B20是一个常见的数字温度传感器,它通过单总线与微控制器通信。
- 函数的声明如下:void ds_reset(void);
这意味着函数ds_reset不接受任何参数。
- 这段代码实现了以下步骤来初始化DS18B20:
1)声明一个无符号整数变量i。
2)将DS引脚置低电平,这通常是用来选择DS18B20并发起通信的步骤。
3)等待大约100个时钟周期;
这个等待时间确保了DS18B20有足够的时间来响应总线上的低电平信号。
4)将DS引脚置高电平,结束对DS18B20的选中。
5)再次等待大约4个时钟周期;
这个等待时间是为了确保DS18B20能够完成初始化过程并准备好接收或发送数据。
*/
1.3 读字节的一位
//1.代码:
bit tmp_readbit(void)
{
uint i;
bit dat;
DS=0;i++;
DS=1;i++;i++;
dat=DS;
i=8; while(i>0)i--;
return (dat);
}
/*2.说明:
- 定义了一个名为tmp_readbit的函数,用于从DS18B20温度传感器读取一个字节的一位;
这个函数通常用于在单总线通信中读取温度传感器的状态或数据。
- 函数的声明如下:bit tmp_readbit(void);
这意味着函数tmpreadbit不接受任何参数,并返回一个位值(bit)。
- 这段代码实现了以下步骤来读取一个字节的一位:
1)声明一个无符号整数变量i和一个位变量dat。
2)将DS引脚置低电平,这通常是用来选择DS18B20并发起通信的步骤。
在这里,i被增加1,这是为了产生一个小的延时,以确保DS18B20有足够的时间响应。
3)将DS引脚置高电平,结束对DS18B20的选中。
在这里,i被增加2,这是为了产生一个更长的延时,以确保DS18B20已经准备好接收或发送数据。
4)将DS18B20的数据线DS的状态读取到位变量dat中。
由于DS是一个输出引脚,在读取之前需要将其置为输入模式。
5)等待8个时钟周期,以确保数据线上的电平稳定。
6)返回位变量dat的值,这将是DS18B20数据线上的当前状态(0或1)。
*/
1.4 读一个字节数据
//1.代码:
uchar tmp_read(void)
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tmp_readbit();
dat=(j<<7)|(dat>>1);
}
return(dat);
}
/*2.说明:
- 定义了一个名为tmp_read的函数,用于从DS18B20温度传感器读取一个字节的数据;
这个函数通常用于在单总线通信中读取温度传感器的温度值或其他数据。
- 函数的声明如下:uchar tmp_read(void);
这意味着函数tmp_read不接受任何参数,并返回一个字节大小(unsigned char)的数据。
- 这段代码实现了以下步骤来读取一个字节的数据:
1)声明三个无符号字符变量i、j和dat。
2)将dat变量初始化为0。
3)循环8次,对应于一个字节的8位。
4)在每次循环中,调用tmp_readbit函数读取数据线DS的一位,并将其存储在变量j中。
5)使用位运算将读取的数据位拼接到dat变量中。
这里使用左移操作'<<'将j的最高位移到dat的最低位,
然后使用右移操作'>>'将dat的其他位向右移动一位;
6)循环完成后,dat变量中包含了一个完整的字节数据,最高位在最前面。
7)返回dat变量的值。
- 注:这个函数假设tmp_readbit函数返回的是一个位值(bit),
并且该位值在循环中被拼接成一个字节的数据。
这种方法确保了字节数据的最低位首先被读取并存储在dat变量中。
*/
1.5 将数据写入DS18B20
//1.代码:
void tmp_writebyte(uchar dat)
{
uint i;
uchar j;
bit test_b;
for(j=1;j<=8;j++)
{
test_b=dat&0x01;
dat=dat>>1;
if(test_b)
{
DS=0;
i++;i++;
DS=1;
i=8;while(i>0)i--;
}
else
{
DS=0;
i=8;while(i>0)i--;
DS=1;
i++;i++;
}
}
}
/*2.说明:
- 定义了一个名为tmp_writebyte的函数,用于将一个字节的数据写入DS18B20温度传感器;
这个函数通常用于在单总线通信中向温度传感器发送命令或设置。
- 函数的声明如下:void tmp_writebyte(uchar dat);
这意味着函数tmp_writebyte接受一个无符号字符变量dat作为参数。
- 这段代码实现了以下步骤来向DS18B20写入一个字节的数据:
1)声明三个变量:一个无符号整数i、一个无符号字符j和一个位变量test_b。
2)对dat变量的每一位进行循环,共8次,对应于一个字节的8位。
3)使用位运算'&'和'>>'来提取dat变量的当前最低位并将其存储在test_b变量中。
4)将dat变量向右移动一位,准备提取下一个位。
5)如果test_b变量值为1,则执行写1的操作:
5.1)将DS引脚置低电平,选择DS18B20。
5.2)等待两个时钟周期。
5.3)将DS引脚置高电平,结束对DS18B20的选中。
5.4)等待8个时钟周期,以确保DS18B20有足够的时间处理写入的数据。
6)如果test_b变量值为0,则执行写0的操作:
6.1)将DS引脚置低电平,选择DS18B20。
6.2)等待8个时钟周期,以确保DS18B20有足够的时间处理写入的数据。
6.3)将DS引脚置高电平,结束对DS18B20的选中。
6.4)等待两个时钟周期。
*/
1.6 DS18B20开始变化
//1.代码:
void tmp_change(void)
{
ds_reset();
delay(1);
tmp_writebyte(0xcc);
tmp_writebyte(0x44);
}
/*2.说明:
- 定义了一个名为tmp_change的函数,用于初始化DS18B20温度传感器并开始一个温度转换;
这个函数通常用于在单总线通信中配置DS18B20以开始测量温度。
- 函数的声明如下:void tmp_change(void);
这意味着函数tmp_change不接受任何参数。
- 这段代码实现了以下步骤来初始化DS18B20并开始温度转换:
1)调用ds_reset函数初始化DS18B20温度传感器接口;
这个函数会发送一个复位脉冲到DS18B20,以便从休眠状态唤醒它。
2)调用delay函数等待1个时钟周期;
这个延时是为了确保DS18B20有足够的时间响应复位脉冲。
3)调用tmp_writebyte函数发送一个字节的数据到DS18B20;
发送0xCC,这是一个跳过ROM命令,它告诉DS18B20跳过ROM地址序列,直接与单总线通信。
4)再次调用tmp_writebyte函数发送另一个字节的数据到DS18B20;
发送0x44,这是开始温度转换命令,它告诉DS18B20开始一次温度测量。
*/
1.7 获取温度
//1.代码:
uint tmp()
{
float tt;
uchar a,b;
ds_reset();
delay(1);
tmp_writebyte(0xcc);
tmp_writebyte(0xbe);
a=tmp_read();
b=tmp_read();
temp=b;
temp<<=8;
temp=temp|a;
tt=temp*0.0625;
temp=tt*10+0.5;
return temp;
}
/*2.说明:
- 定义了一个名为tmp的函数,用于从DS18B20温度传感器获取温度值;
这个函数通常用于在单总线通信中读取DS18B20的温度测量结果。
- 函数的声明如下:uint tmp();
这意味着函数tmp不接受任何参数,并返回一个无符号整数(unsigned int)类型的温度值。
- 这段代码实现了以下步骤来获取DS18B20的温度值:
1)声明一个float类型的变量tt和一个uchar类型的变量a和b。
2)调用ds_reset函数初始化DS18B20温度传感器接口。
3)调用delay函数等待1个时钟周期。
4)调用tmp_writebyte函数发送两个字节的数据到DS18B20;
分别发送0xCC和0xBE,这是一个跳过ROM命令和一个温度转换命令。
5)调用tmp_read函数两次,读取两个字节的温度数据;
这两个字节的数据分别存储在变量a和b中。
6)将变量b左移8位,与变量a进行或运算,组合成一个整数变量temp,代表温度的高8位和低8位。
7)将temp乘以0.0625,将温度从摄氏度转换为开尔文。
8)将转换后的温度值乘以10,并加上0.5,进行四舍五入。
9)返回最终的温度值。
*/
1.8 控制显示器的函数
//1.1 代码:发送控制命令
void write_com(uchar com)
{
P0=com;
rs=0;
lcd_en=0;
delay(10);
lcd_en=1;
delay(10);
lcd_en=0;
}
/*1.2 说明:
- 定义了一个名为write_com的函数,用于控制一个显示器(LCD1602)的行为;
这个函数通常用于在单片机系统中与液晶显示器(LCD1602)通信,发送控制命令。
- 函数的声明如下:void write_com(uchar com);
这意味着函数write_com接受一个无符号字符变量com作为参数。
- 这段代码实现了以下步骤来控制显示器:
1)将变量com的内容发送到数据线P0,这通常是LCD1602的数据输入引脚。
2)将rs引脚置低电平,这通常是LCD1602的命令/数据选择引脚,将其置低表示发送命令。
3)将lcd_en引脚置低电平,这通常是LCD的enable引脚,将其置低表示准备接收数据。
4)调用delay函数等待10个时钟周期。
5)将lcd_en引脚置高电平,这通常表示开始数据传输。
6)再次调用delay函数等待10个时钟周期。
7)将lcd_en引脚置低电平,这通常表示数据传输完成。
*/
// 2.1 代码:发送数据
void write_date(uchar date)
{
P0=date;
rs=1;
lcden=0;
delay(10);
lcden=1;
delay(10);
lcden=0;
}
/*2.2 说明:
- 定义了一个名为write_date的函数,用于控制一个显示器(LCD1602)的行为;
这个函数通常用于在单片机系统中与液晶显示器(LCD1602)通信,发送数据。
- 函数的声明如下:void write_date(uchar date);
这意味着函数write_date接受一个无符号字符变量date作为参数。
- 这段代码实现了以下步骤来控制显示器:
1)将变量date的内容发送到数据线P0,这通常是LCD1602的数据输入引脚。
2)将rs引脚置高电平,这通常是LCD1602的命令/数据选择引脚,将其置高表示发送数据。
3)将lcd_en引脚置低电平,这通常是LCD1602的enable引脚,将其置低表示准备接收数据。
4)调用delay函数等待10个时钟周期。
5)将lcd_en引脚置高电平,这通常表示开始数据传输。
6)再次调用delay函数等待10个时钟周期。
7)将lcd_en引脚置低电平,这通常表示数据传输完成。
*/
1.9 初始化显示器
//1.代码:
void init()
{
rw=0;
dula=0;
wela=0;
write_com(0x38);
delay(20);
write_com(0x0f);
delay(20);
write_com(0x06);
delay(20);
write_com(0x01);
delay(20);
}
/*2.说明:
- 定义了一个名为init的函数,用于初始化一个液晶显示器(LCD1602);
这个函数通常用于设置显示器的初始状态,例如设置显示模式、光标移动方向等。
- 函数的声明如下:void init();
这意味着函数init不接受任何参数。
- 这段代码实现了以下步骤来初始化显示器:
1)将rw、dula和wela引脚置低电平;
这些通常是LCD1602的控制引脚,分别用于读写控制、显示开/关控制和背光控制。
2)调用write_com函数发送一个字节的数据到LCD;
发送0x38,这设置了LCD1602的显示模式为16×2显示、5×7点阵和8位数据接口。
3)调用delay函数等待20个时钟周期。
4)再次调用write_com函数发送数据到LCD;
发送0x0F,这进一步设置了LCD1602的显示模式。
5)再次调用delay函数等待20个时钟周期。
6)再次调用write_com函数发送数据到LCD;
发送0x06,这设置了光标右移,字符不移。
7)再次调用delay函数等待20个时钟周期。
8)最后,调用write_com函数发送数据到LCD;
发送0x01,这是清屏幕指令,用于清除LCD1602上的以前显示的内容。
*/
1.10 显示实际温度
//1.代码:
void dis1(uint temp){
uint x;
uint y;
uint z;
if(temp == 850)temp = 250;
x = temp/100;
y = (temp - 100 * x)/10;
z = temp%10;
table2[4] = (uchar)(x + 48);
table2[5] = (uchar)(y + 48);
table2[7] = (uchar)(z + 48);
}
/*2.说明:
- 定义了一个名为dis1的函数,用于将温度值显示在LCD上1602;
这个函数假设温度传感器读到的值是实际温度的10倍,因此需要进行转换才能正确显示。
- 函数的声明如下:void dis1(uint temp);
这意味着函数dis1接受一个无符号整数变量temp作为参数,这个变量是温度传感器的读数值。
- 这段代码实现了以下步骤来将温度值显示在LCD上1602:
1)定义三个无符号整数变量x、y和z,用于存储温度值的百位、十位和个位。
2)如果温度值temp等于850,则将其重置为250,这是为了处理某种异常情况。
3)通过除法计算得到百位数x,即temp除以100的结果。
4)通过减法和除法计算得到十位数y,即temp减去百位数乘以100后除以10的结果。
5)通过取模运算得到个位数z,即temp对10取模的结果。
6)将百位、十位和个位数转换为字符,并存储在table2数组的相应位置,以便在LCD上显示。
- 注意,这里假设table2数组已经定义,并且有足够的空间存储这三个字符。
*/
1.11 判断蜂鸣器响的频率及时间
//1.代码:
if ((temp > setTemp)&&(temp < setTemp1))
{
d = setTemp1 - temp;
beep = 1;
led = 1;
delay(f * d);
beep = 0;
led = 0;
}else if(temp > setTemp1){
beep = 0;
led = 0;
}
else{
beep = 1;
led = 1;
}
/*2.说明:
- 其代码在函数体(void dis1(uint temp))内部。
- 一个判断语句,用于根据当前温度temp与设定的温度范围来控制蜂鸣器beep和led的状态。
- 代码逻辑如下:
1.判断当前温度temp是否在设定的温度范围setTemp(下限)和setTemp1(上限)之间。
如果是,执行以下步骤:
1.1)计算当前温度与设定温度上限setTemp1之间的差值d。
1.2)将蜂鸣器beep的状态设置为1,表示蜂鸣器开始响。
1.3)将led的状态设置为1,表示LED开始亮。
1.4)等待一个时间f * d,这个时间是根据差值d计算出来的,单位是毫秒。
1.5)之后,将蜂鸣器beep的状态设置为0,表示蜂鸣器停止响。
1.6)将led的状态设置为0,表示LED停止亮。
2.如果当前温度temp>setTemp1,
执行以下步骤:
2.1)将蜂鸣器beep的状态设置为0,表示蜂鸣器停止响。
2.2)将led的状态设置为0,表示LED停止亮。
3.如果当前温度temp<=setTemp,
执行以下步骤:
3.1)将蜂鸣器beep的状态设置为1,表示蜂鸣器开始响。
3.2)将led的状态设置为1,表示LED开始亮。
*/
1.12 显示下限温度
//1.代码:
void dis2(uint setTemp){
uint j = setTemp/100;
uint k = (setTemp - 100 * j)/10;
table3[4] = (uchar)(j + 48);
table3[5] = (uchar)(k + 48);
}
/*2.说明:
- 定义了一个名为dis2的函数,用于将设定的温度值显示在LCD1602上;
这个函数假设设定的温度值是实际温度的10倍,因此需要进行转换才能正确显示。
- 函数的声明如下:void dis2(uint setTemp);
这意味着函数dis2接受一个无符号整数变量setTemp作为参数,这个变量应该是设定温度值的10倍。
- 这段代码实现了以下步骤来将设定的温度值显示在LCD上:
1)定义两个无符号整数变量j和k,用于存储温度值的百位和十位。
2)通过除法计算得到百位数j,即setTemp除以100的结果。
3)通过减法和除法计算得到十位数k,即setTemp减去百位数乘以100后除以10的结果。
4)将百位和十位数转换为字符,并存储在table3数组的相应位置,以便在LCD1602上显示。
- 注意,这里假设table3数组已经定义,并且有足够的空间存储这两个字符。
*/
1.13 显示上限温度
//1.代码:
void dis3(uint setTemp1){
uint j = setTemp1/100;
uint k = (setTemp1 - 100 * j)/10;
table3[11] = (uchar)(j + 48);
table3[12] = (uchar)(k + 48);
}
/*2.说明:
- 定义了一个名为dis3的函数,用于将预警温度值显示在LCD1602上;
这个函数假设预警温度值是实际温度的10倍,因此需要进行转换才能正确显示。
- 函数的声明如下: void dis3(uint setTemp1);
这意味着函数dis3接受一个无符号整数变量setTemp1作为参数,这个变量应该是预警温度值的10倍。
- 这段代码实现了以下步骤来将预警温度值显示在LCD1602上:
1)定义两个无符号整数变量j和k,用于存储温度值的百位和十位。
2)通过除法计算得到百位数j,即setTemp1除以100的结果。
3)通过减法和除法计算得到十位数k,即setTemp1减去百位数乘以100后除以10的结果。
4)将百位和十位数转换为字符,并存储在table3数组的相应位置,以便在LCD1602上显示。
- 注意,这里假设table3数组已经定义,并且有足够的空间存储这两个字符。
*/
1.14 主函数
//1.代码:
void main()
{
uchar a;
init();
do{
//将第一个字符写在向右偏移17个字符处,为后面的由右向左划入做准备。
write_com(0x80);
delay(20);
tmp_change();
dis1(tmp());
dis2(setTemp);
dis3(setTemp1);
for(a=0;a<8;a++)
{
write_date(table2[a]);
delay(2);
}
write_com(0xc0);
delay(5);
for(a=0;a<13;a++)
{
write_date(table3[a]);
delay(2);
}
delay(40) ;
if(key_s0 == 0)//判断S2是否按键
{
delay(5);//软件延时
if(key_s0 == 0)
{
if(setTemp <= setTemp1-1)
setTemp = setTemp + 10; //计数加1
}
while(!key_s0); //松手检测
}
if(key_s1 == 0)//判断S3是否按键
{
delay(5);//软件延时
if(key_s1 == 0)
{
setTemp = setTemp - 10; //计数加1
}
while(!key_s1); //松手检测
}
if(key_s2 == 0)//判断S4是否按键
{
delay(5);//软件延时
if(key_s2 == 0)
{
setTemp1 = setTemp1 + 10; //计数加1
}
while(!key_s2); //松手检测
}
if(key_s3 == 0)//判断S5是否按键
{
delay(5);//软件延时
if(key_s3 == 0)
{
if(setTemp <= setTemp1-1)
setTemp1 = setTemp1 - 10; //计数加1
}
while(!key_s3); //松手检测
}
}while(1);
}
/*2.说明:
- 一个主循环部分,
它负责初始化显示器,读取温度传感器数据,显示温度信息,
并处理按键输入来更新温度设置。
- 以下是代码的主要步骤:
1)init()函数,
被调用来初始化显示器。
2)一个do-while循环开始,
它将一直执行直到程序被其他信号中断或重启。
3)write_com(0x80),
在循环内部,将光标移动到LCD的第一个字符位置,为后续的由右向左划入做准备。
4)delay(20);
进行延时。
5)tmp_change();
函数被调用来读取温度传感器的数据,并更新全局变量tmp。
6)dis1(tmp());
函数被调用来显示实际温度。
7)dis2(setTemp);
函数被调用来显示设定温度。
8)dis3(setTemp1);
函数被调用来显示预警温度。
9)write_date(table2[a]);
通过循环,将温度信息的字符写入LCD1602。
10)write_com(0xC0);
将光标移动到下一个字符位置,为显示设定温度和预警温度的字符做准备。
11)write_date(table3[a]);
再次通过循环,将温度信息的字符写入LCD1602。
12)delay(40);
进行延时。
13)检查按键S0是否被按下,如果是,则递增设定温度setTemp。
14)检查按键S1是否被按下,如果是,则递减设定温度setTemp。
15)检查按键S2是否被按下,如果是,则递增预警温度setTemp1。
16)检查按键S3是否被按下,如果是,则递减预警温度setTemp1。
17)循环继续,等待下一个循环周期的开始。
*/
1.15 头文件及其相关变量、按键定义
//1.代码:
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit DS=P2^2;
sbit dula=P2^6;
sbit wela=P2^7;
sbit lcden=P3^4;
sbit rs=P3^5;
sbit rw=P3^6;
sbit beep=P2^3;//蜂鸣器
sbit led=P1^0; //led灯
uint f = 100;//可以通过改这个来控制蜂鸣器的频率
sbit key_s0 = P3^0;//S2按键位定义
sbit key_s1 = P3^1;//S3按键位定义
sbit key_s2 = P3^2;//S4按键位定义
sbit key_s3 = P3^3;//S5按键位定义
uint d; //预警温度和实际温度的差值
uint temp; //实际温度
uint setTemp = 280;//界限温度
uint setTemp1 = 300;//预警温度
uchar table2[]="Tem:25.0"; //显示实际温度
uchar table3[]="Cri:25 War:30";//显示预警温度和界限温度
/*2.说明:
- 这段代码是一个针对8051系列微控制器的C语言程序,
它使用了reg52.h头文件,该头文件包含了8051微控制器的寄存器定义。
- 代码的主要功能是控制一个LCD显示屏,一个蜂鸣器,一个LED灯,
以及读取和处理按键输入来控制蜂鸣器的频率和处理温度预警。
- 代码的分析:
1)#include <reg52.h>
包含8051微控制器的寄存器定义头文件。
2)#define uchar unsigned char 和 #define uint unsigned int
定义两个宏,uchar表示无符号字符类型,uint表示无符号整数类型。
3)sbit DS=P2^2;
定义一个位变量DS,用于LCD的数据选择引脚,连接到微控制器的P2口的第2位。
4)sbit dula=P2^6;
定义一个位变量dula,用于LCD的数据线D7,连接到微控制器的P2口的第6位。
5)sbit wela=P2^7;
定义一个位变量wela,用于控制LCD的写入信号,连接到微控制器的P2口的第7位。
6)sbit lcd_en=P3^4;
定义一个位变量lcd_en,用于控制LCD的显示使能信号,连接到微控制器的P3口的第4位。
7)sbit rs=P3^5;
定义一个位变量rs,用于选择LCD的数据还是指令,连接到微控制器的P3口的第5位。
8)sbit rw=P3^6;
定义一个位变量rw,用于LCD的读写控制,连接到微控制器的P3口的第6位。
9)sbit beep=P2^3;
蜂鸣器:定义一个位变量beep,用于控制蜂鸣器,连接到微控制器的P2口的第3位。
10)sbit led=P1^0;
LED灯:定义一个位变量led,用于控制LED灯,连接到微控制器的P1口的第0位。
11)uint f = 100;
可以通过改这个来控制蜂鸣器的频率,
定义一个无符号整数变量f,用于控制蜂鸣器的频率,初始值为100。
12)sbit key_s0 = P3^0;
S2按键位定义:定义一个位变量key_s0,用于S2按键,连接到微控制器的P3口的第0位。
13)sbit key_s1 = P3^1;
S3按键位定义:定义一个位变量key_s1,用于S3按键,连接到微控制器的P3口的第1位。
14)sbit key_s2 = P3^2;
S4按键位定义:定义一个位变量key_s2,用于S4按键,连接到微控制器的P3口的第2位。
15)sbit key_s3 = P3^3;
S5按键位定义:定义一个位变量key_s3,用于S5按键,连接到微控制器的P3口的第3位。
16)uint d;
预警温度和实际温度的差值:定义一个无符号整数变量d,用于存储预警温度和实际温度的差值。
17)uint temp;
实际温度:定义一个无符号整数变量temp,用于存储实际温度。
18)uint setTemp = 280;
界限温度:定义一个无符号整数变量setTemp,用于存储界限温度,初始值为280。
19)uint setTemp1 = 300;
预警温度:定义一个无符号整数变量setTemp1,用于存储预警温度,初始值为300。
20)uchar table2[]="Tem:25.0";
显示实际温度:定义一个字符数组table2,用于显示实际温度,其中包含字符串。
*/
二、硬件功能设计
2.1 材料清单
1)QX-MCS51开发板(STC89C51RC芯片):
2)LCD1602液晶显示器:
3)DS18B20数字温度传感器:
4)USB数据线:
2.2 各器件装配连接
2.3 代码的敲写与烧录
Step1:打开keil uVision5
Step2:新建工程
Step3:输入文件名TTTTTd
Step4:选择AT89C52(可替代STC89C52RC)
Step5:选中“是”对话框
Step6:在project下的source group中创建新项目
Step7:选择.c文件形式,并输入项目文件名tttttd
Step8:在.c文件中输入相关代码
Step9:点击bulid操作
Step10:点击“生成输出”按钮,输出.hex文件
Step12:打开stc-isp烧录软件
Step13:选择好芯片型号和串口
Step16:打开程序文件,选中生成的.hex文件,并执行下载/编程操作
2.4 功能调试
Step1:通电烧录程序后,开发板上的lcd1602显示器界面:
Step2:调试独立键盘模块功能
1)测试界限温度上调:
2)测试界限温度下调:
3)测试预警温度上调:
4)测试预警温度下调:
三、总结心得
- 课设进行到这,基本已经完工,剩下的,就是整理梳理自己在这一整个课设过程中获得的体验感受与心得。
- 缓一口气,静气平心……
- 刚开始的一两天,不知所措,一直在捣腾keil、proteus、stc-isp的安装搭建操作环境,感到烦躁慌张。
- 然后是了解51开发板和各个功能模块以及ds18b20温度传感器。
- 其实一开始自己选择的课设是停车场车位管理系统,但做到一半,proteus仿真图和keil里的代码都搞的差不多了,发现自己手头上并没有与之对应的红外传感器。
- 当时,有点崩了,我的内心。
- 我调整心态,这真的很重要,太关键了,尤其是自己在实战处理各种项目问题的时候。
… - 这是一次简单、基础的课程设计,但花费了我不少时间和精力和情绪。
- 我试着管理我的情绪、作息,以一种积极乐观、沉着冷静的处理面对态度和方式来完成此次课设。
- 到这里,内心真的有了些许、不少的提升,关于上述的种种。
… - 课设也好,生活学习乃至以后的进入社会工作,事情都是一步一步做出来的,问题也是一个一个不断去认识与解决的,人也在这过程当中得到了相应的锻炼甚至磨练。
- 只有不放弃、勇敢地前进,相信——山重水复疑无路,自然而然、有幸的柳暗花明又一村。
… - 这其中的起起伏伏,磕磕绊绊,让我意识到,我真是一只井底之蛙,故步自封,也真的算是自业自得、自作自受了。
… - 中午11点20了,该去吃中饭了,肚子也饿了。
- 继续前行,继续上路,路上,有我想要的一切。
※※※※※※※※※※2024/6/30
四、代码参考
[1] 使用STC89C52单片机完成一个温度预警系统_单片机基于stc89c52实现温度报警器-CSDN博客
原文链接:https://blog.csdn.net/qq_36236684/article/details/80867693