當前位置:編程學習大全網 - 編程語言 - 單片機 液晶顯示溫度 程序

單片機 液晶顯示溫度 程序

DS18B20溫度檢測及其液晶顯示

#include<reg51.h> //包含單片機寄存器的頭文件

#include<intrins.h> //包含_nop_()函數定義的頭文件

unsigned char code digit[10]={"0123456789"}; //定義字符數組顯示數字

unsigned char code Str[]={"Test by DS18B20"}; //說明顯示的是溫度

unsigned char code Error[]={"Error!Check!"}; //說明沒有檢測到DS18B20

unsigned char code Temp[]={"Temp:"}; //說明顯示的是溫度

unsigned char code Cent[]={"Cent"}; //溫度單位

/*******************************************************************************

以下是對液晶模塊的操作程序

*******************************************************************************/

sbit RS=P2^0; //寄存器選擇位,將RS位定義為P2.0引腳

sbit RW=P2^1; //讀寫選擇位,將RW位定義為P2.1引腳

sbit E=P2^2; //使能信號位,將E位定義為P2.2引腳

sbit BF=P0^7; //忙碌標誌位,,將BF位定義為P0.7引腳

/*****************************************************

函數功能:延時1ms

(3j+2)*i=(3×33+2)×10=1010(微秒),可以認為是1毫秒

***************************************************/

void delay1ms()

{

unsigned char i,j;

for(i=0;i<10;i++)

for(j=0;j<33;j++)

;

}

/*****************************************************

函數功能:延時若幹毫秒

入口參數:n

***************************************************/

void delaynms(unsigned char n)

{

unsigned char i;

for(i=0;i<n;i++)

delay1ms();

}

/*****************************************************

函數功能:判斷液晶模塊的忙碌狀態

返回值:result。result=1,忙碌;result=0,不忙

***************************************************/

bit BusyTest(void)

{

bit result;

RS=0; //根據規定,RS為低電平,RW為高電平時,可以讀狀態

RW=1;

E=1; //E=1,才允許讀寫

_nop_(); //空操作

_nop_();

_nop_();

_nop_(); //空操作四個機器周期,給硬件反應時間

result=BF; //將忙碌標誌電平賦給result

E=0; //將E恢復低電平

return result;

}

/*****************************************************

函數功能:將模式設置指令或顯示地址寫入液晶模塊

入口參數:dictate

***************************************************/

void WriteInstruction (unsigned char dictate)

{

while(BusyTest()==1); //如果忙就等待

RS=0; //根據規定,RS和R/W同時為低電平時,可以寫入指令

RW=0;

E=0; //E置低電平(根據表8-6,寫指令時,E為高脈沖,

// 就是讓E從0到1發生正跳變,所以應先置"0"

_nop_();

_nop_(); //空操作兩個機器周期,給硬件反應時間

P0=dictate; //將數據送入P0口,即寫入指令或地址

_nop_();

_nop_();

_nop_();

_nop_(); //空操作四個機器周期,給硬件反應時間

E=1; //E置高電平

_nop_();

_nop_();

_nop_();

_nop_(); //空操作四個機器周期,給硬件反應時間

E=0; //當E由高電平跳變成低電平時,液晶模塊開始執行命令

}

/*****************************************************

函數功能:指定字符顯示的實際地址

入口參數:x

***************************************************/

void WriteAddress(unsigned char x)

{

WriteInstruction(x|0x80); //顯示位置的確定方法規定為"80H+地址碼x"

}

/*****************************************************

函數功能:將數據(字符的標準ASCII碼)寫入液晶模塊

入口參數:y(為字符常量)

***************************************************/

void WriteData(unsigned char y)

{

while(BusyTest()==1);

RS=1; //RS為高電平,RW為低電平時,可以寫入數據

RW=0;

E=0; //E置低電平(根據表8-6,寫指令時,E為高脈沖,

// 就是讓E從0到1發生正跳變,所以應先置"0"

P0=y; //將數據送入P0口,即將數據寫入液晶模塊

_nop_();

_nop_();

_nop_();

_nop_(); //空操作四個機器周期,給硬件反應時間

E=1; //E置高電平

_nop_();

_nop_();

_nop_();

_nop_(); //空操作四個機器周期,給硬件反應時間

E=0; //當E由高電平跳變成低電平時,液晶模塊開始執行命令

}

/*****************************************************

函數功能:對LCD的顯示模式進行初始化設置

***************************************************/

void LcdInitiate(void)

