因為是看了許多的視頻代碼學習的 有很多可能都是重復定義 在仿真上已經(jīng)能實現(xiàn)在lcd1602顯示 溫度 警報上限下限 但是使用外部中斷時僅能使用溫度上下限減少 不能使用另一個 希望能有大佬指點一下
而且在仿真上 也是延遲了很久才顯示
#include"reg52.h"
#include"intrins.h"
sbit RS=P3^0;
sbit RW=P3^1;
sbit E=P3^2;
sbit BF=P2^7;
sbit DQ=P3^7;
sbit SET=P1^3;
sbit ADD=P1^4;
sbit DEC=P1^5;
sbit BEEP=P3^6;
sbit ALAM=P1^2;
signed char shangxian=28; //上限報警溫度,默認值為28
signed char xiaxian=22; //下限報警溫度,默認值為22
bit shanshuo_st;
bit beep_st; //蜂鳴器
unsigned x=0;
unsigned set_st=0; //設置狀態(tài)
signed char m; //溫度值全局變量
signed char n; //溫度值全局變量
/*****延時子程序*****/
void Delay_DS18B20(int num)
{
while(num--) ;
}
/*****初始化DS18B20*****/
void Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ復位
Delay_DS18B20(8); //稍做延時
DQ = 0; //單片機將DQ拉低
Delay_DS18B20(80); //精確延時,大于480us
DQ = 1; //拉高總線
Delay_DS18B20(14);
x = DQ; //稍做延時后,如果x=0則初始化成功,x=1則初始化失敗
Delay_DS18B20(20);
}
/*****讀一個字節(jié)*****/
unsigned char ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 給脈沖信號
dat>>=1;
DQ = 1; // 給脈沖信號
if(DQ)
dat|=0x80;
Delay_DS18B20(4);
}
return(dat);
}
/*****寫一個字節(jié)*****/
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
Delay_DS18B20(5);
DQ = 1;
dat>>=1;
}
}
/*****讀取溫度*****/
unsigned int ReadTemperature(void)
{
unsigned char a=0;
unsigned char b=0;
unsigned int t=0;
float tt=0;
Init_DS18B20();
WriteOneChar(0xCC); //跳過讀序號列號的操作
WriteOneChar(0x44); //啟動溫度轉換
Init_DS18B20();
WriteOneChar(0xCC); //跳過讀序號列號的操作
WriteOneChar(0xBE); //讀取溫度寄存器
a=ReadOneChar(); //讀低8位
b=ReadOneChar(); //讀高8位
t=b; //高8位轉移到t
t<<=8; //t數(shù)據(jù)左移8位
t=t|a; //將t和a按位或,得到一個16位的數(shù)
tt=t*0.0625; //將t乘以0.0625得到實際溫度值(溫度傳感器設置12位精度,最小分辨率是0.0625)
t= tt*10.0+0.5; //放大10倍(將小數(shù)點后一位顯示出來)輸出并四舍五入
return t; //返回溫度值
}
/*****讀取溫度*****/
void check_wendu(void)
{
unsigned int a,b,c;
c=ReadTemperature(); //獲取溫度值
a=c/100; //計算得到十位數(shù)字
b=c/10-a*10; //計算得到個位數(shù)字
m=c/10; //計算得到整數(shù)位
n=c-a*100-b*10; //計算得到小數(shù)位
if(m<0){m=0;n=0;} //設置溫度顯示上限
if(m>99){m=99;n=9;} //設置溫度顯示上限
}
//延遲函數(shù)
void delay1ms()
{
unsigned char i,j;
for(i=1;i<10;i++)
for(j=0;j<33;j++)
;
}
//延遲 n ms
void delay(unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++)
delay1ms();
}
//忙信號 result=1 忙 反之
unsigned char BusyTest(void)
{
bit result;
RS=0;
RW=1;
E=1;
_nop_();
_nop_();
_nop_();
_nop_();
result=BF;
E=0;
return result;
}
//準備寫數(shù)據(jù)
void WriteInstruction (unsigned char dictate)
{
while(BusyTest()==1);
RS=0;
RW=0;
E=0;
_nop_();
_nop_();
P2=dictate;
_nop_();
_nop_();
_nop_();
_nop_();
E=1;
_nop_();
_nop_();
_nop_();
_nop_();
E=0;
}
//
void WriteAddress(unsigned char x)
{
WriteInstruction (x|0x80);
}
//
void WriteDate (unsigned char y)
{
while(BusyTest()==1);
RS=1;
RW=0;
E=0;
P2=y;
_nop_();
_nop_();
_nop_();
_nop_();
E=1;
_nop_();
_nop_();
_nop_();
_nop_();
E=0;
}
//
void LcdInitiate(void)
{
delay(15);
WriteInstruction(0x38);
delay(5);
WriteInstruction(0x0c);
delay(5);
WriteInstruction(0x06);
delay(5);
WriteInstruction(0x01);
delay(5);
WriteInstruction(0x80);
delay(5);
}
/*****報警子程序*****/
void Alarm()
{
if(x>=10){beep_st=~beep_st;x=0;}
if((m>=shangxian&&beep_st==1)||(m<xiaxian&&beep_st==1))
{
BEEP=0;
ALAM=0;
}
else
{
BEEP=1;
ALAM=1;
}
}
void display(void)
{
unsigned int m=ReadTemperature();
unsigned char shi,ge,dian;
unsigned char shangshi,shangge,xiashi,xiage;
shi=m/100;
ge=m/10%10;
dian=m%10;
shangshi=shangxian/10;
shangge=shangxian%10;
xiashi=xiaxian/10;
xiage=xiaxian%10;
LcdInitiate();
WriteAddress(0x00);
WriteDate('T');
WriteAddress(0x01);
WriteDate('e');
WriteAddress(0x02);
WriteDate('m');
WriteAddress(0x03);
WriteDate('p');
WriteAddress(0x04);
WriteDate(':');
WriteAddress(0x05);
WriteDate(48+shi);
WriteAddress(0x06);
WriteDate(48+ge);
WriteAddress(0x07);
WriteDate('.');
WriteAddress(0x08);
WriteDate(48+dian);
WriteAddress(0x0A);
WriteDate('H');
WriteAddress(0x0B);
WriteDate(48+shangshi);
WriteAddress(0x0C);
WriteDate(48+shangge);
WriteAddress(0x0D);
WriteDate('L');
WriteAddress(0x0E);
WriteDate(48+xiashi);
WriteAddress(0x0F);
WriteDate(48+xiage);
}
/*****初始化定時器0*****/
void InitTimer(void)
{
TMOD=0x1;
TH0=0x3c;
TL0=0xb0; //50ms(晶振12M)
}
void main(void)
{
unsigned int z;
InitTimer(); //初始化定時器
EA=1; //全局中斷開關
TR0=1;
ET0=1; //開啟定時器0
IT0=1;
IT1=1;
check_wendu();
check_wendu();
for(z=0;z<300;z++)
{
LcdInitiate();
}
while(1)
{
if(SET==0)
{
delay(2000);
do{}while(SET==0);
set_st++;x=0;shanshuo_st=1;
if(set_st>2)set_st=0;
}
if(set_st==0)
{
EX0=0; //關閉外部中斷0
EX1=0; //關閉外部中斷1
check_wendu();
display();
Alarm(); //報警檢測
}
else if(set_st==1)
{
BEEP=1; //關閉蜂鳴器
ALAM=1;
EX0=1; //開啟外部中斷0
EX1=1; //開啟外部中斷1
if(x>=10){shanshuo_st=~shanshuo_st;x=0;}
if(shanshuo_st) {display();}
}
else if(set_st==2)
{
BEEP=1; //關閉蜂鳴器
ALAM=1;
EX0=1; //開啟外部中斷0
EX1=1; //開啟外部中斷1
if(x>=10){shanshuo_st=~shanshuo_st;x=0;}
if(shanshuo_st) {display();}
}
}
}
/*****定時器0中斷服務程序*****/
void timer0(void) interrupt 1
{
TH0=0x3c;
TL0=0xb0;
x++;
}
/*****外部中斷0服務程序*****/
void int0(void) interrupt 0
{
//關外部中斷0
if(DEC==0&&set_st==1)
{
do{
display();
}
while(DEC==0);
shangxian--;
if(shangxian<xiaxian)shangxian=xiaxian;
}
else if(DEC==0&&set_st==2)
{
do{
display();
}
while(DEC==0);
xiaxian--;
if(xiaxian<0)xiaxian=0;
}
}
/*****外部中斷1服務程序*****/
void int1(void) interrupt 2
{
//關外部中斷1
if(ADD==0&&set_st==1)
{
do{
display();
}
while(ADD==0);
shangxian++;
if(shangxian>99)shangxian=99;
}
else if(ADD==0&&set_st==2)
{
do{
display();
}
while(ADD==0);
xiaxian++;
if(xiaxian>shangxian)xiaxian=shangxian;
}
}
|