#include <stc15.h>
#include <intrins.h>
#include "ds1302.h"
#include "onewire.h"
unsigned char a[19]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,
0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,0x7f,0xbf,0xff};
unsigned char b[8]={0};
unsigned char s,f,m,s1,f1,m1,ns,nf,nm;
unsigned char i=0;
bit S7=0;//S7初始化为0
unsigned char S6=0;
bit n=0;
unsigned char temp2;
unsigned int count=0;//用于数码管延时
unsigned int count2=0;//用于闹钟延时
unsigned int wendu,count3=0;//用于温度延时
bit wen=0;
void BUZZ() //初始化
{
P2=(P2&0x1f)|0x80;
P0=0xff;
P2=(P2&0x1f)|0xa0;
P0=0x00;
P2=(P2&0x1f)|0xc0;
P0=0xff;
P2=(P2&0x1f)|0xe0;
P0=0xff;
}
void Timer0Init(void) //1毫秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xCD; //设置定时初值
TH0 = 0xD4; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1;
EA = 1;
}
void SMGchuxian()//数码管初显
{
s1=Read_Ds1302_Byte(0x85);
f1=Read_Ds1302_Byte(0x83);
m1=Read_Ds1302_Byte(0x81);
s=s1/16*10+s1%16;
f=f1/16*10+f1%16;
m=m1/16*10+m1%16;
b[0]=s/10;
b[1]=s%10;
b[2]=17;
b[3]=f/10;
b[4]=f%10;
b[5]=17;
b[6]=m/10;
b[7]=m%10;
}
void SMGxianshi()//数码管显示 段选 位选
{
static int i=0;
P2=(P2&0x1f)|0xc0;
P0=0x01<<i;
P2&=0x1f;
P2=(P2&0x1f)|0xe0;
P0=a[b[i]];
P2&=0x1f;
i=(i+1)%8;
}
void naozhong()//闹钟
{
b[0]=ns/10;
b[1]=ns%10;
b[2]=17;
b[3]=nf/10;
b[4]=nf%10;
b[5]=17;
b[6]=nm/10;
b[7]=nm%10;
}
void SMGshanshuo()//数码管闪烁
{
b[i]=18;//实现两个数码管同时闪灭
b[i+1]=18;
}
void Delay30ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 2;
j = 67;
k = 183;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Keys() //独立按键
{
if(P30==0)//时钟显示按键
{
Delay30ms();//消抖
if(P30==0)
{
n=0;
if(S7==0)S7=1;
else if(S7==1)
{
i+=3;
if(i>6)
{
i=0;
S7=0;
}
}
}
}
while(P30==0);//判断是否只摁下一次
//
if(P31==0)//闹钟显示按键
{
Delay30ms();//消抖
if(P31==0)
{
n=1;
if(S6==0)S6=1;
else if(S6==1)
{
S6=2;
}
else if(S6==2)
{
i+=3;
if(i>6)
{
i=0;
S6=0;
}
}
}
}
while(P31==0);//判断是否只摁下一次
//
if(n==0&&S7==0)
{
if(P33==0)
{
wen=1;
while(P33==0);
wen=0;
}
}
//
if(P32==0)//时钟加
{
Delay30ms();
if(P32==0)
{
if(S7==1&&i==0)
{
s++;
s=s%24;
time(s,f,m);
}
else if(i==3)
{
f++;
f=f%60;
time(s,f,m);
}
else if(i==6)
{
m++;
m=m%60;
time(s,f,m);
}
}
}while(P32==0);
//
if(P33==0)//时钟减
{
Delay30ms();
if(P33==0)
{
if(S7==1&&i==0)
{
s--;
time(s,f,m);
if(s<0)
{
s=0;
}
}
if(S7==1&&i==3)
{
f--;
time(s,f,m);
if(f<0)
{
f=0;
}
}
if(S7==1&&i==6)
{
m--;
time(s,f,m);
if(m<0)
{
m=0;
}
}
}
}while(P33==0);
//
if(P32==0)//闹钟加
{
Delay30ms();
if(P32==0)
{
if(S6==2&&i==0)
{
ns++;
ns=ns%24;
}
else if(S6==2&&i==3)
{
nf++;
nf=nf%60;
}
else if(S6==2&&i==6)
{
nm++;
nm=nm%60;
}
}
}while(P32==0);
//
if(P33==0)//闹钟减
{
Delay30ms();
if(P33==0)
{
if(S6==2&&i==0)
{
ns--;
if(ns<0)
{
ns=0;
}
}
if(S6==2&&i==3)
{
nf--;
if(nf<0)
{
nf=0;
}
}
if(S6==2&&i==6)
{
nm--;
if(nm<0)
{
nm=0;
}
}
}
}while(P33==0);
//
}
unsigned int ds18b2_Read()
{
unsigned int wendu;
EA=0;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
wendu= Read_DS18B20();
wendu |= (Read_DS18B20()<<8);
wendu *=6.25;
EA=1;
return wendu;
}
void Display_wendu()
{
b[0]=18;
b[1]=18;
b[2]=18;
b[3]=18;
b[4]=18;
b[5]=wendu/1000;
b[6]=wendu/100%10;
b[7]=12;
}
void ServiceTimer0() interrupt 1
{
if(wen==0)
{
if(n==0)
{
if(S7==0)//初始化状态下闪烁
{
SMGchuxian();
SMGxianshi();//初始界面不闪现闪烁
}
else//S7被摁下 进入闪烁
{
count++;//之前定时器定义了1毫秒
if(count<=500)
{
SMGchuxian();
SMGxianshi();//当S7被摁下 500毫秒前还是原来的不闪烁
}
else if(count>500&&count<=1000)//实现500-1000的熄灭 从而实现闪烁效果
{
SMGxianshi();
SMGshanshuo();//熄灭
}
else if(count>1000)count=0;
}
}
//
if(n==1)
{
if(S6==0)//初始化状态下闪烁
{
naozhong();
SMGxianshi();//初始界面不闪现闪烁
}
if(S6==1)//初始化状态下闪烁
{
naozhong();
SMGxianshi();//初始界面不闪现闪烁
}
if(S6==2)
{
count2++;
if(count2<=500)
{
SMGxianshi();
naozhong();
}
else if(count2>500&&count2<=1000)
{
SMGxianshi();
SMGshanshuo();//熄灭
}
else if(count2>1000)count2=0;
}
}
}
//
if(wen==1)
{
SMGxianshi();
Display_wendu();
count3++;
if(count3%500==0)
wendu=ds18b2_Read();
}
}
void main()
{
BUZZ();
Timer0Init();
time(23,59,50);
while(1)
{
Keys();
}
}
该代码实现了一个基于STM8S微控制器的系统,包括DS1302实时时钟的读取和数码管显示,以及DS18B20温度传感器的数据读取。系统支持时间的显示和调整,以及温度显示。还包含了一个简单的闹钟功能,并使用独立按键进行交互。
250





