#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阳LED段码表
uchar code tab1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//含小数点共阳段码 0-9
char displayData[4];
uint shi,fen=9,miao=9,T50ms,tt;//时,分,秒,50ms
uchar bai,sh,ge,a,b,t;
sbit a0=P2^0;//连接P2.0
sbit a1=P2^1;//连接P2.1
sbit a2=P2^2;//连接P2.2
sbit a3=P2^3;//连接P2.3
sbit DQ=P3^7;//连接P3.7
/*void delay(uchar n)//延时5微秒函数
{
do{
_nop_();
_nop_();
_nop_();
n--;
}
while(n);
}*/
void delay(uint n)
{
while(n--);
}
void init() //初始化子程序
{
TMOD=0x01;//定时器T0为方式1
TH0=(65536-50000)/256;//采用方式1,并设置定时器初值,50ms
TL0=(65536-50000)%256;
ET0=1;//启动T0中断允许
EA=1;//总中断允许
TR0=1;//启动T0
EX0=1;//允许外部中断0中断
//PX0=1;//外部中断0高优先级中断
//PT0=1;//定时器T0中断高优先级中断
}
void scan()//扫描
{
displayData[0] = tab[miao%10];
displayData[1] = tab[(miao/10)%10];
displayData[2] = tab[fen%10]|0x80;
displayData[3] = tab[(fen/10)%10];
}
void display() //显示位数
{
char i;
for(i=0;i<=3;i++)
{
switch(i)
{
case 0:a0=0;a1=0;a2=0;a3=1;break;//显示第0位
case 1:a0=0;a1=0;a2=1;a3=0;break;//显示第1位
case 2:a0=0;a1=1;a2=0;a3=0;break;//显示第2位
case 3:a0=1;a1=0;a2=0;a3=0;break;//显示第3位
}
if(i==2){
P0=(displayData[i]&0x7f);//加小数点
}else
P0=displayData[i];//发送数据
delay(200); //间隔一段时间扫描
P0=0xff;//高电位清零
}
}
int_DS18b20()//对18b20初始化函数
{
uchar x=0;
DQ = 1; //DQ复位
delay(8);
DQ=0; //释放DQ
delay(80); //DS18B20收到信号后延时
DQ=1; //读取DQ
delay(10);
x=DQ;
delay(20);
return x;
}
void write_byte(uchar dat)//写时序
{
uchar i=0;
for(i=8;i>0;i--){
DQ=0;
DQ=dat&0x01;//写1,在15微秒内拉低
delay(5);//写0,拉低60微秒
DQ=1;
dat>>=1;//右移1位,原数值除以2
}
delay(4);
}
read_byte()//读时序
{
uchar i=0;
uchar dat=0;
for(i=8;i>0;i--){
DQ=0;//拉低ds18b20单总线
dat>>=1;
DQ=1;//15微秒内拉释放总线,等待ds18b20的存在脉冲
if(DQ)
dat|=0x80;
delay(4);
}
return (dat);
}
void int_()
{
while(int_DS18b20());
write_byte(0xcc);//发Skip ROM命令,由于只有一只DS18B20就不需要读取ROM编码以及匹配ROM编码
write_byte(0x44);//启动温度转换
}
void ReadTemperature()//读取温度的函数
{
uchar a=0;
unsigned b=0;
unsigned t=0;
int_();
delay(5);//延时,必要
int_DS18b20();
write_byte(0xCC);//跳过读写序列号
write_byte(0xBE);//读温度寄存器
delay(5);
a=read_byte();//读取温度
b=read_byte();
t=b<<4;//取高八位的后三位
t+=(a&0xf0)>>4;//低八位的高四位加上高八位中后三位的值
tt=a&0x0f;//小数位
sh=((b*256+a)>>4);//实际温度
ge=tt*0.0625*10;
}
void wenduxianshi()//温度显示的函数
{
a0=1;
P0=tab[sh/10];//百
delay(100);
a0=0;
a1=1;
P0=tab[sh%10]+0x80;//十位,+0x80可以显示小数点后一位
delay(100);
a1=0;
a2=1;
P0=tab[ge%10];//个位
delay(100);
a2=0;
a3=1;
P0=0xc6;// C
delay(100);
a3=0;
}
void main()//主函数
{
init();//初始化程序
while(1){
scan();//扫描
display();//显示
}
}
void timer0() interrupt 1//timer0中断服务子程序定是时间为50ms
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
T50ms++;
if(T50ms==20)//仿分钟
{
T50ms=0;
miao++;
if(miao>=60)
{
miao=miao-60;
fen++;
if(fen>=60)
{
fen=fen-60;
shi++;
}
}
}
}
void k4q8() interrupt 0//外部中断0
{
uint count=0;
while(1)
{
count++;
ReadTemperature();
wenduxianshi();
wenduxianshi();
if(k2=0)//隔一段时间返回时钟
{
miao=miao+4;
break;
}
}
}
这段程序的效果是 按下按键由时间模块切换到温度模块 4秒后自动切回时间模块。怎么修改能变成通过点击按键来回切换
|