標(biāo)題: 詳細(xì)的程序分析:編程實現(xiàn)單片機(jī)ds18b20溫度測量及顯示系統(tǒng) [打印本頁]
作者: 15856431200 時間: 2018-3-27 23:09
標(biāo)題: 詳細(xì)的程序分析:編程實現(xiàn)單片機(jī)ds18b20溫度測量及顯示系統(tǒng)
編程實現(xiàn)基于單片機(jī)的溫度測量及顯示系統(tǒng)
- 利用開發(fā)板上的ds18b20傳感器測量當(dāng)前溫度,利用數(shù)碼管輸出當(dāng)前溫度值。
實現(xiàn)結(jié)果:
測試結(jié)果顯示當(dāng)前攝氏溫度25.3度。
實現(xiàn)原理:
(1)獨(dú)立數(shù)碼管
數(shù)碼管分為共陽極和共陰極數(shù)碼管,
通過控制數(shù)碼管中的8個二極管,來顯示數(shù)字。
(2)多位共陰數(shù)碼管和共陽數(shù)碼管
本項目使用的是6位共陰數(shù)碼管。
數(shù)碼管控制主要通過段鎖存和位鎖存控制顯示要顯示的數(shù)字如溫度。段鎖存是指6位共陰極數(shù)碼管段輸出端連接鎖存器74HC573的輸出端,鎖存器的輸入端連接單片機(jī)接口P0。位鎖存是指6位數(shù)碼管位置輸出端連接鎖存器74HC573的輸出端,鎖存器的輸入端連接單片機(jī)接口P0。段鎖存器片選端接單片機(jī)接口P2.6,位鎖存器片選端接單片機(jī)接口P2.7。
連接圖如下:
程序分析:溫度傳感器DS18B20接單片機(jī)P2.2,段鎖存接P2.6,位鎖存接P2.7,unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
顯示段碼值0~9,Unsigned char code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
分別對應(yīng)相應(yīng)的數(shù)碼管點亮,即位碼。
溫度傳感器的程序有測溫的程序,測得的溫度通過數(shù)碼管顯示出來。其中使用了延時和中斷子程序。
- 利用按鍵實現(xiàn)攝氏溫度和華氏溫度的轉(zhuǎn)換,并顯示。
實現(xiàn)結(jié)果:
按下S2,顯示攝氏溫度如下
按下S2,顯示華氏溫度如下
實現(xiàn)原理:
在之前的溫度顯示模塊加入按鍵功能程序,利用兩種溫度轉(zhuǎn)換公式華氏溫度=(攝氏溫度*9/5)+32實現(xiàn)轉(zhuǎn)換。
相關(guān)程序如下:- void display(uint temp,uint hstemp) //顯示程序
- {
-
- if(s2==0)
- {
-
- ser=temp/10;
- SBUF=ser;
- A1=temp/100;
- A2t=temp%100;
- A2=A2t/10;
- A3=A2t%10;
- dula=0;
- P0=table[A1]; //顯示百位
- dula=1;
- dula=0;
-
- wela=0;
- P0=0x7e;
- wela=1;
- wela=0;
- delay(1);
-
- dula=0;
- P0=table1[A2]; //顯示十位
- dula=1;
- dula=0;
-
- wela=0;
- P0=0x7d;
- wela=1;
- wela=0;
- delay(1);
-
- P0=table[A3]; //顯示個位
- dula=1;
- dula=0;
-
- P0=0x7b;
- wela=1;
- wela=0;
- delay(1);
- }
- if(s3==0)
- {
-
- ser1=hstemp/10;
- SBUF=ser1;
- A11=hstemp/100;
- A21t=hstemp%100;
- A21=A21t/10;
- A31=A21t%10;
- dula=0;
- P0=table[A11]; //顯示百位
- dula=1;
- dula=0;
-
- wela=0;
- P0=0x7e;
- wela=1;
- wela=0;
- delay(1);
-
- dula=0;
- P0=table1[A21]; //顯示十位
- dula=1;
- dula=0;
-
- wela=0;
- P0=0x7d;
- wela=1;
- wela=0;
- delay(1);
-
- P0=table[A31]; //顯示個位
- dula=1;
- dula=0;
-
- P0=0x7b;
- wela=1;
- wela=0;
- delay(1);
- }
- }
復(fù)制代碼
程序分析:s2,s3代表按鍵分別接在單片機(jī)P3.4,p3.5上,當(dāng)按鍵按下時單片機(jī)相應(yīng)接口顯示低電平,松開顯示高電平。當(dāng)檢測到S2按下時,顯示攝氏溫度。當(dāng)檢測到S3按下時,顯示華氏溫度。主程序如下:
if(s2==0)
{
SendByte(A1*10+A2);
SendStr(".");
SendByte(A3);
}
if(s3==0)
{
SendByte(A11*10+A21);
SendStr(".");
SendByte(A3);
}
- 利用串口將當(dāng)前溫度值發(fā)送至電腦,電腦端利用串口助手進(jìn)行接收和顯示。
實現(xiàn)原理:
連接好串口或者usb轉(zhuǎn)串口至電腦,下載該程序,打開電源, 打開串口調(diào)試程序,將波特率設(shè)置為9600,無奇偶校驗,晶振11.0592MHz,發(fā)送和接收使用的格式相同。
串口通訊程序包括串口初始化,輸出字節(jié)函數(shù),輸出字符串函數(shù),主函數(shù)。溫度傳感器測得的溫度數(shù)值通過串口通訊程序輸出顯示在電腦上。
實現(xiàn)結(jié)果:
當(dāng)按下S2按鍵,電腦顯示如下:
發(fā)送和接收都是16進(jìn)制,1B=1*16+11*1=27,2E代表小數(shù)點,01=1,所以顯示溫度27.2攝氏度。
當(dāng)按下S3按鍵,電腦顯示如下:

