⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 finalclock.c

📁 多功能时钟
💻 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 + -