|
想知道為什么無法運行
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define delayNOP() {_nop_();_nop_();_nop_();_nop_();}
sbit HI_LED=P2^3; //高溫,低溫白凈閃爍 LED
sbit LO_LED=P2^6;
sbit DQ=P3^3; //DS18B20數據線
sbit BEEP=P3^7; //報警
sbit RS=P2^0;
sbit RW=P2^1;
sbit EN=P2^2;
sbit K1=P1^7; //正常顯示溫度,越界時報警
sbit K2=P1^4; //顯示報警溫度
sbit K3=P1^1; //查看 ROM CODE
uchar code RomCodeStr[]={"-- ROM CODE --"};
uchar RomCode[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //64位ROM CODE
uchar code Temp_Disp_Title[] ={"Current Temp: "};
uchar Current_Temp_Display_Buffer[]={"TEMPE: "};
uchar code Temperature_Char[8]={0x0c,0x12,0x12,0x0c,0x00,0x00,0x00,0x00}; //溫度示字符
uchar code Alarm_Temp[]={"ALARM TEMP Hi Lo"};
uchar Alarm_HI_LO_STR[]={"Hi: Lo: "};
uchar temp_data[2]={0x00,0x00};
uchar temp_alarm[2]={0x00,0x00};
uchar display[5]={0x00,0x00,0x00,0x00,0x00,}; //溫度值
uchar display1[3]={0x00,0x00,0x00}; //溫度報警值
uchar code df_Table[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9}; //溫度小數位對照表
//.......................................................
//報警溫度上下限(取值范圍:-128~+127)(DS18B20溫度范圍為:-55~+125)
//數組中前一位為高溫值,后一位為低溫值
//此處類型注意設為char,否則不能進行有符號數的比較
char Alarm_Temp_HL[2]={70,-20};
//............................................................
uchar CurrentT=0; //當前讀取溫度整數部分
uchar Temp_Value[]={0x00,0x00};//從DS18B20讀取的溫度值
uchar Display_Digit[]={0,0,0,0};//待顯示的各溫度數位
bit HI_Alarm=0,LO_Alarm=0; //高低溫報警標志
bit DS18B20_IS_OK=1; //傳感器正常標志
uint Time0_Count=0; //定時器延時累加
//...........................
//延時
//...........................
void DelayXus(int x)
{
uchar i;
while(x--)for(i=0;i<200;i++);
}
//.......................................
//忙檢測
bit LCD_Busy_Check()
{
bit LCD_Status;
RS=0;//寄存器選擇
RW=1;//讀狀態寄存器EN=1;//開始讀
DelayXus(1);
LCD_Status=(bit)(P0&0x80) ;
EN=0;
return LCD_Status;
}
//寫LCD指令
void Write_LCD_Command(uchar cmd)
{
while((LCD_Busy_Check()&0x80)==0x80); //忙等待
RS=0; //寫選擇命令寄存器
RW=0; //寫
EN=0;
P0=cmd; EN=1; DelayXus(1); EN=0;
}
//向LCD寫數據
void Write_LCD_Data(uchar dat)
{
while((LCD_Busy_Check()&0x80)==0x80); //忙等待
RS=1;RW=0;EN=0;P0=dat;EN=1; DelayXus(1); EN=0;
}
//設置液晶顯示位置
void Set_LCD_POS(uchar pos)
{
Write_LCD_Command(pos |0x80);
}
//LCD初始化
void LCD_Initialise()
{
Write_LCD_Command(0x38);
DelayXus(1);
Write_LCD_Command(0x01); //清屏
DelayXus(1);
Write_LCD_Command(0x06); //字符進入模式:屏幕不動,字符后移
DelayXus(1);
Write_LCD_Command(0x0C); //顯示開,關光標
DelayXus(1);
}
//...............................................
//..........................................
//自定義字符寫CGRAM
//..................................
void Write_NEW_LCD_Char()
{
uchar i;
Write_LCD_Command(0x40); //寫CGRAM
for(i=0;i<8;i++)
Write_LCD_Data(Temperature_Char[i]); //寫入溫度符號
}
//............................................
//延時
//........................................................
void Delay(uint num)
{
while(--num);
}
//...............................................
//初始化DS18B20
//...............................................
uchar Init_DS18B20()
{
uchar status;
DQ=1;Delay(8);
DQ=0;Delay(90);
DQ=1;Delay(8);
status=DQ;
Delay(100);
DQ=1;
return status; //初始化成功時返回0
}
//...............................................
//讀一節
//...............................................
uchar ReadOneByte()
{
uchar i,dat=0;
DQ=1;_nop_();
for(i=0;i<8;i++)
{
DQ=0;dat>>=1;DQ=1;_nop_(); _nop_();
if(DQ) dat |=0x80;Delay(30);DQ=1;
}
return dat;
}
//...............................................
//寫一字節
//...............................................
void WriteOneByte(uchar dat)
{
uchar i;
for(i=0;i<8;i++)
{
DQ=0;DQ=dat&0x01;Delay(5);DQ=1;dat>>=1;
}
}
//...............................................
//讀取溫度值
//...............................................
void Read_Temperature()
{
if(Init_DS18B20()==1) //DS18B20故障
DS18B20_IS_OK=0;
else
{
WriteOneByte(0xCC); //跳過序列號
WriteOneByte(0x44); //啟動溫度轉換
Init_DS18B20();
WriteOneByte(0xCC); //跳過序列號
WriteOneByte(0xBE); //讀取溫度寄存器
Temp_Value[0]=ReadOneByte(); //溫度低8位
Temp_Value[1]=ReadOneByte(); //溫度高8位
Alarm_Temp_HL[0]=ReadOneByte(); //報警溫度TH
Alarm_Temp_HL[1]=ReadOneByte(); //報警溫度TL
DS18B20_IS_OK=1;
}
}
//...............................................
//設置DS18B20溫度報警值
//...............................................
void Set_Alarm_Temp_Value()
{
Init_DS18B20();
WriteOneByte(0xCC); //跳過序列號
WriteOneByte(0x4E); //將設定的溫度報警值寫入DS18B20
WriteOneByte(Alarm_Temp_HL[0]); //寫TH
WriteOneByte(Alarm_Temp_HL[1]); //寫TL
WriteOneByte(0x7F); //12位精度
Init_DS18B20();
WriteOneByte(0xCC); //跳過序列號
WriteOneByte(0x48); //溫度報警值存入DS18B20
}
//......................................................
//在LCD上顯示當前溫度
//.....................................................
void Display_Temperature()
{
uchar i;
uchar t=150; //延時值
uchar ng=0; //負數標識
char Signed_Current_Temp;
//如果為負數則取反加1,并設置負數標識
if((Temp_Value[1]&0xF8)==0xF8)
{
Temp_Value[1]=~Temp_Value[1];
Temp_Value[0]=~Temp_Value[0]+1;
if(Temp_Value[0]==0x00) Temp_Value[1]++;
ng=1; //設負數標識
}
//查表得到溫度小數部分
Display_Digit[0]=df_Table[Temp_Value[0]&0x0F];
//獲取溫度整數部分(無符號)
CurrentT=((Temp_Value[0]&0xF0)>>4)|((Temp_Value[1]&0x07)<<4);
//有符號的當前溫度值,注意此處定義為char, 其值可為-128~+127
Signed_Current_Temp=ng?-CurrentT:CurrentT;
//高低溫報警標志設置(與定義為char類型的Alarm_Temp_HL比較,這樣可區分正負比較)
HI_Alarm=Signed_Current_Temp>=Alarm_Temp_HL[0]?1:0;
LO_Alarm=Signed_Current_Temp<=Alarm_Temp_HL[1]?1:0;
//將整數部分分解為三位待顯示數字
Display_Digit[3]=CurrentT/100;
Display_Digit[2]=CurrentT%100/10;
Display_Digit[1]=CurrentT%10;
//刷新LCD顯示緩沖
Current_Temp_Display_Buffer[11]=Display_Digit[0]+'0';
Current_Temp_Display_Buffer[10]='.';
Current_Temp_Display_Buffer[9]=Display_Digit[1]+'0';
Current_Temp_Display_Buffer[8]=Display_Digit[2]+'0';
Current_Temp_Display_Buffer[7]=Display_Digit[3]+'0';
//高位為0時不顯示
if(Display_Digit[3]==0) Current_Temp_Display_Buffer[7]=' ';
//高位為0且次高位為0時,次高位不顯示
if(Display_Digit[2]==0&&Display_Digit[3]==0)
Current_Temp_Display_Buffer[8]=' ';
//負數符號顯示恰當位置
if (ng)
{
if(Current_Temp_Display_Buffer[8]==' ')
Current_Temp_Display_Buffer[8]='_';
else
if(Current_Temp_Display_Buffer[7]==' ')
Current_Temp_Display_Buffer[7]='_';
else
Current_Temp_Display_Buffer[6]='_';
}
//在第一行顯示標題
Set_LCD_POS(0X00);
for(i=0;i<16;i++) Write_LCD_Data( Temp_Disp_Title[i]);
//在第二行顯示當前溫度
Set_LCD_POS(0X40);
for(i=0;i<16;i++) Write_LCD_Data(Current_Temp_Display_Buffer[i]);
//顯示溫度符號
Set_LCD_POS(0X4D);Write_LCD_Data(0x00);
Set_LCD_POS(0X4E);Write_LCD_Data('C');
}
//.....................................
//定時器中斷,控制報警聲音
//.................................
void T0_INT() interrupt 1
{
TH0=-1000/256;
TL0=-1000%256;
BEEP=!BEEP;
if(++Time0_Count==400)
{
Time0_Count=0;
if(HI_Alarm) HI_LED=~HI_LED; else HI_LED=0;
if(LO_Alarm) LO_LED=~LO_LED; else LO_LED=0;
TR0=0;
}
}
//...............................................
//ROM CODE轉換與顯示
//.....................................................
void Display_Rom_Code()
{
uchar i,t;
Set_LCD_POS(0x40);
for(i=0;i<8;i++)
{
t=((RomCode[i]&0xF0)>>4);
if(t>9) t+=0x37;else t+='0';
Write_LCD_Data(t); //高位數顯示
t=RomCode[i]&0x0F;
if(t>9) t+=0x37;else t+='0';
Write_LCD_Data(t); //低位數顯示
}
}
//..................................
//讀64位序列碼
//...............................
void Read_Rom_Code()
{
uchar i;
Init_DS18B20();
WriteOneByte(0x33); //讀序列碼
for (i=0;i<8;i++) RomCode[i]=ReadOneByte();
}
//.........................................
//顯示ROM CODE
//...............................
void Display_RomCode()
{
uchar i;
Set_LCD_POS(0x00);
for(i=0;i<16;i++) //顯示標題
Write_LCD_Data(RomCodeStr[i]);
Read_Rom_Code(); //讀64位序列碼
Display_Rom_Code(); //顯示64位ROM CODE
}
//.......................................
//顯示報警溫度
//...............................................
void Disp_Alarm_Temperature()
{
uchar i,ng;
//顯示Alarm_Temp_HL數組中的報警溫度值
//由于Alarm_Temp_HL類型為char,故可以直接進行正負比較
//高溫報警值.........................
ng=0;
if(Alarm_Temp_HL[0]<0) //如果為負數則取反加1
{
Alarm_Temp_HL[0]=~Alarm_Temp_HL[0]+1;
ng=1;
}
//分解高溫各數位到待顯示串中
Alarm_HI_LO_STR[4]=Alarm_Temp_HL[0]/100+'0';
Alarm_HI_LO_STR[5]=Alarm_Temp_HL[0]/10%10+'0';
Alarm_HI_LO_STR[6]=Alarm_Temp_HL[0]%10+'0';
//屏蔽高位不顯示的0
if(Alarm_HI_LO_STR[4]=='0') Alarm_HI_LO_STR[4]=' ';
if(Alarm_HI_LO_STR[4]==' '&& Alarm_HI_LO_STR[5]=='0')
Alarm_HI_LO_STR[5]=' ';
//"-"符號顯示
if (ng)
{
if (Alarm_HI_LO_STR[5]==' ') Alarm_HI_LO_STR[5]='-';
else
if(Alarm_HI_LO_STR[4]==' ') Alarm_HI_LO_STR[4]='-';
else
Alarm_HI_LO_STR[3]='-';
}
//低溫報警值
ng=0;
if(Alarm_Temp_HL[1]<0) //如果為負數則取反加1
{
Alarm_Temp_HL[1]=~Alarm_Temp_HL[1]+1;
ng=1;
}
//分解低溫各數位到待顯示串中
Alarm_HI_LO_STR[12]=Alarm_Temp_HL[1]/100+'0';
Alarm_HI_LO_STR[13]=Alarm_Temp_HL[0]/10%10+'0';
Alarm_HI_LO_STR[14]=Alarm_Temp_HL[0]%10+'0';
//屏蔽高位不顯示的0
if(Alarm_HI_LO_STR[12]=='0') Alarm_HI_LO_STR[12]=' ';
if(Alarm_HI_LO_STR[12]==' '&& Alarm_HI_LO_STR[13]=='0')
Alarm_HI_LO_STR[13]=' ';
//"-"符號顯示
if (ng)
{
if (Alarm_HI_LO_STR[13]==' ') Alarm_HI_LO_STR[13]='-';
else
if(Alarm_HI_LO_STR[12]==' ') Alarm_HI_LO_STR[12]='-';
else
Alarm_HI_LO_STR[11]='-';
}
//顯示高低溫報警溫度值
Set_LCD_POS(0x00); //顯示標題
for (i=0;i<16;i++) Write_LCD_Data(Alarm_Temp[i]);
Set_LCD_POS(0x40); //顯示高低溫
for (i=0;i<16;i++) Write_LCD_Data(Alarm_HI_LO_STR[i]);
}
//................................
//主函數
//..................................
void main()
{
uchar Current_Operation=1; //默認當前操作為顯示溫度
LCD_Initialise();
IE=0x82;
TMOD=0x01;
TH0=-1000/256;
TL0=-1000%256;
TR0=0;
HI_LED=0;
LO_LED=0;
Set_Alarm_Temp_Value();
Read_Temperature();
Delay(50000);
Delay(50000);
while(1)
{
if (K1==0) Current_Operation=1;
if (K2==0) Current_Operation=2;
if (K3==0) Current_Operation=3;
switch (Current_Operation)
{
case 1://正常顯示當前溫度,越界時報警
Read_Temperature();
if( DS18B20_IS_OK)
{
if (HI_Alarm==1 || LO_Alarm==1) TR0=1;
else TR0=0;
Display_Temperature();
}
DelayXus(100);
break;
case 2: //顯示報警溫度上下限
Read_Temperature();
Disp_Alarm_Temperature();
DelayXus(100);
break;
case 3: //顯示DS18B20 ROM CODE
Display_RomCode();
DelayXus(50);
break;
}
}
}
程序如上
|
-
-
fujian.zip
2019-2-21 18:46 上傳
點擊文件名下載附件
20.61 KB, 下載次數: 6
|