發(fā)送和接收都是16進(jìn)制,51=5*16+1*1=81,2E代表小數(shù)點,03=3,所以顯示溫度81.3華氏。
單片機(jī)源程序如下:
- //安裝目錄下的EXE文件打開后可在電腦上顯示當(dāng)前溫度值
- #include <reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit DS=P2^2; //define interface
- uint temp; // variable of temperature
- uchar flag1; // sign of the result positive or negative
- sbit dula=P2^6;
- sbit wela=P2^7;
- sbit s2=P3^4;
- sbit s3=P3^5;
- uchar A1,A2,A2t,A3,ser,A11,A21,A21t,A31,ser1;
- unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
- 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
- unsigned char code table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,
- 0x87,0xff,0xef};
-
-
- void SendStr(unsigned char *s);
- /*------------------------------------------------
- 串口初始化
- ------------------------------------------------*/
- void InitUART (void)
- {
-
- SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能接收
- TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit 重裝
- TH1 = 0xFD; // TH1: 重裝值 9600 波特率 晶振 11.0592MHz
- TR1 = 1; // TR1: timer 1 打開
- EA = 1; //打開總中斷
- //ES = 1; //打開串口中斷
- }
- void delay(uint count) //delay
- {
- uint i;
- while(count)
- {
- i=200;
- while(i>0)
- i--;
- count--;
- }
- }
- void DelayUs2x(unsigned char t)
- {
- while(--t);
- }
- /*------------------------------------------------
- mS延時函數(shù),含有輸入?yún)?shù) unsigned char t,無返回值
- unsigned char 是定義無符號字符變量,其值的范圍是
- 0~255 這里使用晶振12M,精確延時請使用匯編
- ------------------------------------------------*/
- void DelayMs(unsigned char t)
- {
-
- while(t--)
- {
- //大致延時1mS
- DelayUs2x(245);
- DelayUs2x(245);
- }
- }
- ///////功能:串口初始化,波特率9600,方式1///////
- void Init_Com(void)
- {
- TMOD = 0x20;
- PCON = 0x00;
- SCON = 0x50;
- TH1 = 0xFd;
- TL1 = 0xFd;
- TR1 = 1;
- }
-
- void dsreset(void) //send reset and initialization command
- {
- uint i;
- DS=0;
- i=103;
- while(i>0)i--;
- DS=1;
- i=4;
- while(i>0)i--;
- }
-
- bit tmpreadbit(void) //read a bit
- {
- uint i;
- bit dat;
- DS=0;i++; //i++ for delay
- DS=1;i++;i++;
- dat=DS;
- i=8;while(i>0)i--;
- return (dat);
- }
-
- uchar tmpread(void) //read a byte date
- {
- uchar i,j,dat;
- dat=0;
- for(i=1;i<=8;i++)
- {
- j=tmpreadbit();
- dat=(j<<7)|(dat>>1); //讀出的數(shù)據(jù)最低位在最前面,這樣剛好一個字節(jié)在DAT里
- }
- return(dat);
- }
-
- void tmpwritebyte(uchar dat) //write a byte to ds18b20
- {
- uint i;
- uchar j;
- bit testb;
- for(j=1;j<=8;j++)
- {
- testb=dat&0x01;
- dat=dat>>1;
- if(testb) //write 1
- {
- DS=0;
- i++;i++;
- DS=1;
- i=8;while(i>0)i--;
- }
- else
- {
- DS=0; //write 0
- i=8;while(i>0)i--;
- DS=1;
- i++;i++;
- }
-
- }
- }
-
- void tmpchange(void) //DS18B20 begin change
- {
- dsreset();
- delay(1);
- tmpwritebyte(0xcc); // address all drivers on bus
- tmpwritebyte(0x44); // initiates a single temperature conversion
- }
-
- uint tmp() //get the temperature
- {
- float tt;
- uchar a,b;
- dsreset();
- delay(1);
- tmpwritebyte(0xcc);
- tmpwritebyte(0xbe);
- a=tmpread();
- b=tmpread();
- temp=b;
- temp<<=8; //two byte compose a int variable
- temp=temp|a;
- tt=temp*0.0625;
- temp=tt*10+0.5;
- return temp;
- }
-
- void readrom() //read the serial
- {
- uchar sn1,sn2;
- dsreset();
- delay(1);
- tmpwritebyte(0x33);
- sn1=tmpread();
- sn2=tmpread();
- }
-
-
- void delay10ms() //delay
- {
- uchar a,b;
- for(a=10;a>0;a--)
- for(b=60;b>0;b--);
- }
-
- void display(uint temp,uint hstemp) //顯示程序
- {
-
- if(s2==0)
- {
-
- ser=temp/10;
- SBUF=ser;
- A1=temp/100;
- A2t=temp%100;
- A2=A2t/10;
- A3=A2t%10;
- dula=0;
- P0=table[A1]; //顯示百位
- dula=1;
- dula=0;
-
- wela=0;
- P0=0x7e;
- wela=1;
- wela=0;
- delay(1);
-
- dula=0;
- P0=table1[A2]; //顯示十位
- dula=1;
- dula=0;
-
- wela=0;
- P0=0x7d;
- wela=1;
- wela=0;
- delay(1);
-
- P0=table[A3]; //顯示個位
- dula=1;
- dula=0;
-
- P0=0x7b;
- wela=1;
- wela=0;
- delay(1);
- }
- if(s3==0)
- {
-
- ser1=hstemp/10;
- SBUF=ser1;
- A11=hstemp/100;
- A21t=hstemp%100;
- A21=A21t/10;
- A31=A21t%10;
- dula=0;
- P0=table[A11]; //顯示百位
- dula=1;
- dula=0;
-
- wela=0;
- P0=0x7e;
- wela=1;
- wela=0;
- delay(1);
-
- dula=0;
- P0=table1[A21]; //顯示十位
- dula=1;
- dula=0;
-
- wela=0;
- P0=0x7d;
- wela=1;
- wela=0;
- delay(1);
-
- P0=table[A31]; //顯示個位
- dula=1;
- dula=0;
-
- P0=0x7b;
- wela=1;
- wela=0;
- delay(1);
- }
- }
-
- void SendByte(unsigned char dat)
- {
- SBUF = dat;
- while(!TI);
- TI = 0;
- }
- void main()
- {
- uchar a;
- InitUART();
- Init_Com();
- do
- {
- tmpchange();
-
- for(a=10;a>0;a--)
- { display(tmp(),(tmp()*9/5)+320);
- // delay(200);
- }
- if(s2==0)
- {
- SendByte(A1*10+A2);
- SendStr(".");
- SendByte(A3);
-
- }
- if(s3==0)
- {
- SendByte(A11*10+A21);
- SendStr(".");
- SendByte(A3);
- }
-
- DelayMs(240);//延時循環(huán)發(fā)送
- DelayMs(240);
- } while(1);
- }
-
- /*------------------------------------------------
- 發(fā)送一個字符串
- ------------------------------------------------*/
- void SendStr(unsigned char *s)
- {
- while(*s!='\0')// \0 表示字符串結(jié)束標(biāo)志,
- //通過檢測是否字符串末尾
- {
- SendByte(*s);
- s++;
- }
- }
-
- 液晶顯示溫度程序
- #include <reg52.H>
- #include <intrins.H>
- #include <math.H>
-
- #define uchar unsigned char
- #define uint unsigned int
- sbit dula = P2^6;
- sbit wela = P2^7;
-
- sbit RS = P3^5;
- sbit LCDEN = P3^4;
-
- void delayUs()
- {
- _nop_();
- }
-
- void delayMs(uint a)
- {
- uint i, j;
- for(i = a; i > 0; i--)
- for(j = 100; j > 0; j--);
- }
-
-
- void writeComm(uchar comm)
- {
- RS = 0;
- P0 = comm;
- LCDEN = 1;
- delayUs();
- LCDEN = 0;
- delayMs(1);
- }
-
- //寫數(shù)據(jù):RS=1, RW=0;
- void writeData(uchar dat)
- {
- RS = 1;
- P0 = dat;
- LCDEN = 1;
- delayUs();
- LCDEN = 0;
- delayMs(1);
- }
-
-
- void init()
- {
-
- dula = wela = 0;
- writeComm(0x38);
- writeComm(0x0c);
- writeComm(0x06);
- writeComm(0x01);
- }
-
- void writeString(uchar * str, uchar length)
- {
- uchar i;
- for(i = 0; i < length; i++)
- {
- writeData(str[i]);
- }
- }
-
- /**//*****************************DS18B20*******************************/
- sbit ds = P2^2;
- void dsInit()
- {
-
- unsigned int i;
- ds = 0;
- i = 100;
- while(i>0) i--;
- ds = 1;
- i = 4;
- while(i>0) i--;
- }
-
- void dsWait()
- {
- unsigned int i;
- while(ds);
- while(~ds);
- i = 4;
- while(i > 0) i--;
- }
-
-
- bit readBit()
- {
- unsigned int i;
- bit b;
- ds = 0;
- i++;
- ds = 1;
- i++; i++;
- b = ds;
- i = 8;
- while(i>0) i--;
- return b;
- }
-
- unsigned char readByte()
- {
- unsigned int i;
- unsigned char j, dat;
- dat = 0;
- for(i=0; i<8; i++)
- {
- j = readBit();
-
- dat = (j << 7) | (dat >> 1);
- }
- return dat;
- }
-
-
- void writeByte(unsigned char dat)
- {
- unsigned int i;
- unsigned char j;
- bit b;
- for(j = 0; j < 8; j++)
- {
- b = dat & 0x01;
- dat >>= 1;
-
- if(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++;
- }
- }
- }
-
-
- void sendChangeCmd()
- {
- dsInit();
- dsWait();
- delayMs(1);
- writeByte(0xcc);
- writeByte(0x44);
- }
-
- void sendReadCmd()
- {
- dsInit();
- dsWait();
- delayMs(1);
- writeByte(0xcc);
- writeByte(0xbe);
- }
-
-
- int getTmpValue()
- {
- unsigned int tmpvalue;
- int value;
- float t;
- unsigned char low, high;
- sendReadCmd();
-
- low = readByte();
- high = readByte();
-
- tmpvalue = high;
- tmpvalue <<= 8;
- tmpvalue |= low;
- value = tmpvalue;
-
- \
- t = value * 0.0625;
- \
- value = t * 100 + (value > 0 ? 0.5 : -0.5); //大于0加0.5, 小于0減0.5
- return value;
- }
-
- void display(int v)
- {
- unsigned char count;
- unsigned char datas[] = {0, 0, 0, 0, 0};
- unsigned int tmp = abs(v);
- datas[0] = tmp / 10000;
- datas[1] = tmp % 10000 / 1000;
- datas[2] = tmp % 1000 / 100;
- datas[3] = tmp % 100 / 10;
- datas[4] = tmp % 10;
- writeComm(0xc0+3);
- if(v < 0)
- {
- writeString("- ", 2);
- }
- else
- {
- writeString("+ ", 2);
- }
- if(datas[0] != 0)
- {
- writeData('0'+datas[0]);
- }
- for(count = 1; count != 5; count++)
- {
- writeData('0'+datas[count]);
- if(count == 2)
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
單片機(jī)的溫度測量及顯示系統(tǒng).docx
(1.66 MB, 下載次數(shù): 70)
2018-3-27 23:08 上傳
點擊文件名下載附件
單片機(jī)
下載積分: 黑幣 -5
作者: why___1997 時間: 2018-6-26 23:14
非常感謝分享
作者: lorraine 時間: 2018-6-27 08:49
GANXIE
作者: 倔強(qiáng)lan 時間: 2018-12-2 16:02
謝謝樓主的分享,現(xiàn)在我已經(jīng)大致明白了單片機(jī)內(nèi)部這個部件的構(gòu)造了,但可能我們的板子不一樣,還有你的一些變量名我看不懂,我還是要好好學(xué)習(xí)才行。
作者: Hopeful 時間: 2020-1-16 19:54
感謝分享
作者: gao687 時間: 2022-6-24 11:39
可以使用,代碼詳細(xì)
| 歡迎光臨 (http://www.raoushi.com/bbs/) |
Powered by Discuz! X3.1 |