欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
單片機LCD1602溫度計實驗 Proteus仿真加源程序
[打印本頁]
作者:
51黑電子happy
時間:
2017-3-30 01:35
標題:
單片機LCD1602溫度計實驗 Proteus仿真加源程序
51單片機LCD1602液晶顯示的溫度計的仿真原理圖(proteus工程文件可到本帖附件下載):
0.png
(21.67 KB, 下載次數: 122)
下載附件
2017-3-30 01:32 上傳
單片機源程序:
//--------------------------------------------------------------------------------------------
//程序名: LCD_TEMP09-1.c
//程序功能:LCD溫度計
//--------------------------------------------------------------------------------------------
#include <reg51.h>
#include<intrins.h> //包含_nop_()函數定義的頭文件
sbit RS=P2^5; // 引腳定義
sbit RW=P2^6;
sbit EN=P2^7;
sbit busy=P0^7; // "忙"標志位
#define LCD P0 //命令或數據線
sbit DQ=P2^0;
//代碼表
unsigned char code TAB1[]={ 0x0c,0x12,0x12,0x0c,
0x00,0x00,0x00,0x00,
};
//字符表
unsigned char code TAB2[]={"DS18B20 OK"};
unsigned char code Error[]={"Error!Check!"}; //說明沒有檢測到DS18B20
unsigned char code digit[10]={"0123456789"}; //定義字符數組顯示數字
unsigned char code TEMP[]={"TEMP:"}; //說明顯示的是溫度
unsigned char fuhao;
//------------------------------------ 延時函數 -------------------------------------------
void delay(unsigned int t) //延時若干微秒
{
while(t--);
}
//---------------------------------- 判斷液晶顯示器是否忙函數 ----------------------------------
CHECK_BF() //判斷是否忙碌
{
do
{
LCD=0xff;
RS=0; // RS=0,選擇指令寄存器
RW=1; // RW=1,選擇讀模式
EN=0; // 執行顯示命令
EN=1; // 允許讀/寫
}
while(busy); //busy為高電平表示忙,循環等待
}
//-------------------------------------- 寫命令函數 -----------------------------------
WR_COMM() //寫命令
{
RS=0; // RS=0,選擇指令寄存器
RW=0; // RW=0,選擇寫模式
EN=0; // 執行顯示命令
CHECK_BF(); // 等待
EN=1; // E=1,允許讀/寫LCD
}
//-------------------------------------- 寫數據函數 -------------------------------------
WR_DATA() //寫數據
{
RS=1; // RS=1,選擇數據寄存器
RW=0; //準備寫入數據
EN=0; //執行顯示命令
CHECK_BF(); //判斷液晶模塊是否忙
EN=1; // E=1,允許讀/寫LCD
}
//--------------------------------------- 初始化函數 ----------------------------------
INIT_LCD() //初始化
{
unsigned char i=200;
{
while(--i);
LCD=0x01; //清屏并光標復位
WR_COMM(); //寫入命令
LCD=0x38; //設置顯示模式:8位2行5x7點陣
WR_COMM();
LCD=0x0c; //開顯示屏
WR_COMM();
LCD=0x06; //文字不動,光標自動右移
WR_COMM(); //寫入命令
}
}
//-------------------------------- 顯示溫度標記字符C函數 ----------------------------
TEMP_BJ() //顯示字符C
{
LCD=0xce; //寫入顯示起始地址
WR_COMM(); //寫入命令
LCD=('C' );
WR_DATA(); //送出
}
//----------------------------------- 自定義溫度標志符函數 --------------------------------
STORE_DATA()
{
unsigned char i;
LCD=0x40; // 指定CG RAM起始地址
WR_COMM(); //寫入命令
for(i=0;i<9;i++)
{
LCD=TAB1[i]; //提取字符
WR_DATA(); //送出
}
LCD=0xcd; //寫入顯示起始地址
WR_COMM(); //寫入命令
LCD=0x00; //CGRAM內第0號圖形
WR_DATA(); //寫入數據
TEMP_BJ();
}
//------------------------------------------- DS18B20初始化函數 --------------------------------------
bit INIT_1820(void)
{
bit flag; //flag為標志符
DQ = 1; //DQ復位
delay(3); //稍作延時
DQ = 0; //將數據線從高拉低,保持480~960us
delay(80);
DQ = 1; //釋放數據線
delay(10);
flag=DQ; //DQ=0表示存在
delay(25);
return (flag); //返回檢測標志
}
//------------------------------------------ 讀出DS18B20函數 ----------------------------------------
unsigned char READ_1820(void)
{
unsigned char i=0;
unsigned char dat; //儲存讀出的一個字節數據
for (i=0;i<8;i++)
{
DQ =1; //將數據線拉高
DQ = 0; //將數據線從高拉低,啟動讀時序
dat>>=1;
DQ = 1; //將數據線拉高,為輸出電平作準備
_nop_();
if(DQ==1)
dat|=0x80; //讀數據,存入dat
else
dat|=0x00; //讀數據,存入dat
delay(3);
}
return(dat); //返回讀出的十進制數據
}
//--------------------------------------------- 寫入DS18B20函數 ---------------------------------------------
WRITE_1820(unsigned char dat)
{
unsigned char i=0;
for (i=0; i<8; i++)
{
DQ =1; // 先將數據線拉高
DQ=0; //數據線從高拉低,開始寫入
DQ=dat&0x01; //利用與運算取出要寫的某位二進制數據,
delay(3);
DQ=1; //釋放數據線
_nop_();
dat>>=1; //將dat中的各二進制位數據右移1位
}
delay(3);
}
//---------------------------------------- 顯示錯誤信息函數 ------------------------------------------
void DISP_ERR(void)
{
unsigned char i;
LCD=0x80; //寫顯示地在第1行第1列
WR_COMM();
i = 0; //從第一個字符開始顯示
while(Error[i] != '\0') //寫到結束標志
{
LCD=(Error[i]); //將字符常量寫入LCD
WR_DATA();
i++; //指向下一個字符
delay(1000); //延時
}
while(1); //循環,等待查明原因
}
//-------------------------------------- 顯示溫度的小數點 ------------------------------------------
void DISP_D(void)
{
LCD=0xc9; //寫顯示地址在第2行第10列
WR_COMM();
LCD=('.');
WR_DATA();
delay(200); //延時一點時間
}
//------------------------------------------ 顯示TEMP字符函數 ------------------------------------------------
void DISP_TEMP(void)
{
unsigned char i;
LCD=0xc0; //寫入顯示起始地址
WR_COMM(); //寫入命令
for(i=0;i<5;i++)
{
LCD=TEMP[i]; //提取字符
WR_DATA(); //送出
}
}
//------------------------------------------- 顯示菜單函數 --------------------------------------------
DISP_EXP( )
{
unsigned char i;
LCD=0x83; //寫入顯示起始地址
WR_COMM(); //寫入命令
for(i=0;i<11;i++)
{
LCD=TAB2[i]; //提取字符
WR_DATA(); //送出
}
DISP_TEMP();
DISP_D();
}
//---------------------------------------------- 讀溫度函數 -----------------------------------------
RE_TEMP()
{
unsigned char time;
INIT_1820(); //將DS18B20初始化
WRITE_1820(0xCC); // 跳過讀序號列號的操作
WRITE_1820(0x44); // 啟動溫度轉換
for(time=0;time<100;time++);
INIT_1820(); //將DS18B20初始化
WRITE_1820(0xCC); //跳過讀序號列號的操作
WRITE_1820(0xBE); //讀取溫度的低位和高位
}
//------------------------------------------ 顯示溫度正負的符號 ---------------------------------------
void DISP_ZF(unsigned char fuhao)
{
unsigned char show;
show=fuhao;
LCD=0xc5; //寫顯示地址在第2行第10列
WR_COMM();
LCD=(show); //將小數點的字符常量寫入LCD
WR_DATA();
delay(200); //延時一點時間
}
//---------------------------------------- 顯示溫度的整數部分函數 ----------------------------------------
void DISP_TEMP1(unsigned char x)
{
unsigned char j,k,l; //j,k,l分別儲存溫度的百位、十位和個位
j=x/100; //取百位
k=(x%100)/10; //取十位
l=x%10; //取個位
LCD=0xc6; //寫顯示地址在第2行第7列
WR_COMM();
LCD=(digit[j]);
WR_DATA();
LCD=0xc7;
WR_COMM();
LCD=(digit[k]);
WR_DATA();
LCD=0xc8;
WR_COMM();
LCD=(digit[l]);
WR_DATA();
delay(200); //延時一點時間
}
//---------------------------------------- 顯示溫度的小數數部分函數 -----------------------------------------
void DISP_TEMP2(unsigned char x)
{
LCD=0xca; //寫顯示地址在第2行第11列
WR_COMM();
LCD=(digit[x]);
WR_DATA(); //將小數部分寫入LCD
delay(200); //延時一點時間
}
//---------------------------------------- 溫度數據轉換顯示函數 -------------------------------------------
void CONV_TEMP(void)
{
unsigned char TL; //儲存溫度低位
unsigned char TH; //儲存溫度高位
unsigned char TN; //儲存整數部分
unsigned char TD; //儲存小數部分
while(1) //不斷檢測顯示溫度
{
RE_TEMP(); //讀溫度函數
//-------------------
TL=READ_1820(); //先讀溫度值低位
TH=READ_1820(); //接著讀溫度值高位
if(TH>=0xf8)
{
DISP_ZF('-');
if(TL==0)
{
TH=(~TH+1)&0x03;
TN=TH*16+TL/16;
TD=(TL%16)*10/16;
goto loopshow;
}
TH=~TH&0x03;
TL=~TL+1;
TN=TH*16+TL/16;
TD=(TL%16)*10/16;
goto loopshow;
}
DISP_ZF('+');
TN=TH*16+TL/16; //計算溫度值整數部分
TD=(TL%16)*10/16; //計算溫度的小數部分
loopshow:
//------------------------
DISP_TEMP1(TN); //顯示溫度的整數部分
DISP_TEMP2(TD); //顯示溫度的小數部分
delay(100);
}
}
//---------------------------------------- 主函數 ----------------------------------------------
void main(void)
{
INIT_LCD(); //LCD初始化函數
delay(100);
if(INIT_1820()==1) //DS18B20初始化函數
DISP_ERR(); //顯示錯誤信息函數
STORE_DATA(); //自定義溫度標志符函數
DISP_EXP(); //顯示菜單函數
CONV_TEMP(); //溫度數據轉換顯示函數
…………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
該系列源碼包含有很多非常經典,代碼風格十分規范,而且注釋詳細的單片機例程,還帶仿真,對于MCU學習特別是初學者是很有幫助的,全部源碼下載(共25個項目):
http://www.raoushi.com/bbs/dpj-79328-1.html
本例程下載(含proteus仿真工程文件與源碼):
單片機LCD1602溫度計實驗.rar
(76.76 KB, 下載次數: 291)
2017-3-30 01:35 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
作者:
科學小怪蛋
時間:
2017-3-30 12:42
可以。。
作者:
gentlezr
時間:
2017-6-6 19:24
請問在這個基礎上怎么加報警器,并且可以手動設置溫度上限呢
作者:
bobono1
時間:
2017-6-20 13:02
完美!
作者:
慚阜崳
時間:
2017-12-5 10:44
好貼,很給力!
作者:
292217911
時間:
2017-12-12 01:05
剛好要用到,太有幫助了
作者:
歐陽云天
時間:
2018-5-30 21:54
新手看得云里霧里的
作者:
丶Cristiano
時間:
2018-10-28 23:54
很實用,謝謝樓主
作者:
sgly
時間:
2019-3-5 16:30
正需要這個,謝謝啦
作者:
casualV
時間:
2019-3-17 09:56
感謝分享
作者:
chenziyue1996
時間:
2019-3-17 12:01
感謝分享,多謝
作者:
czbbb
時間:
2019-6-10 15:04
感謝感謝
作者:
qwerfghnm
時間:
2019-6-19 09:15
怎么能在加個NRF24L01無線傳輸模塊呢?
歡迎光臨 (http://www.raoushi.com/bbs/)
Powered by Discuz! X3.1