Ⅰ 單片機溫度計上電顯示溫度怎麼設置
1、首先通過DS18B20檢測溫度,若溫度高於設定最大閾值,紅燈亮,若溫度低於設定最小閾值,黃燈亮。
2、其次通過ADC0832配合電壓檢測電路檢測當前電壓,通過蜂鳴器提供按鍵音。
3、最後通過顯示屏顯示數字溫度計的溫度下限閾值,當前溫度值,電壓表的電壓值,通過按鍵切換界面,設置上下限閾值。
Ⅱ 用51單片機和18b20做一個溫度計,求一個完整程序,要求用12864顯示。
這個是用數碼顯示的 你自己改改顯示就ok了 12864 有帶字型檔的那種,只要輸入ASCII碼就行了 程序有點亂,你注意換行就行
1.DS18B20基本知識
DS18B20數字溫度計是DALLAS公司生產的1-Wire,即單匯流排器件,具有線路簡單,體積小的特點。因此用它來組成一個測溫系統,具有線路簡單,在一根通信線,可以掛很多這樣的數字溫度計,十分方便。
1、DS18B20產品的特點
(1)、只要求一個埠即可實現通信。
(2)、在DS18B20中的每個器件上都有獨一無二的序列號。
(3)、實際應用中不需要外部任何元器件即可實現測溫。
(4)、測量溫度范圍在-55。C到+125。C之間。
(5)、數字溫度計的解析度用戶可以從9位到12位選擇。
(6)、內部有溫度上、下限告警設置。
2、DS18B20的引腳介紹
TO-92封裝的DS18B20的引腳排列見圖1,其引腳功能描述見表1。
(底視圖)圖1
表1 DS18B20詳細引腳功能描述
序號 名稱 引腳功能描述
1 GND 地信號
2 DQ 數據輸入/輸出引腳。開漏單匯流排介面引腳。當被用著在寄生電源下,也可以向器件提供電源。
3 VDD 可選擇的VDD引腳。當工作於寄生電源時,此引腳必須接地。
3. DS18B20的使用方法
由於DS18B20採用的是1-Wire匯流排協議方式,即在一根數據線實現數據的雙向傳輸,而對AT89S51單片機來說,硬體上並不支持單匯流排協議,因此,我們必須採用軟體的方法來模擬單匯流排的協議時序來完成對DS18B20晶元的訪問。
由於DS18B20是在一根I/O線上讀寫數據,因此,對讀寫的數據位有著嚴格的時序要求。DS18B20有嚴格的通信協議來保證各位數據傳輸的正確性和完整性。該協議定義了幾種信號的時序:初始化時序、讀時序、寫時序。所有時序都是將主機作為主設備,單匯流排器件作為從設備。而每一次命令和數據的傳輸都是從主機主動啟動寫時序開始,如果要求單匯流排器件回送數據,在進行寫命令後,主機需啟動讀時序完成數據接收。數據和命令的傳輸都是低位在先。
DS18B20的復位時序
DS18B20的讀時序
對於DS18B20的讀時序分為讀0時序和讀1時序兩個過程。
對於DS18B20的讀時隙是從主機把單匯流排拉低之後,在15秒之內就得釋放單匯流排,以讓DS18B20把數據傳輸到單匯流排上。DS18B20在完成一個讀時序過程,至少需要60us才能完成。
DS18B20的寫時序
對於DS18B20的寫時序仍然分為寫0時序和寫1時序兩個過程。
對於DS18B20寫0時序和寫1時序的要求不同,當要寫0時序時,單匯流排要被拉低至少60us,保證DS18B20能夠在15us到45us之間能夠正確地采樣IO匯流排上的「0」電平,當要寫1時序時,單匯流排被拉低之後,在15us之內就得釋放單匯流排。
4. 實驗任務
用一片DS18B20構成測溫系統,測量的溫度精度達到0.1度,測量的溫度的范圍在-20度到+100度之間,用8位數碼管顯示出來。
5. 電路原理圖
6. 系統板上硬體連線
(1). 把「單片機系統」區域中的P0.0-P0.7用8芯排線連接到「動態數碼顯示」區域中的ABCDEFGH端子上。
(2). 把「單片機系統」區域中的P2.0-P2.7用8芯排線連接到「動態數碼顯示」區域中的S1S2S3S4S5S6S7S8端子上。
(3). 把DS18B20晶元插入「四路單匯流排」區域中的任一個插座中,注意電源與地信號不要接反。
(4). 把「四路單匯流排」區域中的對應的DQ端子連接到「單片機系統」區域中的P3.7/RD端子上。
C語言源程序#include <AT89X52.H>#include <INTRINS.h> unsigned char code displaybit[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};unsigned char code displaycode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,0x40};unsigned char code dotcode[32]={0,3,6,9,12,16,19,22,25,28,31,34,38,41,44,48,50,53,56,59,63,66,69,72,75,78,81,84,88,91,94,97};unsigned char displaycount;unsigned char displaybuf[8]={16,16,16,16,16,16,16,16};unsigned char timecount;unsigned char readdata[8]; sbit DQ=P3^7;bit sflag; bit resetpulse(void){unsigned char i; DQ=0;for(i=255;i>0;i--);DQ=1;for(i=60;i>0;i--);return(DQ);for(i=200;i>0;i--);} void writecommandtods18b20(unsigned char command){unsigned char i;unsigned char j; for(i=0;i<8;i++){if((command & 0x01)==0){DQ=0;for(j=35;j>0;j--);DQ=1;}else{DQ=0;for(j=2;j>0;j--);DQ=1;for(j=33;j>0;j--);}command=_cror_(command,1);}} unsigned char readdatafromds18b20(void){unsigned char i;unsigned char j;unsigned char temp; temp=0;for(i=0;i<8;i++){temp=_cror_(temp,1);DQ=0;_nop_();_nop_();DQ=1;for(j=10;j>0;j--);if(DQ==1){temp=temp | 0x80;}else{temp=temp | 0x00;}for(j=200;j>0;j--);}return(temp);} void main(void){TMOD=0x01;TH0=(65536-4000)/256;TL0=(65536-4000)%256;ET0=1;EA=1; while(resetpulse());writecommandtods18b20(0xcc);writecommandtods18b20(0x44);TR0=1;while(1){;}} void t0(void) interrupt 1 using 0{unsigned char x;unsigned int result; TH0=(65536-4000)/256;TL0=(65536-4000)%256;if(displaycount==2){P0=displaycode[displaybuf[displaycount]] | 0x80;}else{P0=displaycode[displaybuf[displaycount]];}P2=displaybit[displaycount];displaycount++;if(displaycount==8){displaycount=0;} timecount++;if(timecount==150){timecount=0;while(resetpulse());writecommandtods18b20(0xcc);writecommandtods18b20(0xbe);readdata[0]=readdatafromds18b20();readdata[1]=readdatafromds18b20();for(x=0;x<8;x++){displaybuf[x]=16;}sflag=0;if((readdata[1] & 0xf8)!=0x00){sflag=1;readdata[1]=~readdata[1];readdata[0]=~readdata[0];result=readdata[0]+1;readdata[0]=result;if(result>255){readdata[1]++;}}readdata[1]=readdata[1]<<4;readdata[1]=readdata[1] & 0x70;x=readdata[0];x=x>>4;x=x & 0x0f;readdata[1]=readdata[1] | x;x=2;result=readdata[1];while(result/10){displaybuf[x]=result%10;result=result/10;x++;}displaybuf[x]=result;if(sflag==1){displaybuf[x+1]=17;}x=readdata[0] & 0x0f;x=x<<1;displaybuf[0]=(dotcode[x])%10;displaybuf[1]=(dotcode[x])/10;while(resetpulse());writecommandtods18b20(0xcc);writecommandtods18b20(0x44);}}
Ⅲ 基於AT89C51單片機和DS18B20溫度感測器、LCD1602液晶顯示的高精度數字溫度計程序,用C語言編程
/***********ds18b20子程序*************************/
/***********ds18b20延遲子函數(晶振12MHz )*******/
#include<reg51.h>
sbit DQ=P1^2;
#define uchar unsigned char
void delay_18B20(unsigned int i)
{
while(i--);
}
/**********ds18b20初始化函數**********************/
void Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ復位
delay_18B20(8); //稍做延時
DQ = 0; //單片機將DQ拉低
delay_18B20(80); //精確延時 大於 480us
DQ = 1; //拉高匯流排
delay_18B20(4);
x=DQ; //稍做延時後 如果x=0則初始化成功 x=1則初始化失敗
delay_18B20(20);
}
/***********ds18b20讀一個位元組**************/
unsigned char ReadOneChar(void)
{
uchar i=0;
uchar dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 給脈沖信號
dat>>=1;
DQ = 1; // 給脈沖信號
if(DQ)
dat|=0x80;
delay_18B20(4);
}
return(dat);
}
/*************ds18b20寫一個位元組****************/
void WriteOneChar(uchar dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay_18B20(5);
DQ = 1;
dat>>=1;
}
}
/**************讀取ds18b20當前溫度************/
ReadTemp(void)
{ float val;
uchar temp_value,value;
unsigned char a=0;
unsigned char b=0;
unsigned char t=0;
Init_DS18B20();
WriteOneChar(0xCC); // 跳過讀序號列號的操作
WriteOneChar(0x44); // 啟動溫度轉換
delay_18B20(100); // this message is wery important
Init_DS18B20();
WriteOneChar(0xCC); //跳過讀序號列號的操作
WriteOneChar(0xBE); //讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度
delay_18B20(100);
a=ReadOneChar(); //讀取溫度值低位
b=ReadOneChar(); //讀取溫度值高位
temp_value=b<<4;
temp_value+=(a&0xf0)>>4;
value=a&0x0f;
val=temp_value+value;
return(val);
}
以上是DS18B20的驅動程序。然後在主程序中直接調用函數就可以了。
以上是在主程序中的調用,你看關於溫度的那個就可以。
#include "reg51.h"
#include "18b20.h"
#define uchar unsigned char
#define uint unsigned int
uchar code table[]="Welcome To" ;//初始化日期和星期
uchar code table1[]="Our System!";//初始化時間
uchar code table2[]="Temperature is:";//初始化時間
//以下三個是定義LCD的引腳
sbit lcden=P2^2;
sbit lcdwrite=P2^1;
sbit lcdrs=P2^0;
char wen;
//延時程序
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)
{
lcdrs=0;
lcden=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
//lcd的寫數據
void write_data(uchar da)
{ lcdrs=1;
lcden=0;
P0=da;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
//初始化
void init()
{
uchar num;
lcdwrite=0;
lcden=0;
write_com(0x38); //16*2顯示,5*7點陣,8位數據
write_com(0x0c);//顯示開,關游標
write_com(0x06); //移動游標
write_com(0x01);//清除LCD的顯示內容
write_com(0x80);
for (num=0;num<10;num++)
{
write_data(table[num]);
delay(5);
}
write_com(0x80+0x40);
for (num=0;num<11;num++)
{
write_data(table1[num]);
delay(5);
}
}
void write_wen(uchar add, char da)
{
uchar shi,ge;
shi=da/10;
ge=da%10;
write_com(0x80+0x40+add);
write_data(0x30+shi);
write_data(0x30+ge);
}
//主函數
void main ()
{
uchar num;
init();
delay(2000);
delay(2000);
delay(2000);
write_com(0x01);//清除LCD的顯示內容
while(1)
{
write_com(0x80);
for (num=0;num<15;num++)
{
write_data(table2[num]);
delay(5);
}
wen = ReadTemp( );
write_wen(2,wen);
}
}
Ⅳ 基於單片機的數字溫度計設計好做么
這種設計相對來說比較好做。
首先選擇用什麼洞此慶系列的單片機。目前常用的有51單片機,AVR單片機,MSP430單片機等等。
接下來選擇用什麼感測器。
採用有溫敏電阻,通過對直流電壓分壓,測量其直流電壓的變化,也就是AD檢測,再納握把電壓值轉換成溫度值;(這種方式要求單片機具有AD檢測功能,否則需要外接AD轉換晶元。)
採用溫度模塊,例如常用的DS18B20,不需要AD檢測,只需要進行I2C讀寫取扒仔得溫度值;
最後確定如何顯示檢測到的數值。
常用的有:
1.數碼管,可以顯示段碼數字或簡單字元。
2.LCD1602液晶屏,可以顯示兩行16*2個英文字母和數字;
3.LCD12864液晶屏,可以顯示四行8*4個漢字。也可以顯示字母及數字,當然也可以顯示自定義圖形。
以上選擇需要合理搭配。
接著就是繪制原理圖和PCB圖、採集元件、焊接,編寫程序,調試。
Ⅳ 求一個51單片機控制的溫度計顯示程序
這個程序完全沒問題的,我做過實驗。希望對你有幫助,,,,
//DS18B20的讀寫程序,數據腳P3.3 //
//溫度感測器18B20匯編程序,採用器件默認的12位轉化 //
//最大轉化時間750微秒,顯示溫度-55到+125度,顯示精度 //
//為0.1度,顯示採用4位LED共陽顯示測溫值 //
//P0口為段碼輸入,P24~P27為位選 //
/***************************************************/
#include "reg51.h"
#include "intrins.h" //_nop_();延時函數用
#define Disdata P0 //段碼輸出口
#define discan P2 //掃描口
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P3^3; //溫度輸入口
sbit DIN=P0^7; //LED小數點控制
uint h;
uchar flag;
//**************溫度小數部分用查表法***********//
uchar code ditab[16]=
{0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
//
uchar code dis_7[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};
//共陽LED段碼表 "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "不亮" "-"
uchar code scan_con[4]={0x7f,0xbf,0xdf,0xef}; //列掃描控制字
uchar data temp_data[2]={0x00,0x00}; //讀出溫度暫放
uchar data display[5]={0x00,0x00,0x00,0x00,0x00}; //顯示單元數據,共4個數據和一個運算暫用
//
//
//
/***********11微秒延時函數**********/
//
void delay(uint t)
{
for(;t>0;t--);
}
//
/***********顯示掃描函數**********/
scan()
{
char k;
for(k=0;k<4;k++) //四位LED掃描控制
{
Disdata=0xff;
Disdata=dis_7[display[k]];
if(k==1){DIN=0;}
discan=scan_con[k];delay(90);
discan=0xff;
}
}
//
//
/***********18B20復位函數**********/
ow_reset(void)
{
char presence=1;
while(presence)
{
while(presence)
{
DQ=1;_nop_();_nop_();
DQ=0; //
delay(50); // 550us
DQ=1; //
delay(6); // 66us
presence=DQ; // presence=0繼續下一步
}
delay(45); //延時500us
presence = ~DQ;
}
DQ=1;
}
//
//
/**********18B20寫命令函數*********/
//向 1-WIRE 匯流排上寫一個位元組
void write_byte(uchar val)
{
uchar i;
for (i=8; i>0; i--) //
{
DQ=1;_nop_();_nop_();
DQ = 0;_nop_();_nop_();_nop_();_nop_();_nop_();//5us
DQ = val&0x01; //最低位移出
delay(6); //66us
val=val/2; //右移一位
}
DQ = 1;
delay(1);
}
//
/*********18B20讀1個位元組函數********/
//從匯流排上讀取一個位元組
uchar read_byte(void)
{
uchar i;
uchar value = 0;
for (i=8;i>0;i--)
{
DQ=1;_nop_();_nop_();
value>>=1;
DQ = 0; //
_nop_();_nop_();_nop_();_nop_(); //4us
DQ = 1;_nop_();_nop_();_nop_();_nop_(); //4us
if(DQ)value|=0x80;
delay(6); //66us
}
DQ=1;
return(value);
}
//
/***********讀出溫度函數**********/
//
read_temp()
{
ow_reset(); //匯流排復位
write_byte(0xCC); // 發Skip ROM命令
write_byte(0xBE); // 發讀命令
temp_data[0]=read_byte(); //溫度低8位
temp_data[1]=read_byte(); //溫度高8位
ow_reset();
write_byte(0xCC); // Skip ROM
write_byte(0x44); // 發轉換命令
}
//
/***********溫度數據處理函數**********/
void work_temp()
{
uchar n=0;
uchar doth,dotl;
uchar flag3=1,flag2=1; //數字顯示修正標記
if((temp_data[1]&0xf8)!=0x00)
{
temp_data[1]=~(temp_data[1]);
temp_data[0]=~(temp_data[0])+1;
n=1;
flag=1;
}//負溫度求補碼
if(temp_data[0]>255)
{
temp_data[1]++;
}
display[4]=temp_data[0]&0x0f;
display[0]=ditab[display[4]];
doth=display[0]/10;
dotl=display[0]%10;
display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x07)<<4);
display[3]=display[4]/100;
display[2]=display[4]/10%10;
display[1]=display[4]%10;
if(!display[3])
{
display[3]=0x0a;
flag3=0;
if(!display[2])
{
display[2]=0x0a;
flag2=0;
}
}//最高位為0時都不顯示
if(n)
{
display[3]=0x0b;//負溫度時最高位顯示"-"
flag3=0;
}
}
//
//
/**************主函數****************/
main()
{
Disdata=0xff; //初始化埠
discan=0xff;
for(h=0;h<4;h++){display[h]=8;}//開機顯示8888
ow_reset(); // 開機先轉換一次
write_byte(0xCC); // Skip ROM
write_byte(0x44); // 發轉換命令
for(h=0;h<500;h++)
{scan();} //開機顯示"8888"2秒
while(1)
{
read_temp(); //讀出18B20溫度數據
work_temp(); //處理溫度數據
scan(); //顯示溫度值2秒
}
}
//
//*********************結束**************************//