{

delaynms(15); //延時15ms,首次寫指令時應給LCD壹段較長的反應時間

WriteInstruction(0x38); //顯示模式設置:16×2顯示,5×7點陣,8位數據接口

delaynms(5); //延時5ms ,給硬件壹點反應時間

WriteInstruction(0x38);

delaynms(5); //延時5ms ,給硬件壹點反應時間

WriteInstruction(0x38); //連續三次,確保初始化成功

delaynms(5); //延時5ms ,給硬件壹點反應時間

WriteInstruction(0x0c); //顯示模式設置:顯示開,無光標,光標不閃爍

delaynms(5); //延時5ms ,給硬件壹點反應時間

WriteInstruction(0x06); //顯示模式設置:光標右移,字符不移

delaynms(5); //延時5ms ,給硬件壹點反應時間

WriteInstruction(0x01); //清屏幕指令,將以前的顯示內容清除

delaynms(5); //延時5ms ,給硬件壹點反應時間

}

/************************************************************************

以下是DS18B20的操作程序

************************************************************************/

sbit DQ=P3^3;

unsigned char time; //設置全局變量,專門用於嚴格延時

/*****************************************************

函數功能:將DS18B20傳感器初始化,讀取應答信號

出口參數:flag

***************************************************/

bit Init_DS18B20(void)

{

bit flag; //儲存DS18B20是否存在的標誌,flag=0,表示存在;flag=1,表示不存在

DQ = 1; //先將數據線拉高

for(time=0;time<2;time++) //略微延時約6微秒

DQ = 0; //再將數據線從高拉低,要求保持480~960us

for(time=0;time<200;time++) //略微延時約600微秒

; //以向DS18B20發出壹持續480~960us的低電平復位脈沖

DQ = 1; //釋放數據線(將數據線拉高)

for(time=0;time<10;time++)

; //延時約30us(釋放總線後需等待15~60us讓DS18B20輸出存在脈沖)

flag=DQ; //讓單片機檢測是否輸出了存在脈沖(DQ=0表示存在)

for(time=0;time<200;time++) //延時足夠長時間,等待存在脈沖輸出完畢

return (flag); //返回檢測成功標誌

}

/*****************************************************

函數功能:從DS18B20讀取壹個字節數據

出口參數:dat

***************************************************/

unsigned char ReadOneChar(void)

{

unsigned char i=0;

unsigned char dat; //儲存讀出的壹個字節數據

for (i=0;i<8;i++)

{

DQ =1; // 先將數據線拉高

_nop_(); //等待壹個機器周期

DQ = 0; //單片機從DS18B20讀書據時,將數據線從高拉低即啟動讀時序

dat>>=1;

_nop_(); //等待壹個機器周期

DQ = 1; //將數據線"人為"拉高,為單片機檢測DS18B20的輸出電平作準備

for(time=0;time<2;time++)

; //延時約6us,使主機在15us內采樣

if(DQ==1)

dat|=0x80; //如果讀到的數據是1,則將1存入dat

else

dat|=0x00;//如果讀到的數據是0,則將0存入dat

//將單片機檢測到的電平信號DQ存入r[i]

for(time=0;time<8;time++)

; //延時3us,兩個讀時序之間必須有大於1us的恢復期

}

return(dat); //返回讀出的十進制數據

}

/*****************************************************

函數功能:向DS18B20寫入壹個字節數據

入口參數:dat

***************************************************/

WriteOneChar(unsigned char dat)

{

unsigned char i=0;

for (i=0; i<8; i++)

{

DQ =1; // 先將數據線拉高

_nop_(); //等待壹個機器周期

DQ=0; //將數據線從高拉低時即啟動寫時序

DQ=dat&0x01; //利用與運算取出要寫的某位二進制數據,

//並將其送到數據線上等待DS18B20采樣

for(time=0;time<10;time++)

;//延時約30us,DS18B20在拉低後的約15~60us期間從數據線上采樣

DQ=1; //釋放數據線

for(time=0;time<1;time++)

;//延時3us,兩個寫時序間至少需要1us的恢復期

dat>>=1; //將dat中的各二進制位數據右移1位

}

for(time=0;time<4;time++)

; //稍作延時,給硬件壹點反應時間

}

/******************************************************************************

以下是與溫度有關的顯示設置

******************************************************************************/

/*****************************************************

函數功能:顯示沒有檢測到DS18B20

***************************************************/

void display_error(void)

{

unsigned char i;

WriteAddress(0x00); //寫顯示地址,將在第1行第1列開始顯示

i = 0; //從第壹個字符開始顯示

while(Error[i] != '\0') //只要沒有寫到結束標誌,就繼續寫

{

WriteData(Error[i]); //將字符常量寫入LCD

i++; //指向下壹個字符

delaynms(100); //延時100ms較長時間,以看清關於顯示的說明

}

while(1) //進入死循環,等待查明原因

}

/*****************************************************

函數功能:顯示說明信息

***************************************************/

void display_explain(void)

