📄 finalclock.c
字号:
/***********************************************************************************
学校:东北石油大学
院系:电子科学学院
专业:电子科学与技术
班级:电子**班
学号:***********
姓名:小菜
*************************************************************************************/
#include <reg52.h> //52 单品机头文件
#include <intrins.h>
#define uchar unsigned char //宏定义
#define uint unsigned int
void delay(uint z);
sbit key1=P3^4; //设置按键
sbit key2=P3^5;
sbit key3=P3^0;
sbit key4=P3^1;
sbit key5=P3^2;
sbit key6=P3^3;
sbit BEEP=P2^1;
sbit led=P2^7;
sbit DQ = P2^0;
void beepopen(uchar times); //声明函数
void onit();
void clockset();
void display(h,m,s);
void alarmset();
void distribute();
void zd_clock();
void clock();
void delay1(unsigned char t);
void song();
void alarmbeep();
unsigned char Init_DS18B20(void);
unsigned int ReadTemperature(void);
uchar code disp_code[] =
{
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90,
// 0-9 0 1 2 3 4 5 6 7 8 9
0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e,
// 10-15 a b c d e f
0x7F, 0xBF, 0x9C, 0xFF
// 16-19 . - 。null
}; //数码管显示值列表
uchar code disp_code1[]=
{
0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10 //带小数点的0-9
};
//设置变量
uint num,temp,alarm,l,j,temp1,ttemp;
uchar ch,cm,cs,xs,h1,h2,m1,m2,s1,s2,tf,hh,mm,ss,h,m,s,ah,am,as,timer0h, timer0l,k,time,shift,flag,temp0,z;
void proc_18b20(uint t) //18b20温度显示函数--由于一开始没想加测温功能,另外时间仓促,函数利用率不高
{
uint t_temp1, t_temp2,t_temp3,t_temp4;
t_temp1 = (int)(t / 100);
t_temp2 = (int)(t % 100);
t_temp3=(int)(t_temp2%10);
t_temp4=(int)(t_temp2/10);
P1=0xfe;
P0=0xf6;
delay(2);
P1=0xfd;
P0=disp_code[12];
delay(2);
P1=0xfb;
P0=disp_code[18];
delay(2);
P1=0xf7;
P0=disp_code[0];
delay(2);
P1=0xef;
P0=disp_code[t_temp3];
delay(2);
P1=0xdf;
P0=disp_code1[t_temp4];
delay(2);
P1=0xbf;
P0=disp_code[t_temp1];
delay(2);
P1=0x7f;
P0=0xf6;
delay(2);
}
void main()
{
onit();
while(1)
{
zd_clock(); //整点报时
if(key5==0&&key6!=0&&key1!=0&&key2!=0)
{
Init_DS18B20();
ttemp = ReadTemperature();
if(ttemp>30)
beepopen(1);
ttemp = (unsigned int)(ttemp * 10 + 0.5); //放大10倍输出并四舍五入
proc_18b20(ttemp);
}
else
{
if(key6==0) //当k2按下时 设置闹钟时间
alarmset();
else
{
if(key1==0||key2==0) //当k4或k3按下时 进行时钟设置
clockset(); //调用时钟设置程序
else
{
clock(); //调用时钟程序
if(ah==h&&am==m&&as==s)
{
ET1= 1; //打开定时器1中断
alarmbeep();
}
}
}
}
}
}
void timer0() interrupt 1 //定时器0的中断处理程序
{
TH0=(65536-9216)/256; // 每10ms产生一次中断 因为晶振频率为11.0592MHz,所以定时器装入初值应为,65536-10000/12*11.0592
TL0=(65536-9216)%256;
num++; //定时器0每产生一次中断 num++
}
void delay(uint z) //延时子函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void beepopen(uchar times) //整点报时的驱动蜂鸣器的程序
{
uint m = 0;
uchar n = 0;
while(times--)
{
for(m=0; m<5000; m++)
{
for(n=0; n<50; n++);
BEEP = ~BEEP;
}
BEEP = 1;
delay(200);
}
}
void onit()
{
num=0;
TMOD=0x01;
TH0=(65536-9216)/256; //赋初值给定时器0,表明每9126个机器周期发生一次定时器中断
TL0=(65536-9216)%256;
EA=1;
ET0=1;
TR0=1;
ah=5; //闹钟的初值为06:00:00
am=30;
as=0;
h=5;
m=01;
s=0;
}
void clockset() //时钟设置程序
{
TR0=0;
ch=h;
cm=m;
if(key1==0)
{
P3=0xbf;
if(key3==0)
{
while(!key3);
cs++;
if(cs==60)
cs=0;
num=cs*100;
}
if(key4==0)
{
while(!key4);
cm++;
if(cm==60)
cm=0;
}
if(key5==0)
{
while(!key5);
ch++;
if(h==24)
ch=0;
}
}
if(key2==0)
{
P3=0x7f;
if(key3==0)
{
while(!key3);
cs--;
if(cs==-1)
cs=59;
num=cs*100;
}
if(key4==0)
{
while(!key4);
cm--;
if(cm==-1)
cm=59;
}
if(key5==0)
{
while(!key5);
ch--;
if(ch==-1)
ch=23;
}
}
display(ch,cm,cs);
h=ch;
m=cm;
}
void display(h,m,s) //显示程序
{
h1=h%10;
h2=h/10;
m1=m%10;
m2=m/10;
s1=s%10;
s2=s/10;
P1=0xfe;
P0=disp_code[s1];
delay(2);
P1=0xfd;
P0=disp_code[s2];
delay(2);
P1=0xfb;
P0=disp_code[17];
delay(2);
P1=0xf7;
P0=disp_code[m1];
delay(2);
P1=0xef;
P0=disp_code[m2];
delay(2);
P1=0xdf;
P0=disp_code[17];
delay(2);
P1=0xbf;
P0=disp_code[h1];
delay(2);
P1=0x7f;
P0=disp_code[h2];
delay(2);
}
void alarmset() //闹钟设置程序
{
key1=0;
if(key3==0)
{
while(!key3);
{
as++;
if(as==60)
as=0;
}
}
if(key4==0)
{
while(!key4);
{
am++;
if(am==60)
am=0;
}
}
if(key5==0)
{
while(!key5);
{
ah++;
if(ah==24)
ah=0;
}
}
display(ah,am,as);
}
void distribute() //记时程序
{
uchar e;
s=num/100;
if(s>60)
{
e=s/60;
m=m+e;
s=s%60;
num=0;
}
if(s==60)
{
num=0;
m++;
}
if(m==60)
{
m=0;
h++;
}
if(h==24)
h=0;
}
void zd_clock() //整点报时程序
{
if(m==0&&s==0)
{
tf=h;
if(h==0)
tf=24;
led=0;
delay(50);
beepopen(tf);
led=1;
}
}
void clock() //时钟程序
{
TR0=1;
distribute();
display(h,m,s);
}
void alarmbeep() //闹钟音乐程序
{
code unsigned char FREQH[] = {
0xF2, 0xF3, 0xF5, 0xF5, 0xF6, 0xF7, 0xF8,
0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFC,
0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF};
code unsigned char FREQL[] = {
0x42, 0xC1, 0x17, 0xB6, 0xD0, 0xD1, 0xB6,
0x21, 0xE1, 0x8C, 0xD8, 0x68, 0xE9, 0x5B, 0x8F,
0xEE, 0x44, 0x6B, 0xB4, 0xF4, 0x2D,
0x47, 0x77, 0xA2, 0xB6, 0xDA, 0xFA, 0x16};
//--------------------------------------
//义勇军进行曲数码表
code unsigned char sszymmh[] = {5, 1, 1, 1, 2, 3, 1, 2, 1, 1, 2, 3, 1, 2, 1, 5, 2, 1, 6, 1, 1, 7, 1, 1, 1, 2, 2, 1, 2, 2,
3, 2, 1, 1, 2, 1, 2, 2, 1, 3, 2, 1, 5, 2, 2, 5, 2, 2, 3, 2, 3, 3, 2, 1, 1, 2, 3, 3, 2, 1,
5, 2, 3, 3, 2, 1, 2, 2, 2, 2, 2, 4, 6, 2, 2, 5, 2, 2, 2, 2, 2, 3, 2, 2, 5, 2, 1, 3, 2, 1,
5, 2, 1, 3, 2, 1, 2, 2, 1, 3, 2, 1, 1, 2, 2, 3, 2, 2, 5, 1, 3, 6, 1, 1, 1, 2, 1, 1, 2, 1,
3, 2, 3, 3, 2, 1, 5, 2, 1, 5, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 6, 1, 2, 2, 2, 3, 5, 1, 1,
1, 2, 3, 1, 2, 1, 3, 2, 3, 3, 2, 1, 5, 2, 4, 1, 2, 3, 3, 2, 1, 5, 2, 1, 5, 2, 1, 6, 2, 2,
5, 2, 2, 3, 2, 3, 1, 2, 1, 5, 2, 1, 5, 2, 1, 5, 2, 1, 3, 2, 1, 1, 2, 1, 5, 2, 2, 1, 2, 2,
3, 2, 3, 1, 2, 1, 5, 2, 1, 5, 2, 1, 5, 2, 1, 3, 2, 1, 1, 2, 1, 5, 1, 2, 1, 2, 2, 5, 1, 2,
1, 2, 2, 5, 1, 2, 1, 2, 2, 1, 2, 2, 0, 0, 0};
//--------------------------------------
TMOD = 0x11;
EA = 1;
l = 0;
if(key5!=0)
time = 1;
while(time)
{
k = sszymmh[l] + 7 * sszymmh[l + 1] - 1;
timer0h = FREQH[k];
timer0l = FREQL[k];
time = sszymmh[l + 2];
l += 3;
song();
if(key5==0)
{
ET1=0;
time=0;
}
}
}
void timer1() interrupt 3 //定时器1中断处理程序
{
TR1 = 0;
BEEP = !BEEP;
TH1 = timer0h;
TL1 = timer0l;
TR1 = 1;
}
void delay1(unsigned char t0) //用于音乐程序的延时函数
{
unsigned char t1;
unsigned long t2;
for(t1 = 0; t1 < t0; t1++) //双重循环, 共延时t个半拍
for(t2 = 0; t2 <8000; t2++)
; //延时期间, 可进入T0中断去发音
TR1 = 0; //关闭T1, 停止发音
}
void song() //演奏一个音符
{
TH1 = timer0h; //控制音调
TL1 = timer0l;
TR1=1; //启动T1, 由T1输出方波去发音
delay1(time); //控制时间长度
}
/******************************************************************************/
void delay2(int numb) //延时函数
{
while (numb--)
;
}
/*******************************************************************************/
unsigned char Init_DS18B20(void) //初始化ds1820
{
unsigned char x = 0;
DQ = 1; //DQ复位
delay2(8); //稍做延时
DQ = 0; //单片机将DQ拉低
delay2(80); //精确延时 大于 480us
DQ = 1; //拉高总线
delay2(14);
x = DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay2(20);
return(x);
}
/******************************************************************************/
unsigned char ReadOneChar(void) //读一个字节
{
unsigned char r = 0;
unsigned char dat = 0;
for (r = 8; r > 0; r--)
{
DQ = 0; // 给脉冲信号
dat >>= 1;
DQ = 1; // 给脉冲信号
if (DQ)
{
dat |= 0x80;
}
delay2(4);
}
return (dat);
}
/******************************************************************************/
void WriteOneChar(unsigned char dat) //写一个字节
{
unsigned char s = 0;
for (s = 8; s > 0; s--)
{
DQ = 0;
DQ = dat & 0x01;
delay2(5);
DQ = 1;
dat >>= 1;
}
}
/*void Config18b20()
{
Init_DS18B20();
WriteOneChar(0xcc); //skip rom
WriteOneChar(0x4e); //write scratchpad
WriteOneChar(0x3c); //上限
WriteOneChar(0x3f); //下限
WriteOneChar(0xff); //set 11 bit (0.125)
Init_DS18B20();
WriteOneChar(0xcc); //skip rom
WriteOneChar(0x48); //保存设定值
Init_DS18B20();
WriteOneChar(0xcc); //skip rom
WriteOneChar(0xb8); //回调设定值
}*/
unsigned int ReadTemperature(void) //读取温度
{
unsigned char a = 0;
unsigned char b = 0;
unsigned int ttt = 0;
float tt = 0;
void Config18b20();
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器
a = ReadOneChar(); //读低8位
b = ReadOneChar(); //读高8位
ttt = b;
ttt <<= 8;
ttt = ttt| a;
(ttt!=1360)?(tt=ttt*0.062525):0;
return (tt);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -