因为是看了许多的视频代码学习的 有很多可能都是重复定义 在仿真上已经能实现在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; //设置状态
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);
}
/*****读一个字节*****/
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);
}
/*****写一个字节*****/
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数据左移8位
t=t|a; //将t和a按位或,得到一个16位的数
tt=t*0.0625; //将t乘以0.0625得到实际温度值(温度传感器设置12位精度,最小分辨率是0.0625)
t= tt*10.0+0.5; //放大10倍(将小数点后一位显示出来)输出并四舍五入
return t; //返回温度值
}
/*****读取温度*****/
void check_wendu(void)
{
unsigned int a,b,c;
c=ReadTemperature(); //获取温度值
a=c/100; //计算得到十位数字
b=c/10-a*10; //计算得到个位数字
m=c/10; //计算得到整数位
n=c-a*100-b*10; //计算得到小数位
if(m<0){m=0;n=0;} //设置温度显示上限
if(m>99){m=99;n=9;} //设置温度显示上限
}
//延迟函数
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;
}
//准备写数据
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;
}
}
|