久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费
標題:
單片機熱水鍋爐自動溫度控制系統(C51)
[打印本頁]
作者:
51黑科技
時間:
2016-2-3 22:52
標題:
單片機熱水鍋爐自動溫度控制系統(C51)
為好朋友東東設計了個單片機熱水鍋爐自動溫度控制系統。因為他家的熱水鍋爐因溫度太低,沒及時加熱,爆過幾 次。也有因加熱過頭,燒干水,化了管子。東東很快做好了實物,程序得到驗證,兩人皆大歡喜。
1.下限5°C時加熱器加熱,上限40°C時停止。溫度下降,直到下限時重新加熱。
2.溫度70°C時冷卻水泵工作,溫度降到45°C時停止。下次仍為70°C時水泵工作。
3.加熱/水泵 按鈕可切換切換加熱器和冷卻泵的設定及顯示(HTR為加熱器,CTP為冷卻水泵)。
程序中對兩組上下限設定做成可調的,方便實際使用中對上下限的細調。
E:\DPJ_C\18B20LCD\DD2\18B20DD2.C
//2012 05 04
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit RS=P2^0;
sbit RW=P2^1;
sbit E=P2^2;
sbit BF=P0^7;
sbit DQ=P3^3;
sbit KEY0=P1^0;
sbit KEY1=P1^1;
sbit KEY2=P1^2;
sbit KEY3=P1^3;
sbit HTR=P1^4; //加熱器
sbit CTP=P1^5; //冷卻泵
uchar h_TH=40,h_TL=5,p_TH=70,p_TL=45;
uchar code digit[12]={"0123456789- "};
uchar code digit1[15]={"011233445677889"};
uchar code digit2[16]={"0112234456677889"};
uchar code Now[]={"Now:"};
uchar code TH[]={"TH"};
uchar code TL[]={"TL"};
uchar code Cent[]={0xdf,0x43}; //溫度單位℃
bit flag1,flag2,flag3; //flag1溫度為負的標志 flag2電熱標志 flag3 水泵標志
/*****************************************************
us 延時子函數
***************************************************/
void ds18b20_delay(uchar us)
{
while(us--);
}
/*****************************************************
ms 延時子函數
***************************************************/
void delay(uint ms)
{
uchar i;
while(ms--)
for(i=0;i<123;i++);
}
/*****************************************************
判斷液晶模塊的忙碌狀態
***************************************************/
bit BusyTest()
{
bit result;
RS=0;
RW=1;
E=1;
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四個機器周期,給硬件反應時間
result=BF;
E=0; //將E恢復低電平
return result;
}
/*****************************************************
將模式設置指令或顯示地址寫入液晶模塊
***************************************************/
void WriteCmd (uchar dictate)
{
while(BusyTest()==1); //如果忙就等待
RS=0;
RW=0;
E=0;
_nop_();
_nop_(); //空操作兩個機器周期,給硬件反應時間
P0=dictate;
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四個機器周期,給硬件反應時間
E=1;
_nop_();
_nop_();
_nop_();
_nop_();
E=0;
}
/*****************************************************
函數功能:指定字符顯示的實際地址
入口參數:x
***************************************************/
void WriteAdd(uchar x)
{
WriteCmd(x|0x80); //顯示位置的確定方法規定為"80H+地址碼x"
}
/*****************************************************
將數據(字符的標準ASCII碼)寫入液晶模塊
***************************************************/
void WriteData(uchar 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由高電平跳變成低電平時,液晶模塊開始執行命令
}
/*****************************************************
LCD1602 初始化
***************************************************/
void LcdInitiate(void)
{
delay(15); //延時15ms,首次寫指令時應給LCD一段較長的反應時間
WriteCmd(0x38); //顯示模式設置:16×2顯示,5×7點陣,8位數據接口
delay(5); //延時5ms ,給硬件一點反應時間
WriteCmd(0x38);
delay(5); //延時5ms ,給硬件一點反應時間
WriteCmd(0x38); //連續三次,確保初始化成功
delay(5); //延時5ms ,給硬件一點反應時間
WriteCmd(0x0c); //顯示模式設置:顯示開,無光標,光標不閃爍
delay(5); //延時5ms ,給硬件一點反應時間
// WriteCmd(0x06); //顯示模式設置:光標右移,字符不移
delay(5); //延時5ms ,給硬件一點反應時間
WriteCmd(0x01); //清屏幕指令,將以前的顯示內容清除
delay(5); //延時5ms ,給硬件一點反應時間
}
/************************************************************************
以下是DS18B20的操作程序
************************************************************************/
/*****************************************************
DS18B20初始化
***************************************************/
void Init_DS18B20()
{
uchar x=0;
DQ=1;
ds18b20_delay(8);
DQ=0;
ds18b20_delay(80);
DQ=1;
ds18b20_delay(14);
x=DQ;
ds18b20_delay(20);
}
/*****************************************************
函數功能:寫一個字節
入口參數:
***************************************************/
void WriteOneChar(uchar dat)
{
uchar i;
for(i=8;i>0;i--)
{
DQ=0;
if(dat&0x01==0x01)
DQ=1;
else
DQ=0;
ds18b20_delay(5);
DQ=1;
ds18b20_delay(1);
dat>>=1;
}
}
/*****************************************************
讀一個字節
***************************************************/
uchar ReadOneChar()
{
uchar dat=0,i;
for(i=8;i>0;i--)
{
dat>>=1;
DQ=0;
ds18b20_delay(1);
DQ=1;
if(DQ==1)
dat|=0x80;
else
dat&=0x7f;
ds18b20_delay(4);
}
return(dat);
}
/*****************************************************
顯示Now:
***************************************************/
void display_Now()
{
uchar i;
WriteAdd(0x00); //寫顯示地址,將在第1行第1列開始顯示
for(i=0;i<4;i++)
WriteData(Now[i]);
delay(50); //延時1ms給硬件一點反應時間
}
/*****************************************************
顯示溫度的小數點
***************************************************/
void display_dot(void)
{
WriteAdd(0x07); //寫顯示地址,將在第1行第10列開始顯示
WriteData('.'); //將小數點的字符常量寫入LCD
delay(50); //延時1ms給硬件一點反應時間
}
/*****************************************************
顯示溫度的單位(°C)
***************************************************/
void display_cent(void)
{
uchar i;
WriteAdd(0x09); //寫顯示地址,將在第1行第13列開始顯示
for(i=0;i<2;i++)
WriteData(Cent[i]); //將字符常量寫入LCD
WriteAdd(0x45);
for(i=0;i<2;i++)
WriteData(Cent[i]);
WriteAdd(0x4e);
for(i=0;i<2;i++)
WriteData(Cent[i]);
}
/*****************************************************
顯示溫度的整數部分
***************************************************/
void display_temp1(uchar x)
{
uchar j,k,l; //j,k,l分別儲存溫度的百位、十位和個位
j=x/100; //取百位
k=(x%100)/10; //取十位
l=x%10; //取個位
WriteAdd(0x04); //寫顯示地址,將在第1行第5列開始顯示
if(flag1==1)
{
WriteData(digit[10]); //將"-" 號寫入LCD
}
else
if(j==0)
{j=11;}
WriteData(digit[j]); //將百位數字的字符常量寫入LCD
if(j==0&&k==0)
{k=11;}
WriteData(digit[k]); //將十位數字寫入LCD
WriteData(digit[l]); //將個位數字寫入LCD
delay(50);
}
/*****************************************************
顯示溫度的小數部分
***************************************************/
void display_temp2(uchar x)
{
WriteAdd(0x08); //寫顯示地址,將在第2行第11列開始顯示
if(flag1==1)
{
WriteData(digit1[x]); //溫度為負,將小數部分的第一位數字寫入LCD
}
else
WriteData(digit2[x]); //溫度為正,將小數部分的第一位數字寫入LCD
}
/*****************************************************
顯示溫度設定部分
***************************************************/
void display_THTL ()
{
uchar i,hhh,hhl,phh,phl,hlh,hll,plh,pll;
hhh=h_TH/10;
hhl=h_TH%10;
phh=p_TH/10;
phl=p_TH%10;
hlh=h_TL/10;
hll=h_TL%10;
plh=p_TL/10;
pll=p_TL%10;
WriteAdd(0x40); //第2行第1個字節開始
for(i=0;i<2;i++)
WriteData(TH[i]);
WriteAdd(0x43);
if(flag2)
{
WriteData(digit[phh]);
WriteData(digit[phl]);
}
else
{
WriteData(digit[hhh]);
WriteData(digit[hhl]);
}
WriteAdd(0x49); //第2行第10個字節開始
for(i=0;i<2;i++)
WriteData(TL[i]);
WriteAdd(0x4c);
if(flag2)
{
WriteData(digit[plh]);
WriteData(digit[pll]);
WriteAdd(0x0d);
WriteData('C');
WriteAdd(0x0e);
WriteData('T');
WriteAdd(0x0f);
WriteData('P');
}
else
{
WriteData(digit[hlh]);
WriteData(digit[hll]);
WriteAdd(0x0d);//也可以這樣的寫法
WriteData('H');
WriteAdd(0x0e);
WriteData('T');
WriteAdd(0x0f);
WriteData('R');
}
}
/*****************************************************
準備讀溫度
***************************************************/
void ReadyReadTemp()
{
Init_DS18B20(); //將DS18B20初始化
WriteOneChar(0xCC); // 跳過讀序號列號的操作
WriteOneChar(0x44); // 啟動溫度轉換
//for(time=0;time<100;time++); //溫度轉換需要一點時間
Init_DS18B20(); //將DS18B20初始化
WriteOneChar(0xCC); //跳過讀序號列號的操作
WriteOneChar(0xBE); //讀取溫度寄存器,前兩個分別是溫度的低位和高位
}
/*****************************************************
函數功能:按鍵掃描子函數
***************************************************/
void keyscan()
{
while(!KEY0) //加熱/水泵切換
{
delay(10);
if(KEY0)
flag2=!flag2;
}
while(!KEY1) //上限/下限切換
{
delay(10);
if(KEY1)
flag3=!flag3;
}
while(!KEY2) //設置溫度加
{
delay(10);
if(KEY2)
{
if(flag2)
{
if(flag3)
p_TL++;
else
p_TH++;
}
else
{
if(flag3)
h_TL++;
else
h_TH++;
}
}
}
while(!KEY3) //設置溫度減
{
delay(10);
if(KEY3)
{
if(flag2)
{
if(flag3)
p_TL--;
else
p_TH--;
}
else
{
if(flag3)
h_TL--;
else
h_TH--;
}
}
}
}
/*****************************************************
主函數
***************************************************/
void main()
{
uint temp;
uchar TL; //儲存暫存器的溫度低位
uchar TH; //儲存暫存器的溫度高位
uchar TN; //儲存溫度的整數部分
uchar TD; //儲存溫度的小數部分
LcdInitiate(); //將液晶初始化
delay(5); //延時5ms給硬件一點反應時間
display_Now();
display_dot(); //顯示溫度的小數點
display_cent(); //顯示 ℃
HTR=1;
CTP=1;
while(1)
{
keyscan();
ReadyReadTemp(); //讀溫度準備
TL=ReadOneChar(); //先讀溫度值低位
TH=ReadOneChar(); //后讀溫度值高位
ds18b20_delay(150);
if(TN<h_TL)
HTR=0;
if(TN>h_TH)
HTR=1;
if(TN>p_TH)
CTP=0;
if(TN<p_TL)
CTP=1;
// if(TH&0xf8==0xf8) //TH高5 位為1,溫度值為負 。負數一直調試未成,原來是忽視了優先等級。改成if((TH&0XF8)==0XF8),負溫度就正常了。
// {
// flag1=1;
// TL=~(TL)+0x01;
// TH=~TH;
// }
// else
temp=TH;
temp=temp<<8|TL;
TN=temp*0.0625;
// flag1=0;
TD=TL&0x0f;
display_THTL();
display_temp1(TN); //顯示溫度的整數部分
display_temp2(TD); //顯示溫度的小數部分
delay(10);
}
}
復制代碼
作者:
ls0899
時間:
2016-2-27 23:13
我試了一下。顯示NOW:255一直在閃
作者:
jiyidewang
時間:
2017-3-9 18:41
//2012 05 04
歡迎光臨 (http://www.zg4o1577.cn/bbs/)
Powered by Discuz! X3.1
主站蜘蛛池模板:
国产精品久久久精品
|
男女羞羞视频免费
|
毛片视频免费
|
亚洲精精品
|
成人黄色电影在线播放
|
性大毛片视频
|
亚洲视频一区二区三区
|
欧美日韩国产精品一区
|
久久亚洲一区
|
国产视频在线观看一区二区三区
|
国产精品久久久久久久久久妞妞
|
欧美精品福利
|
日韩欧美在线观看
|
伊人网站视频
|
中文字幕一区在线
|
久久久久久久久久久丰满
|
日韩成人国产
|
7799精品视频天天看
|
亚洲一级av毛片
|
日日干夜夜操天天操
|
黄色操视频
|
99精品一区二区
|
男人久久天堂
|
日本成人片在线观看
|
一级在线观看
|
日韩国产一区二区三区
|
欧美在线视频一区二区
|
成人一区二区三区视频
|
91精品国产一区二区三区动漫
|
亚洲国产成人在线视频
|
日韩乱码一二三
|
av电影手机版
|
毛片一级片
|
欧美中文字幕一区二区三区亚洲
|
久久网国产
|
亚洲一区
|
精品国偷自产在线
|
小草久久久久久久久爱六
|
国产精品美女久久久
|
亚洲国产激情
|
新91
|