{

unsigned char i;

WriteAddress(0x00); //寫顯示地址,將在第1行第1列開始顯示

i = 0; //從第壹個字符開始顯示

while(Str[i] != '\0') //只要沒有寫到結束標誌,就繼續寫

{

WriteData(Str[i]); //將字符常量寫入LCD

i++; //指向下壹個字符

delaynms(100); //延時100ms較長時間,以看清關於顯示的說明

}

}

/*****************************************************

函數功能:顯示溫度符號

***************************************************/

void display_symbol(void)

{

unsigned char i;

WriteAddress(0x40); //寫顯示地址,將在第2行第1列開始顯示

i = 0; //從第壹個字符開始顯示

while(Temp[i] != '\0') //只要沒有寫到結束標誌,就繼續寫

{

WriteData(Temp[i]); //將字符常量寫入LCD

i++; //指向下壹個字符

delaynms(50); //延時1ms給硬件壹點反應時間

}

}

/*****************************************************

函數功能:顯示溫度的小數點

***************************************************/

void display_dot(void)

{

WriteAddress(0x49); //寫顯示地址,將在第2行第10列開始顯示

WriteData('.'); //將小數點的字符常量寫入LCD

delaynms(50); //延時1ms給硬件壹點反應時間

}

/*****************************************************

函數功能:顯示溫度的單位(Cent)

***************************************************/

void display_cent(void)

{

unsigned char i;

WriteAddress(0x4c); //寫顯示地址,將在第2行第13列開始顯示

i = 0; //從第壹個字符開始顯示

while(Cent[i] != '\0') //只要沒有寫到結束標誌,就繼續寫

{

WriteData(Cent[i]); //將字符常量寫入LCD

i++; //指向下壹個字符

delaynms(50); //延時1ms給硬件壹點反應時間

}

}

/*****************************************************

函數功能:顯示溫度的整數部分

入口參數:x

***************************************************/

void display_temp1(unsigned char x)

{

unsigned char j,k,l; //j,k,l分別儲存溫度的百位、十位和個位

j=x/100; //取百位

k=(x%100)/10; //取十位

l=x%10; //取個位

WriteAddress(0x46); //寫顯示地址,將在第2行第7列開始顯示

WriteData(digit[j]); //將百位數字的字符常量寫入LCD

WriteData(digit[k]); //將十位數字的字符常量寫入LCD

WriteData(digit[l]); //將個位數字的字符常量寫入LCD

delaynms(50); //延時1ms給硬件壹點反應時間

}

/*****************************************************

函數功能:顯示溫度的小數數部分

入口參數:x

***************************************************/

void display_temp2(unsigned char x)

{

WriteAddress(0x4a); //寫顯示地址,將在第2行第11列開始顯示

WriteData(digit[x]); //將小數部分的第壹位數字字符常量寫入LCD

delaynms(50); //延時1ms給硬件壹點反應時間

}

/*****************************************************

函數功能:做好讀溫度的準備

***************************************************/

void ReadyReadTemp(void)

{

Init_DS18B20(); //將DS18B20初始化

WriteOneChar(0xCC); // 跳過讀序號列號的操作

WriteOneChar(0x44); // 啟動溫度轉換

for(time=0;time<100;time++)

; //溫度轉換需要壹點時間

Init_DS18B20(); //將DS18B20初始化

WriteOneChar(0xCC); //跳過讀序號列號的操作

WriteOneChar(0xBE); //讀取溫度寄存器,前兩個分別是溫度的低位和高位

}

/*****************************************************

函數功能:主函數

***************************************************/

void main(void)

{

unsigned char TL; //儲存暫存器的溫度低位

unsigned char TH; //儲存暫存器的溫度高位

unsigned char TN; //儲存溫度的整數部分

unsigned char TD; //儲存溫度的小數部分

LcdInitiate(); //將液晶初始化

delaynms(5); //延時5ms給硬件壹點反應時間

if(Init_DS18B20()==1)

display_error();

display_explain();

display_symbol(); //顯示溫度說明

display_dot(); //顯示溫度的小數點

display_cent(); //顯示溫度的單位

while(1) //不斷檢測並顯示溫度

{

ReadyReadTemp(); //讀溫度準備

TL=ReadOneChar(); //先讀的是溫度值低位

TH=ReadOneChar(); //接著讀的是溫度值高位

TN=TH*16+TL/16; //實際溫度值=(TH*256+TL)/16,即:TH*16+TL/16

//這樣得出的是溫度的整數部分,小數部分被丟棄了

TD=(TL%16)*10/16; //計算溫度的小數部分,將余數乘以10再除以16取整,

//這樣得到的是溫度小數部分的第壹位數字(保留1位小數)

display_temp1(TN); //顯示溫度的整數部分

display_temp2(TD); //顯示溫度的小數部分

delaynms(10);

}

}

記得改改哈!!

  • 上一篇:羅技方向盤怎麽校正?最好的答案是100分!
  • 下一篇:怎麽搭建linux centos服務器
  • copyright 2024編程學習大全網