|
這是全部代碼,請求各位大佬幫忙看一下哪里出問題了非常感謝各位
代碼運行后有三個警告
單片機源程序如下:
#include <reg52.h> // 包含頭文件
#include <intrins.h>
#include<math.h>
#define uchar unsigned char
#define uint unsigned int
sbit DQ = P3^7; // DS18B20傳感器的引腳定義
sbit Buzzer = P1^0; // 蜂鳴器引腳
sbit JdqLow = P2^0; // 溫度過低繼電器控制(加熱)
sbit JdqHig = P2^1; // 溫度過高繼電器控制(降溫)
sbit LedLow = P2^2; // 溫度低指示燈
sbit LedHig = P2^3; // 溫度高指示燈
sbit key1 = P3^4; // 設(shè)置按鍵
sbit key3 = P3^6; // 減按鍵
sbit key2 = P3^5; // 加按鍵
sbit RS = P2^6;//1602數(shù)據(jù)/命令選擇端(H:數(shù)據(jù)寄存器L:指令寄存器)
sbit RW = P2^5;//1602讀/寫選擇端
sbit E = P2^4;//1602使能信號
/******************************************************************/
/* 全局變量 */
/******************************************************************/
int temp;//測得溫度
char temp_max=40,temp_min=10;//設(shè)定的溫度
char TempH,TempL;
char control;
uchar flag_get,num=0;
uchar code tab[]={'0','1','2','3','4','5','6','7','8','9'};//液晶顯示
uchar tab1[10]="zcjrjw";//液晶第二行顯示內(nèi)容
uchar mark[16];
uchar str[8];
/*********************************************************/
// 延時函數(shù),
/*********************************************************/
void delay1(uint i)//短延時函數(shù)
{
while(i--);
}
void delay(uint z) //長延時函數(shù)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/*********************************************************/
// 延時15微秒
/*********************************************************/
void Delay15us(void)
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
/*********************************************************/
// 定時器初始化
/*********************************************************/
void Init_DS18B20(void)
{
uchar x=0;
DQ = 1; //拉高總線,等待
delay1(8);
DQ = 0; //單片機將DQ拉低
delay1(80); //精確延時 大于 480us
DQ = 1; //拉高總線,等待
delay1(10);
x=DQ; //稍做延時后 如果x=0則初始化成功 x=1則初始化失敗
delay1(10);
}
/******************************************************************/
/* DS18B20寫一個字節(jié) */
/******************************************************************/
void WriteOneChar(uchar dat) //DS18B20寫一個字節(jié)
{
uchar i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;//取最低位
delay1(5);
DQ = 1;
dat>>=1;//左移
}
delay1(5);
}
/******************************************************************/
/* DS18B20讀一個字節(jié) */
/******************************************************************/
uchar ReadOneChar(void) // DS18B20讀一個字節(jié)
{
uchar i=0;
uchar dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 給脈沖信號
dat>>=1;
DQ = 1; // 給脈沖信號,主機在讀時隙期間必須釋放總線
if(DQ)
dat|=0x80;
delay1(5);
}
return(dat);
}
/******************************************************************/
/* DS18B20讀取溫度 */
/******************************************************************/
uint ReadTemperature(void) //DS18B20讀取溫度
{
uchar a=0;
uint b=0;
uint t=0;
Init_DS18B20();//DS18B20初始化
WriteOneChar(0xCC); // 跳過讀序號列號的操作
WriteOneChar(0x44); // 啟動溫度轉(zhuǎn)換
delay1(200); //延時以求信號的穩(wěn)定
Init_DS18B20(); //DS18B20再次初始化
WriteOneChar(0xCC); //跳過讀序號列號的操作
WriteOneChar(0xBE); //讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度
a=ReadOneChar(); //低位
b=ReadOneChar(); //高位
b<<=8; //b左移8位
t=a+b; //把a與b結(jié)合,放在16位的t中 此處兩行代碼也可用t=((b*256)+1)替代 原理相同
return(t);
}
/******************************************************************/
/* LCD1602寫命令操作 */
/******************************************************************/
void WriteCommand(uchar com)
{
delay(5);//操作前短暫延時,保證信號穩(wěn)定
E=0;
RS=0;
RW=0;
P0=com;
E=1;
delay(5);
E=0;
}
/******************************************************************/
/* LCD1602寫數(shù)據(jù)操作 */
/******************************************************************/
void WriteData(uchar dat)
{
delay(5); //操作前短暫延時,保證信號穩(wěn)定
E=0;
RS=1;
RW=0;
P0=dat;
E=1;
delay(5);
E=0;
}
/******************************************************************/
/* LCD1602初始化程序 */
/******************************************************************/
void InitLcd()
{
// uchar i;
delay(15);
WriteCommand(0x38); //display mode
WriteCommand(0x06); //顯示光標(biāo)移動位置
WriteCommand(0x0c); //顯示開及光標(biāo)設(shè)置
WriteCommand(0x01); //顯示清屏
}
/******************************************************************/
/* 顯示測得的溫度 */
/******************************************************************/
void handle_T()
{
uchar i;
str[0]=0x20;//顯示為空
str[1]=tab[TempH/100]; //百位溫度
str[2]=tab[(TempH%100)/10]; //十位溫度
str[3]=tab[(TempH%100)%10]; //個位溫度,帶小數(shù)點
str[5]=tab[TempL];
str[4]='.';
str[6]=0xdf;
str[7]='C';
mark[1]=0x20;
mark[2]=tab[1]; //百位溫度
mark[3]=tab[0]; //十位溫度
mark[4]=0x20;
mark[5]='-'; //百位溫度
mark[6]=0x20;
mark[7]=tab[4]; //十位溫度
mark[8]=tab[0]; //百位溫度
mark[9]=0x20;
mark[10]=0x20;
mark[11]=tab1[control/10]; //十位溫度11
mark[12]=tab1[control%10]; //十位溫度
if(flag_get==1) //定時讀取當(dāng)前溫度
{
flag_get=0; //清標(biāo)志位
temp=ReadTemperature();//讀取溫度值
if(temp&0x8000)
{
str[0]=0xb0;//負(fù)號標(biāo)志
temp=~temp; // 取反加1
temp +=1;
}
TempH=temp>>4; //由權(quán)重表知移4位就是整數(shù)位
TempL=temp&0x0F;
TempL=TempL*6/10;//小數(shù)近似處理
}
WriteCommand(0x80+0x40);//將光標(biāo)移到第二行
for(i=0;i<16;i++)//顯示初始化內(nèi)容
{
WriteData(mark[ i]);
delay(10);
}
WriteCommand(0x80+0x04);//光標(biāo)指向第一行第一個字符
for(i=0;i<8;i++)// 顯示
{
WriteData(str[ i]);
delay(10);
}
}
void display_range(uchar add,int t)
{
uchar i;
if(t<0)
{
str[0]=0xb0;//負(fù)號標(biāo)志
}
else
{
str[0]=tab[abs(t)/100]; //百位溫度
str[1]=tab[(abs(t)%100)/10]; //十位溫度
str[2]=tab[(abs(t)%100)%10]; //個位溫度
WriteCommand(0x80+0x40+add);
}
for(i=0;i<3;i++)
{
WriteData(str[ i]);
delay(5);
}
}
/*********************************************************/
// 報警判斷
/*********************************************************/
void alarm(int dat)
{
if(TempL<temp_min) // 判斷溫度是否過低
{
LedLow=0; // 溫度低指示燈亮
LedHig=1; // 溫度高指示燈滅
JdqLow=0; // 溫度過低的繼電器閉合(開始加熱)
JdqHig=1; // 溫度過高的繼電器斷開(停止降溫)
Buzzer=0; // 蜂鳴器報警
}
else if(TempH>temp_max) // 判斷溫度是否過高
{
LedLow=1; // 溫度低指示燈滅
LedHig=0; // 溫度高指示燈亮
JdqLow=1; // 溫度過低的繼電器斷開(停止加熱)
JdqHig=0; // 溫度過高的繼電器閉合(開始降溫)
Buzzer=0; // 蜂鳴器報警
}
else // 溫度正常
{
LedLow=1; // 溫度低指示燈滅
LedHig=1; // 溫度高指示燈滅
JdqLow=1; // 溫度過低的繼電器斷開(停止加熱)
JdqHig=1; // 溫度過高的繼電器斷開(停止降溫)
Buzzer=1; // 蜂鳴器停止報警
}
}
/******************************************************************/
/* 獨立鍵盤掃描函數(shù)并顯示設(shè)定的溫度 */
/******************************************************************/
void keyscan()
{
uchar flag1=0,flag2=0;//有按鍵按下標(biāo)記
P3=0xff;//拉高P3口,以讀取P3口的值
if(key1==0) //兩個按鍵控制最高/最低溫度的加減 按住key1時通過其他2個鍵控制最高溫度的加減
{
delay(5);
if(key2==0)//最高溫加
{
delay(5);//延時消抖
if(key2==0)
{
temp_max++;
if(temp_max>=85)
temp_max=85;
}
while(!key2);//松手檢測
flag1=1;
}
if(key3==0)//最高溫減
{
delay(5);
if(key3==0)
{
temp_max--;
if(temp_max<=temp_min)
temp_max=temp_min;
}
while(!key3);
flag1=1;
}
}
if(key1==1) //松開key1時通過其他2個鍵控制最低溫度的加減
{
delay(5);
if(key2==0)//最低溫加
{
delay(5);//延時消抖
if(key2==0)
{
temp_min++;
if(temp_min>=temp_max)
temp_min=temp_max;
}
while(!key2);//松手檢測
flag2=1;
}
if(key3==0)//最低溫減
{
delay(5);
if(key3==0)
{
temp_min--;
if(temp_min<=-10)
temp_min=-10;
}
while(!key3);
flag2=1;
}
}
if(flag1)//如有設(shè)置最高溫度的鍵按下,更新設(shè)定的溫度
{
flag1=0;// 清標(biāo)記
display_range(0x0d,temp_max);
}
if(flag2)//如有設(shè)置最低溫度的鍵按下,更新設(shè)定的溫度
{
flag2=0;// 清標(biāo)記
display_range(0x04,temp_min);
}
}
/****************************************************************/
/* 主函數(shù) */
/******************************************************************/
void main()
{
TMOD|=0x01;//定時器設(shè)置
TH0=0xEF;//裝初始值
TL0=0xF0;
EA=1;// 開總中斷
ET0=1;//允許定時器0中斷
TR0=1;//開定時器0中斷
InitLcd();//lcd1602初始化
flag_get=1;
while(1)
{
handle_T();// 處理溫度:獲得、顯示、報警
keyscan(); //獨立按鍵掃描
}
}
/******************************************************************/
/* 定時0中斷處理程序,用于溫度檢測間隔,大約1秒測一次溫度 */
/******************************************************************/
void timer0(void) interrupt 1 using 1
{
TH0=0xEF;//定時器重裝值
TL0=0xF0;
num++;
if (num==50)
{
num=0;
flag_get=1;//標(biāo)志位有效,開始測溫
}
}
|
|