标题:
单片机温度传感器的显示、存储与传输程序
[打印本页]
作者:
sfghjkdfhg
时间:
2022-4-14 10:05
标题:
单片机温度传感器的显示、存储与传输程序
使用DS18B20温度传感器采集温度,并将温度的值显示在LCD1602上,可以通过按键调整温度的阈值,当温度传感器的值在阈值之外,报警电路发出警报,在按键的时候可以将温度传感器的值数据保存在AT24C02中。可以通过串口将温度传感器的值上传到电脑的串口调试助手。
原理图如下:
原理图.PNG
(145.72 KB, 下载次数: 82)
下载附件
2022-4-14 10:05 上传
单片机源程序如下:
#include<reg52.h>
#include<intrins.h>
#include"lcd1602.h"
#include"key.h"
#include"timer0.h"
#include"at24c02.h"
#include"uart.h"
#include"nixie.h"
typedef unsigned char uchar;
typedef unsigned int uint;
sbit Bus=P3^7;//数据单总线
sbit LED=P3^6;//LED报警灯
void Delay10us(void);//10us延时函数
void Delay600us(void);//600us延时子函数
void Delay(uint n);//LCD1602中延时子函数
void Delay1ms(uint t);//t毫秒延时子函数
void Init_Ds(void);//DS18B20初始化
void Write_Ds(uchar com);//向DS18B20写入一字节
uchar Read_Ds(void);//从DS18B20读出一字节
uint Get_Tem(void);//获取温度值
void Change(uint x);//把整型数值x转换为字符串
void Write_com(uchar com);//写命令子函数
void Write_dat(uchar dat);//写数据子函数
void Init_1602(void);//LCD1602初始化子函数
void Show(uchar x,uchar y,uchar *str);//LCD1602显示子函数
uchar str[4];//储存转换值对应的字符串
unsigned char KeyNum;
char TLow,THigh;
unsigned char t;
unsigned char second=1;
unsigned char minute;
unsigned char hour;
void main()
{
unsigned int temp;
UART_Init(); //串口初始化
LED=0;
LCD_Init();
// THigh=AT24C02_ReadByte(0); //读取温度阈值数据
// TLow=AT24C02_ReadByte(1);
if(THigh>125 || TLow<-55 || THigh<=TLow)
{
THigh=25; //如果阈值非法,则设为默认值
TLow=20;
}
LCD_ShowString(2,1,"TH:");
LCD_ShowString(2,9,"TL:");
LCD_ShowSignedNum(2,4,THigh,3);
LCD_ShowSignedNum(2,12,TLow,3);
while(1)
{
KeyNum=Key();
temp=Get_Tem();
UART_SendByte(temp); //串口发送温度值
if(temp>THigh) //越界判断
{
LED=1;
}
else if(temp<TLow)
{
LED=1;
}
else
{
LED=0;
}
Change(temp);
LCD_ShowString(1,1,"Temperature:");
LCD_ShowString(1,13,str);
/*阈值判断及显示*/
if(KeyNum)
{
if(KeyNum==1) //K1按键,THigh自增
{
THigh++;
if(THigh>125){THigh=125;}
}
if(KeyNum==2) //K2按键,THigh自减
{
THigh--;
if(THigh<=TLow){THigh++;}
}
if(KeyNum==3) //K3按键,TLow自增
{
TLow++;
if(TLow>=THigh){TLow--;}
}
if(KeyNum==4) //K4按键,TLow自减
{
TLow--;
if(TLow<-55){TLow=-55;}
}
LCD_ShowSignedNum(2,4,THigh,3); //显示阈值数据
LCD_ShowSignedNum(2,12,TLow,3);
AT24C02_WriteByte(0,temp); //写入到At24C02中保存
Delay(20);
AT24C02_WriteByte(1,THigh);
Delay(20);
AT24C02_WriteByte(1,TLow);
Delay(20);
}
}
}
/***************************************延时函数体**************************/
void Delay10us(void)//10us延时函数
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=1;a>0;a--);
}
void Delay600us(void)//600us延时函数
{
unsigned char a,b;
for(b=119;b>0;b--)
for(a=1;a>0;a--);
}
void Delay1ms(uint t)//t毫秒延时函数
{
unsigned char a,b;
uint i;
for(i=0;i<t;i++)
for(b=199;b>0;b--)
for(a=1;a>0;a--);
}
/********************************DS18B20初始化函数*************************/
void Init_Ds(void)//DS18B20初始化
{
Bus=0;//主动拉低480-960us(此处选择600us)
Delay600us();
Bus=1;//释放总线,传感器15-60us后拉低总线
while(Bus);//等待传感器拉低;
while(!Bus);//度过传感器被拉低的时间(60-240us)后主动拉高
Bus=1;//主动拉高
}
/********************************向DS18B20写入一字节***********************/
void Write_Ds(uchar com)//从低位开始写入
{
uchar mask;
for(mask=0x01;mask!=0;mask<<=1)
{
//该位为0,先拉低,15us后在拉高,并通过延时使整个周期为60us
//该位为1,先拉低并在15us内(此处选择5us)拉高,并通过延时使整个周期为60us
Bus=0;
_nop_();_nop_();_nop_();_nop_();_nop_();//先拉低5us
if((com&mask)==0)//该位是0
{
Bus=0;
}
else//该位是1
{
Bus=1;
}
Delay10us();Delay10us();Delay10us();Delay10us();Delay10us();;//延时60us
_nop_();_nop_();_nop_();_nop_();_nop_();
Bus=1;//拉高
_nop_();_nop_();//写两个位之间至少有1us的间隔(此处选择2us)
}
}
/********************************从DS18B20读出一字节***********************/
uchar Read_Ds(void)//先读的是低位,整个读周期至少为60us,但控制器采样要在15us内完成,相邻“位”之间至少间隔1us
{
uchar value=0,mask;
for(mask=0x01;mask!=0;mask<<=1)
{
Bus=0;//先把总线拉低超过1us(此处选择2us)后释放
_nop_();_nop_();
Bus=1;
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();//再延时6us后读总线数据
if(Bus==0)//如果该位是0
{
value&=(~mask);
}
else
{
value|=mask;
}
Delay10us();Delay10us();Delay10us();Delay10us();Delay10us();//再延时52us,凑够至少60us的采样周期
_nop_();_nop_();
Bus=1;
_nop_();_nop_();//写两个位之间至少有1us的间隔(此处选择2us)
}
return value;
}
/**********************************获取温度值函数***************************/
uint Get_Tem(void)
{
uint temp=0;
float tp;
uchar LSB=0,MSB=0;
Delay1ms(10);//延时10ms度过不稳定期
Init_Ds();//Ds18b20初始化
Delay1ms(1);
Write_Ds(0xcc);//跳过ROM寻址
Write_Ds(0x44);//启动一次温度转换
Delay1ms(1000);//延时1s等待转化
Init_Ds();//Ds18b20初始化
Delay1ms(1);
Write_Ds(0xcc);//跳过ROM寻址
Write_Ds(0xbe);//发送读值命令·
LSB=Read_Ds();
MSB=Read_Ds();
temp=MSB;
temp<<=8;
temp|=LSB;
tp=temp*0.0625;
temp=tp;
if(tp-temp>=0.5)
{
temp+=1;
}
return temp;
}
/******************************把整型数据转换为字符串**********************/
void Change(uint x)
{
str[0]=x/100+48;
str[1]=(x/10)%10+48;
str[2]=x%10+48;
str[3]='\0';
}
复制代码
仅供参考,如存在错误和不足之处,请大家回帖多多指教,切勿照搬,Keil代码下载:
代码.7z
(32.55 KB, 下载次数: 28)
2022-4-14 17:55 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
Zcc…
时间:
2023-5-23 12:52
楼主 仿真可以分享一下么
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1