IOP3.1低电平就执行if后语句,让他显示上限温度值,怎么一按按键,4位数码管就不显示了
我用proteus也仿真出来了。。电路我觉得没问题,也检查了好几遍。我做的是温度传感器,功能是显示温度 通过三个按键来控制温度上下限值,然后检测 如果超出则报警。。它能够显示温度,但是不能够通过按键和中断来调整上下限温度值。。请高手指教。我是学生,菜鸟,也没有财富值。。但请您看在我是学生的份上就帮帮我吧,好人一定好报。。急!!!!送上电路图 和仿真图 还有程序代码。。
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
bit f_biao ; //当显示上下限温度时的闪烁间隔
sbit DQ=P3^7; //ds18b20数据端
sbit SET=P3^1; //显示上下限温度
sbit DEC=P3^2; //调整上下限温度,使上下限温度减少
sbit ADD=P3^3 ; //使上下限温度增加
sbit BEEP=P1^4; //蜂鸣器
sbit LIGHT=P1^5; //报警灯
sbit dp=P2^7;
uchar x; //计数值
uchar anci ; //按下SET键的次数
uchar m; //温度值
uchar n; //温度值
uchar h=35;
uchar l=27; //上下限温度值
uchar code led[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
void delay(uint num)
{
while(num--);
}
void initds18b20() //初始化ds18b20
{
uchar g=0;
P2=0x00;
DQ=1;
delay(8);
DQ=0;
delay(80);
DQ=1;
delay(14);
g=DQ;
delay(20);
}
void inittimer0(void) //初始化定时器0
{
TMOD=01;
TH0=0x3c;
TL0=0xb0;
}
void timer0(void) interrupt 1 //定时器0服务子程序
{
TH0=0x3c;
TL0=0xb0;
x++;
}
void int0(void) interrupt 0 //外部中断0服务子程序
{
EX0=0; //关外部中断0
if(DEC==0&&(anci==1||anci==2))
{
delay(200); //延时去抖
if(DEC==0&&anci==1)
{
h--;
if(h<l)
h=l;
}
else if(DEC==0&&anci==2)
{
l--;
if(l<0)
l=0;
}
}
}
void int1(void) interrupt 2 //外部中断1服务子程序
{
EX1=0 ; //关外部中断1
if(ADD==0&&(anci==1||anci==2))
{
delay(210) ;
if(ADD==0&&anci==1)
{
h++;
if(h>99)
h=99;
}
else if(ADD==0&&anci==2)
{
l++;
if(l>h)
l=h;
}
}
}
void writeonechar(uchar dat) //写一个字节
{
uchar i;
for(i=0;i<8;i++)
{
DQ=0;
DQ=dat&0x01;
delay(8);
DQ=1;
dat>>=1;
}
}
unsigned char readonechar(void) //读一个字节
{
uchar j;
uchar dat=0;
for(j=0;j<8;j++)
{
DQ=0;
dat>>=1;
DQ=1;
if(DQ==1)
dat=dat|0x80;
delay(4);
}
return(dat);
}
unsigned int readtemperature() //读取温度
{
uchar a=0;
uchar b=0;
uint t=0;
float tt=0; //初始化ds18b20
initds18b20();
writeonechar(0xcc); // 跳过读序列号操作
writeonechar(0x44); //启动温度转换
initds18b20();
writeonechar(0xcc);
writeonechar(0xbe); //读取温度寄存器
a=readonechar();
b=readonechar();
t=b;
t<<=8;
t=t|a;
tt=t*0.0625 ; //得到真正的温度值
t=tt*10+0.5; //放大10倍,便于显示
return(t);
}
void checktemperature() //检测温度
{
uint a,b,c;
c=readtemperature()-5 ; //温度误差
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 dis_init() //显示开机画面,当开机时所有的数码管都显示1
{
P2=0x06; //显示1
P0=0xfe;
delay(200); //为数码管动态显示
P0=0xfd;
delay(200);
P0=0xfb;
delay(200);
P0=0xf7;
delay(200);
P0=0xff;
}
void disp_temperature()
{
P0=0xf7;
P2=0x39; //显示C
delay(200);
P0=0xfb;
P2=led[n]; //显示小数位
delay(200);
P0=0xfd;
P2=led[m%10]; //显示个位
dp=1; //显示小数点
delay(200);
P0=0xfe;
P2=led[m/10]; //显示十位
delay(200);
P0=0xff;
}
void disp_alarm(uchar warnning) //显示上下限温度警告值
{
P0=0xf7; //显示C
P2=0x39;
delay(200) ;
P0=0xfb; //小数位
P2=led[warnning%10];
delay(200);
P0=0xfd;
P2=led[warnning/10]; //十位
delay(200);
if(anci==1)
{
P0=0xfe; //显示H 上限
P2=0x76;
delay(200);
}
if(anci==2)
{
P0=0xfe;
P2=0x38;
delay(200); //显示L 下限
}
P0=0xff;
}
void alarm() //报警子程序
{
if(l<m&&m<h)
{
BEEP=1;
LIGHT=1;
}
else if(m<=l||m>=h)
{
BEEP=0;
LIGHT=0;
}
}
void main()
{
uchar z;
inittimer0();
EA=1; //开总中断
TR0=1; //启动定时器0,开始计数
ET0=1; //开启定时器0中断允许
IT0=1; //外部中断0为跳变沿触发
IT1=1;
checktemperature();
for(z=100;z>0;z--)
{
dis_init();
}
while(1)
{
if(SET==0)
{
delay(200); //延时去抖
do{}while(SET==0); //先执行{}一次再判断(条件)如果为真则执行,如果一直按着,则循环下去
anci++;
x=0;
f_biao=1;
if(anci>2)
anci=0;
}
if(anci==0)
{
EX0=0; //关中断
EX1=0;
checktemperature(); //检测温度
disp_temperature(); //显示温度
alarm(); //报警检测
}
if(anci==1)
{
EX0=1; //开中断
EX1=1;
BEEP=1;
LIGHT=1;
if(x>10)
{
f_biao=~f_biao;
x=0;
}
if(f_biao)
{
disp_alarm(h); //按一次 显示上限温度
}
}
if(anci==2)
{
BEEP=1;
LIGHT=1;
EX0=1;
EX1=1;
if(x>10)
{
f_biao=~f_biao;
x=0;
}
if(f_biao)
{
disp_alarm(l); //按两次显示下限温度
}
}
}
}
/****THE END*****/
//成功啦!!!!!!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
do{}while(SET==0);
当SET=0的时候,程序在此死循环,自然不会往下执行disp_temperature();
程序中的多处地方要注意加括号,比如:
if(DEC==0&&(anci==1||anci==2))
应当写成
if((DEC==0)&&((anci==1)||(anci==2)))
很高兴你能指教,但我还有很多问题不懂。。为什么我用该程序能够仿真的出来了呢?还有这个do{}while(set==0)语句不是要该按键按下去SET==0才会是低电平的吗?他才执行{}里语句,也只有我按下去的时候才为低电平啊,我不按就为高电平了 他就不满足while()后的条件 不是就跳出这个语句了吗?好像不可能在这死循环啊。。。不解,还需高人点拨才行。。
这个因不是问题吧,第一个键我就没有用中断处理啊。。问题不在这里。。谢谢
仿真软件是不可尽信的
的确如楼主所说:SET==0,他才执行{}里语句,
但是如果不放开,SET仍是0,将会再次执行{}里语句,
所以说会有"一按按键,4位数码管就不显示"的现像.
不知是不是我的误解,楼主的意思难道是按下按键后,数码管不显示,放开按键后,数码管仍然不显示?
嗯 解决了 多亏了你,我往三个按键加了三个上拉电阻就可以了,最初我以为我一按按键就为低电平,放开就为高电平了
一周热门 更多>