|
基于89cC51溫度控制系統
含顯示屏
以下為源程序和仿真
#include<reg51.h>
#include<intrins.h>
#include<absacc.h>
#include<DS18B20.h>
#define uchar unsigned char
#define uint unsigned int
#define BUSY 0x80 //1cd忙檢測標志
#define DATAPORT P0 //定義P0口為LCD通訊端口
#define PLAYE_ADDR XBYTE[0XBFFF] //語音報警地址
sbit RED_ALARM=P1^0; //紅色指示燈
sbit WRITE_ALARM=P1^1; // 白色指示燈
sbit GREEN_ALARM=P1^2; //綠色指示燈
sbit BLUE_ALARM = P1^3;
sbit P1_4 = P1^4; //時鐘調整
sbit P1_5 = P1^5; //時鐘加
sbit P1_6=P1^6; //時鐘減
sbit DQ=P1^7; //定義ds18b20通信端口
sbit LCM_RS=P2^0; //數據/命令端
sbit LCM_RW=P2^1; //讀/寫選擇端
sbit LCM_EN=P2^2;
sbit sda=P2^3; //I0口定義
sbit scl=P2^4; //LCD使能信號
sbit ad_busy=P3^2; //adc中斷方式接口
sbit RECLED_EOC=P3^5; //ISD1420放音結東查詢標志
sbit OUT=P3^7;
uchar ad_data; //ad采樣值存儲
uchar seconde; //定義并初始化時鐘變量
uchar minite;
uchar hour;
uchar mstcnt=0;
uchar temp1,temp2,temp; //溫度顯示變量
uchar t,set;
uchar K;
bit ON_OFF=0;
bit outflag;
bit write=0;
uchar code str0[]={"--- : : --- "};
uchar code str1[]={"SET: C SA: . C"};
void delay_LCM(uint); //LCD延時子程序
void initLCM( void); //LCD初始化子程序
void lcd_wait(void); //LCD檢測忙子程序
void WriteCommandLCM(uchar WCLCM,uchar BusyC);//寫指令到1CM子函數
void WriteDataLCM(uchar WDLCM); //寫數據到1CM子函數
void DisplayOneChar(uchar X,uchar Y,uchar DData);//顯示指定坐標的一個字符子函數
void DisplayListChar(uchar X,uchar Y,uchar code *DData);//顯示指定坐標的串字符子函數
void init_timer0(void); //定時器初始化
void displayfun1(void);
void displayfun2(void);
void displayfun3(void);
void displayfun4(void);
void keyscan(void ); //鍵盤掃描子程序
void set_adj(void);
void inc_key(void);
void dec_key(void);
void delay_18B20(unsigned int i);
void Init_DS18B20(void);
uchar ReadOneChar(void);
void WriteOneChar(unsigned char dat);
void ReadTemperature(void);
void ad0809(void);
void playalarm(void);
//**********延時K*1ms,12.000mhz*******/
void delay_LCM(uint k)
{
uint i,j;
for(i=0; i<k; i++)
{
for(j=0;j<60;j++)
{;}
}
}
//*****寫指令到LCM子函數********//
void WriteCommandLCM(uchar WCLCM,uchar BusyC)
{
if(BusyC)lcd_wait();
DATAPORT=WCLCM;
LCM_RS=0; //選中指令寄存器
LCM_RW=0; //寫模式
LCM_EN=1;
_nop_();
_nop_();
_nop_();
LCM_EN=0;
}
//*****寫數據到LCM子函數********//
void WriteDataLcm(uchar WDLCM)
{
lcd_wait( ); //檢測忙信號
DATAPORT=WDLCM;
LCM_RS=1; //選中數據寄存器
LCM_RW=0; //寫模式
LCM_EN = 1;
_nop_();
_nop_();
_nop_();
LCM_EN=0;
}
//*******1cm內部等待函數********/
void lcd_wait(void)
{
DATAPORT=0xff;
LCM_EN=1;
LCM_RS=0;
LCM_RW=1;
_nop_();
while(DATAPORT&BUSY)
{
LCM_EN=0;
_nop_();
_nop_();
LCM_EN=1;
_nop_();
_nop_();
}
LCM_EN=0;
}
//*******LCM初始化子函數*******/
void initLCM( )
{
DATAPORT=0;
delay_LCM(15);
WriteCommandLCM(0x38,0);//三次顯示模式設置,不檢測忙信號
delay_LCM(5);
WriteCommandLCM(0x38,0);
delay_LCM(5);
WriteCommandLCM(0x38,0);
delay_LCM(5);
WriteCommandLCM(0x38,1);//8bit數據傳送,2行顯示,5*7字型,檢測忙信號
WriteCommandLCM(0x08,1);//關閉顯示,檢測忙信號
WriteCommandLCM(0x01,1);//清屏,檢測忙信號
WriteCommandLCM(0x06,1);//顯示光標右移設置,檢測忙信號
WriteCommandLCM(0x0c,1);//顯示屏打開,光標不顯示,不閃爍,檢測忙信號
}
//****常顯示指定坐標的一個字符子函數******//
void DisplayOneChar(uchar X,uchar Y,uchar DData)
{
Y &= 1;
X &= 15;
if(Y)X|=0x40; //若y為1(顯示第二行),地址碼+0X40
X|=0x80; //指令碼為地址碼+0X80
WriteCommandLCM(X,0);
WriteDataLCM(DData);
}
//****顯示指定坐標的一串字符子函數*****//
void DisplayListChar(uchar X,uchar Y,uchar code *DData)
{
uchar ListLength = 0;
Y &= 0x01;
X &= 0x0f;
while(X < 16)
{
DisplayOneChar(X,Y,DData[ListLength]);
ListLength++;
X++;
}
}
//*****ds18b20延遲子函數(晶振12MHz)****/
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(14);
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&0x0l;
delay_18B20(5);
DQ = 1;
dat >>= 1;
}
}
//****讀取ds18b20當前溫度*****/
void ReadTemperature(void)
{
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(); //讀取溫度值高位
temp1 = b<<4;
temp1 += (a&0xf0)>>4;
temp2 = a&0x0f;
temp =((b*256+a)>>4);//當前采集溫度值除16得實際溫度值
}
//****液品顯示子函數1正常顯示*****//
void displayfun1(void)
{
WriteCommandLCM(0x0c,1); //顯示屏打開,光標不顯示,不閃爍,檢測忙信號
DisplayListChar(0,0,str0);
DisplayListChar(0,1,str1);
DisplayOneChar(3,0,hour/10+0x30);//液晶上顯示小時
DisplayOneChar(4,0,hour%10+0x30);
DisplayOneChar(6,0,minite/10+0x30),//液晶上顯示分
DisplayOneChar(7,0,minite%10+0x30);
DisplayOneChar(9,0,seconde/10+0x30);//液晶上顯示秒
DisplayOneChar(10,0,seconde%10+0x30);
DisplayOneChar(4,1,K/10+0x30); //液品上顯示設定的溫度
DisplayOneChar(5,1,K%10+0x30);
DisplayOneChar(11,1,temp1/10+0x30);//液晶上顯示測得的溫度
DisplayOneChar(12,1,temp1%10+0x30);
DisplayOneChar(14,1,temp2/10+0x30);
if(ON_OFF == 0) //若溫控標志為0
{
DisplayOneChar(14,0,0x4f); //液晶上顯示不控溫的標志
DisplayOneChar(15,0,0x46);
}
else
{
DisplayOneChar(14,0,0x4f); //液晶上顯示控溫的標志
DisplayOneChar(15,0,0x4e);
if(outflag == 1)
DisplayOneChar(0,0,0x7c);
else
DisplayOneChar(0,0,0xef);
}
}
//*****液晶最示子函數2*****//
void displayfun2(void)
{
WriteCommandLCM(0x0c,1); //顯示屏打開,光標不顯示,不閃爍,檢測忙信號
DisplayListChar(0,0,str0);
DisplayListChar(0,1,str1);
DisplayOneChar(6,0,minite/10+0x30);
DisplayOneChar(7,0,minite%10+0x30);
DisplayOneChar(9,0,seconde/10+0x30);
DisplayOneChar(10,0,seconde%10+0x30);
DisplayOneChar(4,1,K/10+0x30);
DisplayOneChar(5,1,K%10+0x30);
DisplayOneChar(11,1,temp1/10+0x30);
DisplayOneChar(12,1,temp1%10+0x30);
DisplayOneChar(14,1,temp2/10+0x30);
WriteCommandLCM(0x0f,1); //顯示打開,光標顯示,閃爍,檢測忙信號
DisplayOneChar(3,0,hour/10+0x30);
DisplayOneChar(4,0,hour%10+0x30);
}
//*****液晶顯示子函數3****//
void displayfun3(void)
{
WriteCommandLCM(0x0c,1); //顯示屏打開,光標不顯示,不閃爍,檢測忙信號
DisplayListChar(0,0,str0);
DisplayListChar(0,1,str1);
DisplayOneChar(3,0,hour/10+0x30);
DisplayOneChar(4,0,hour%10+0x30);
DisplayOneChar(9,0,seconde/10+0x30);
DisplayOneChar (10,0,seconde%10+0x30);
DisplayOneChar(4,1,K/10+0x30);
DisplayOneChar(5,1,K%10+0x30);
DisplayOneChar(11,1,temp1/10+0x30);
DisplayOneChar(12,1,temp1%10+0x30);
DisplayOneChar(14,1,temp2/10+0x30);
WriteCommandLCM(0x0f,1);//顯示屏打開,光標顯示,閃爍,檢測忙信號
DisplayOneChar(6,0,minite/10+0x30);
DisplayOneChar(7,0,minite%10+0x30);
}
//*****液晶顯示子函數4******//
void displayfun4(void)
{
WriteCommandLCM(0x0c,1);//顯示屏打開,光標不顯示,不閃爍,檢測忙信號
DisplayListChar(0,0,str0);
DisplayListChar(0,1,str1);
DisplayOneChar(3,0,hour/10+0x30);
DisplayOneChar(4,0,hour%10+0x30);
DisplayOneChar(6,0,minite/10+0x30);
DisplayOneChar(7,0,minite%10+0x30);
DisplayOneChar(9,0,seconde/10+0x30);
DisplayOneChar(10,0,seconde%10+0x30);
DisplayOneChar(11,1,temp1/10+0x30);
DisplayOneChar(12,1,temp1%10+0x30);
DisplayOneChar(14,1,temp2/10+0x30);
WriteCommandLCM(0x0f,1);//顯示屏打開,光標顯示,閃爍,檢測忙信號
DisplayOneChar(4,1,K/10+0x30);
DisplayOneChar(5,1,K%10+0x30);
}
//*****鍵盤掃描子函數*****//
void keyscan(void)
{
uchar xx; //局部變量
P1 = 0xff;
if( P1 != 0xff)
{
delay_LCM(50);
if(P1 != 0xff)
{
xx = P1;
switch (xx) //根據按鍵狀態,調用不同的子函數
{
case 0xfe:set_adj();
break;
case 0xfd:inc_key();
break;
case 0xfb:dec_key();
break;
case 0xf7:{delay_LCM(150);ON_OFF=!ON_OFF;while(!BLUE_ALARM);}
break;
default: break;
}
}
}
}
//*****設定工作模式子函數*****//
void set_adj(void)
{
delay_LCM(100);
set++;
if(set >= 4)set = 0;
while(!RED_ALARM);
}
//*****按鍵加法子函數******//
void inc_key(void)
{
delay_LCM(150);
switch(set)
{
case 0: if(P1 == 0xf7)
{delay_LCM(150);ON_OFF = !ON_OFF;}
break;
case 1: hour++; if(hour >= 23)hour = 23;
break;
case 2: minite++; if(minite >= 59)minite = 59;
break;
case 3:K++;if(K >= 99)K = 99;
break;
default: break;
}
while(!WRITE_ALARM);
}
//*****按鍵減法子函數******//
void dec_key(void)
{
delay_LCM(150);
switch(set)
{
case 0:if(P1 == 0xf7)
{delay_LCM(150);ON_OFF=!ON_OFF;}
break;
case 1:hour--;
if(hour <= 0)hour = 0;
break;
case 2: minite--;
if(minite <= 0)minite = 0;
break;
case 3: K--; if(K <= 1)K = 1;
break;
default: break;
}
while(!GREEN_ALARM);
}
//******24C02讀寫驅動程序*****//
void delay1(uchar x)
{
uint i;
for(i = 0;i < x;i++);
}
void flash()
{ ; ; }
void x24c02_init()//24c02初始化子程序
{
scl = 1;
flash();
sda = 1;
flash();
}
void start() //啟動I2C總線
{
sda = 1;
flash();
scl = 1;
flash();
sda = 0;
flash();
scl = 0;
flash();
}
void stop() //停止I2C總線
{
sda = 0;
flash();
scl = 1;
flash();
sda = 1;
flash();
}
void writex(uchar j)//寫一個字節
{
uchar i,temp;
temp = j;
for (i = 0; i < 8; i++)
{
temp = temp<<1;
scl = 0;
flash();
sda = CY;
flash();
scl = 1;
flash();
}
scl = 0;
flash();
sda = 1;
flash();
}
uchar readx()//讀一個字節
{
uchar i,j,k = 0;
scl = 0;
flash();
sda = 1;
for(i = 0;i < 8;i++)
{
flash();
scl = 1;
flash();
if(sda == 1)j = 1;
else j = 0;
k = (k<<1)|j;
scl = 0;
}
flash();
return(k);
}
void clock() //I2C總線時鐘
{
uchar i = 0;
scl = 1,
flash();
while((sda == 1)&&(i<255))i++;
scl = 0;
flash();
}
//////從24c02的地址 address中讀取一個字節數據////
uchar x24c02_read(uchar address)
{
uchar i;
start();
writex(0xa0);
clock();
writex(address);
clock();
start();
writex(0xa1);
clock();
i = readx();
stop();
delay1(10);
return (i);
}
////向24c02的address地址中寫入一字節數據info////
void x24c02_write(uchar address,uchar info)
{
EA = 0;
start();
writex(0xa0);
clock();
writex(address);
clock();
writex(info);
clock();
stop();
EA = 1;
delay1(50);
}
//*****定時器t0初始化*****//
void init_timer0(void)
{
TMOD = 0x01; //time0為定時器,方式1
TH0 = 0x3c; //于預置計數初值
TL0 = 0xb0;
EA = 1;
ET0 = 1;
TR0 = 1;
}
//*****定時器t0中斷子函數*****//
void timer0(void) interrupt 1 using 0 //定時器0方式1,50ms中斷一次
{
TH0 = 0x3c;
TL0 = 0xb0;
mstcnt++;
if(mstcnt >= 20 )
{seconde++;write = 1; mstcnt = 0;}
if(seconde >= 60)
{minite++; seconde = 0;}
if(minite >= 60 )
{hour++; minite = 0;}
if(hour >= 24 )
{hour = 0;}
keyscan( ); //按鍵掃描
}
//******the main funtion******/
|
-
-
電加熱爐溫度控制系統設計.zip
2019-5-18 10:08 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
187.21 KB, 下載次數: 142, 下載積分: 黑幣 -5
|