标题:
51单片机通过18b20在数码管显示温度和时间程序,按键设置闹钟
[打印本页]
作者:
巴扎嘿
时间:
2022-1-26 11:40
标题:
51单片机通过18b20在数码管显示温度和时间程序,按键设置闹钟
#include "reg52.h"
unsigned int hour = 2, min = 2, sec = 3; //设置时间初值
unsigned int ahour = 0, amin = 0, asec = 0; //设置闹钟初值
sbit k1 = P3^1; //修改时间
sbit k2 = P3^0; //设置闹钟
sbit k3 = P3^2; //加1
sbit k4 = P3^3; //减1
sbit DSPORT=P3^7;
sbit beep=P1^5;
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
unsigned int keyvalue = 0;
unsigned int settype = 0; //0是初始状态正常显示,1是修改秒,2是修改分,3是修改时
unsigned int alarmvalue = 0; //0是初始状态,1是修改秒,2是修改分,3是修改时
unsigned char Show[8] = {0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f};
unsigned char code TableCC[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
int b = 0;
float tp=0;
int temp=0;
int c1=0;c2=0;
void delay(unsigned char i)
{
while(i--);
}
void delay_us(unsigned char t)
{
while(--t);
}
void delay_ms(unsigned int t) //t最大为255
{
while(t--)
{
delay_us(245);
delay_us(245);
}
}
unsigned char Ds18b20Init() //Ds18b20Init初始化
{
unsigned int i;
DSPORT=0; //将总线拉低480us~960us
i=70;
while(i--);//延时642us
DSPORT=1; //然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
i=0;
while(DSPORT) //等待DS18B20拉低总线
{
i++;
if(i>5000)//等待>5MS
return 0;//初始化失败
}
return 1;//初始化成功
}
void Ds18b20WriteByte(unsigned char dat) //Ds18b20WriteByte 向18B20写入一个字节
{
unsigned int i,j;
for(j=0;j<8;j++)
{
DSPORT=0; //每写入一位数据之前先把总线拉低1us
i++;
DSPORT=dat&0x01; //然后写入一个数据,从最低位开始
i=6;
while(i--); //延时68us,持续时间最少60us
DSPORT=1; //然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值
dat>>=1;
}
}
unsigned char Ds18b20ReadByte() //向18B20读取一个字节
{
unsigned char byte,bi;
unsigned int i,j;
for(j=8;j>0;j--)
{
DSPORT=0;//先将总线拉低1us
i++;
DSPORT=1;//然后释放总线
i++;
i++;//延时6us等待数据稳定
bi=DSPORT; //读取数据,从最低位开始读取
/*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。*/
byte=(byte>>1)|(bi<<7);
i=4; //读取完之后等待48us再接着读取下一个数
while(i--);
}
return byte;
}
void Ds18b20ChangTemp() //让18B20转换温度
{
Ds18b20Init();
delay_ms(1);
Ds18b20WriteByte(0xcc); //跳过ROM操作命令
Ds18b20WriteByte(0x44); //温度转换命令
}
void Ds18b20ReadTempCom() //让18B20 读取温度
{
Ds18b20Init();
delay_ms(1);
Ds18b20WriteByte(0xcc); //跳过ROM操作命令
Ds18b20WriteByte(0xbe); //发送读取温度命令
}
int Ds18b20ReadTemp() //读取温度返回数值
{
int temp=0;
unsigned char tmh,tml;
Ds18b20ChangTemp(); //先写入转换命令
Ds18b20ReadTempCom(); //然后等待转换完后发送读取温度命令
tml=Ds18b20ReadByte(); //读取温度值共16位,先读低字节
tmh=Ds18b20ReadByte(); //再读高字节
temp=tmh;
temp<<=8;
temp|=tml;
return temp;
}
void wendu_shuji()
{
temp=Ds18b20ReadTemp();
tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
temp=tp*0.0625*100+0.5;
c1 = temp % 10000 / 1000;
c2 = temp % 1000 / 100;
Show[7]=TableCC[c1];
Show[6]=TableCC[c2];
}
void Timer0_Init() //定时器初始化
{
TMOD |= 0x01; //选择为定时器0模式,工作方式1,仅用TR0打开启动。
TH0 =(65536 - 50000)/256; //给定时器赋初值
TL0 =(65536 - 50000)%256;
TR0=1;//打开定时器
ET0=1;//打开定时器0中断允许
EA=1;//打开总中断
}
void TimeTim() //时钟正常走
{
if(settype == 0 && alarmvalue == 0) //当不在闹钟状态也不在修改时间状态的时候时间正常走
{
if(b>=20)
{
b=0;
sec++;
if(sec == 60)
{
sec = 0;
min++;
if(min == 60)
{
min = 0;
hour++;
if(hour == 24)
{
hour = 0;
}
}
}
}
}
}
void bsp_CheckAlarm(void) //检查时间是否到了闹钟时间
{
unsigned char a=0;
if((hour == ahour) && (min == amin) && (sec == asec))
{
while(1)
{
beep=~beep;
delay_us(100);
if(k1 == 0)//K1按键被按下
{
delay(1000);
if(k1 == 0)
{
beep=0;
a=1;
}
while(!k1);//等待按键释放
}
if(a == 1)
{
break;
}
}
}
}
void bsp_KeyScan(void) //扫描键盘那个键被按下
{
if(k1 == 0)//K1按键被按下
{
delay(1000);
if(k1==0)
{
keyvalue = 1;
}
while(!k1);//等待按键释放
}
if(k2 == 0)
{
delay(1000);
if(k2==0)
{
keyvalue = 2;
}
while(!k2);
}
if(k3 == 0)
{
delay(1000);
if(k3==0)
{
keyvalue = 3;
}
while(!k3);
}
if(k4 == 0)
{
delay(1000);
if(k4==0)
{
keyvalue = 4;
}
while(!k4);
}
}
void timeadd() //时间加1
{
if(settype == 1)
{
if(sec < 59)
{
sec++;
}
else
{
sec = 0;
}
}
else if(settype == 2)
{
if(min < 59)
{
min++;
}
else
{
min = 0;
}
}
else if(settype == 3)
{
if(hour < 23)
{
hour++;
}
else
{
hour = 0;
}
}
if(alarmvalue == 1) //设置闹钟加1
{
if(asec < 59)
{
asec++;
}
else
{
asec = 0;
}
}
else if(alarmvalue == 2)
{
if(amin < 59)
{
amin++;
}
else
{
amin = 0;
}
}
else if(alarmvalue == 3)
{
if(ahour < 23)
{
ahour++;
}
else
{
ahour = 0;
}
}
}
void timedec() //时间减一
{
if(settype == 1)
{
if(sec > 0)
{
sec--;
}
else
{
sec = 59;
}
}
else if(settype == 2)
{
if(min > 0)
{
min--;
}
else
{
min = 59;
}
}
else if(settype == 3)
{
if(hour > 0)
{
hour--;
}
else
{
hour = 23;
}
}
if(alarmvalue == 1) //设置闹钟减1
{
if(asec > 0)
{
asec--;
}
else
{
asec = 59;
}
}
else if(alarmvalue == 2)
{
if(amin > 0)
{
amin--;
}
else
{
amin = 59;
}
}
else if(alarmvalue == 3)
{
if(ahour > 0)
{
ahour--;
}
else
{
ahour = 23;
}
}
}
void bsp_KeyProc(unsigned char keyv)
{
if(keyv == 1)
{
settype++;
if(settype == 4)
{
settype = 0;
}
keyvalue = 0; //键值要清0!!!
}
if(keyv == 2)
{
alarmvalue++;
if(alarmvalue == 4)
{
alarmvalue = 0;
}
keyvalue = 0;
}
if(keyv == 3)
{
timeadd();
keyvalue = 0;
}
if(keyv == 4)
{
timedec();
keyvalue = 0;
}
}
void SetValueShow(void)
{
if(alarmvalue == 0) //当不在闹钟状态时数码管显示正常的时间
{
Show[5] = TableCC[hour/10];
if(settype == 3)
Show[4] = TableCC[hour%10] | 0x80;
else
Show[4] = TableCC[hour%10];
Show[3] = TableCC[min/10];
if(settype == 2)
Show[2] = TableCC[min%10] | 0x80;
else
Show[2] = TableCC[min%10];
Show[1] = TableCC[sec/10];
if(settype == 1)
Show[0] = TableCC[sec%10] | 0x80;
else
Show[0] = TableCC[sec%10];
}
//在闹钟状态数码管显示闹钟设置的时间
else
{
Show[5] = TableCC[ahour/10];
if(alarmvalue == 3)
Show[4] = TableCC[ahour%10] | 0x80;
else
Show[4] = TableCC[ahour%10];
Show[3] = TableCC[amin/10];
if(alarmvalue == 2)
Show[2] = TableCC[amin%10] | 0x80;
else
Show[2] = TableCC[amin%10];
Show[1] = TableCC[asec/10];
if(alarmvalue == 1)
Show[0] = TableCC[asec%10] | 0x80;
else
Show[0] = TableCC[asec%10];
}
}
void DigDisplay()
{
int i;
for(i=0;i<8;i++)
{
switch(i) //位选,选择点亮的数码管,
{
case(0):
LSA=0;LSB=0;LSC=0; break;//显示第0位
case(1):
LSA=1;LSB=0;LSC=0; break;//显示第1位
case(2):
LSA=0;LSB=1;LSC=0; break;//显示第2位
case(3):
LSA=1;LSB=1;LSC=0; break;//显示第3位
case(4):
LSA=0;LSB=0;LSC=1; break;//显示第4位
case(5):
LSA=1;LSB=0;LSC=1; break;//显示第5位
case(6):
LSA=0;LSB=1;LSC=1; break;//显示第6位
case(7):
LSA=1;LSB=1;LSC=1; break;//显示第7位
}
P0=Show[i];//发送段码
delay(100); //间隔一段时间扫描
P0=0x00;//消隐
}
}
void main()
{
k1=1;
k2=1;
k3=1;
k4=1;
Timer0_Init(); //计时器的初始化
while(1)
{
wendu_shuji(); //温度
TimeTim(); //正常时间在走
bsp_KeyScan(); //键盘扫描看哪个功能键被按下
bsp_KeyProc(keyvalue); //根据键值进行相应的功能处理
SetValueShow(); //数码管上显示的值
DigDisplay(); //显示在数码管上
bsp_CheckAlarm(); //闹钟检查
}
}
void Timer0(void) interrupt 1 //定时器的中断服务程序
{
TH0 = (65536 - 50000)/256;
TL0 = (65536 - 50000)%256;
b++;
}
复制代码
Keil代码下载:
最终.rar
(26.26 KB, 下载次数: 16)
2022-1-26 11:40 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1