標題:
單片機溫度傳感器的顯示、存儲與傳輸程序
[打印本頁]
作者:
sfghjkdfhg
時間:
2022-4-14 10:05
標題:
單片機溫度傳感器的顯示、存儲與傳輸程序
使用DS18B20溫度傳感器采集溫度,并將溫度的值顯示在LCD1602上,可以通過按鍵調整溫度的閾值,當溫度傳感器的值在閾值之外,報警電路發(fā)出警報,在按鍵的時候可以將溫度傳感器的值數據保存在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寫入一字節(jié)
uchar Read_Ds(void);//從DS18B20讀出一字節(jié)
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); //串口發(fā)送溫度值
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寫入一字節(jié)***********************/
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讀出一字節(jié)***********************/
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度過不穩(wěn)定期
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);//發(fā)送讀值命令·
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.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1