基于单片机的电子钟程序设计与调试

代码部分

onewire.c
#include "stc15f2k60s2.h"

sbit DQ = P1^4;  //单总线接口

//单总线延时函数
void Delay_OneWire(unsigned int t)  //STC89C52RC
{
	t = t*12;
	while(t--);
}

//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		DQ = 0;
		DQ = dat&0x01;
		Delay_OneWire(5);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(5);
}

//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;
  
	for(i=0;i<8;i++)
	{
		DQ = 0;
		dat >>= 1;
		DQ = 1;
		if(DQ)
		{
			dat |= 0x80;
		}	    
		Delay_OneWire(5);
	}
	return dat;
}

//DS18B20设备初始化
bit init_ds18b20(void)
{
  	bit initflag = 0;
  	
  	DQ = 1;
  	Delay_OneWire(12);
  	DQ = 0;
  	Delay_OneWire(80);
  	DQ = 1;
  	Delay_OneWire(10); 
    initflag = DQ;     
  	Delay_OneWire(5);
  
  	return initflag;
}

unsigned int duwendu()
{
	 unsigned char high,low;
	 unsigned int temp;
	 init_ds18b20();
	 Write_DS18B20(0xcc);
	 Write_DS18B20(0x44);
	 Delay_OneWire(200);

	 init_ds18b20();
	 Write_DS18B20(0xcc);
	 Write_DS18B20(0xbe);

	 low =	Read_DS18B20();
	 high = Read_DS18B20();
	 temp = high<<8;
	 temp |= low;
	 temp = temp*0.0625;
	 return temp;
}
onewire.h
#ifndef __ONEWIRE_H
#define __ONEWIRE_H

unsigned char rd_temperature(void);  //; ;
unsigned int duwendu();

#endif
ds1302.c
#include <stc15f2k60s2.h>
#include <intrins.h>

sbit SCK=P1^7;		
sbit SDA=P2^3;		
sbit RST = P1^3;   // DS1302复位												

void Write_Ds1302(unsigned  char temp) 
{
	unsigned char i;
	for (i=0;i<8;i++)     	
	{ 
		SCK=0;
		SDA=temp&0x01;
		temp>>=1; 
		SCK=1;
	}
}   

void Write_Ds1302_Byte( unsigned char address,unsigned char dat )     
{
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
 	RST=1; 	_nop_();  
 	Write_Ds1302(address);	
 	Write_Ds1302(dat);		
 	RST=0; 
}

unsigned char Read_Ds1302_Byte ( unsigned char address )
{
 	unsigned char i,temp=0x00;
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
 	RST=1;	_nop_();
 	Write_Ds1302(address);
 	for (i=0;i<8;i++) 	
 	{		
		SCK=0;
		temp>>=1;	
 		if(SDA)
 		temp|=0x80;	
 		SCK=1;
	} 
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
	SCK=1;	_nop_();
	SDA=0;	_nop_();
	SDA=1;	_nop_();
	return (temp);			
}

void set_sfm(unsigned char shi,unsigned char fen,unsigned char miao)
{
	Write_Ds1302_Byte(0x8e,0x00);//关闭保护位
	Write_Ds1302_Byte(0x80,(miao/10)*16+miao%10);//设置秒
	Write_Ds1302_Byte(0x82,(fen/10)*16+fen%10);//设置分
	Write_Ds1302_Byte(0x84,(shi/10)*16+shi%10);//设置小时
	Write_Ds1302_Byte(0x8e,0x80);//打开保护位
}
ds1302.h
#ifndef __DS1302_H
#define __DS1302_H

void Write_Ds1302(unsigned char temp);
void Write_Ds1302_Byte( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302_Byte( unsigned char address );
void set_sfm(unsigned char shi,unsigned char fen,unsigned char miao);
#endif
mian.c
#include<stc15f2k60s2.h>
#include<ds1302.h>
#include<onewire.h>

#define uchar unsigned char
#define uint unsigned int

sbit buzz = P0^6;
sbit relay = P0^4;

bit temp_flag = 0;
bit blink_flag = 0;
bit alarm_flag = 0;
bit led_blink_flag = 0;
bit read_time_flag = 0;


uchar code duan[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0x40,0x39};//定义段码数组
uchar disbuff[8];//定义显示数字数字
uchar keysta[] = {1,1,1,1};
uchar kaymap[] = {1,2,3,4};
uchar trg,cont;
uchar boot_time = 0;
uchar shi,fen,miao;
uchar shi_set=0,fen_set=0,miao_set=0;
uchar temp;
uchar sec;
uchar mode = 0;//0为显示,1为时钟设置,2为闹钟设置
uchar time_count1 = 0 ;
uchar time_count2 = 0 ;

void closebuzz()
{
	P2 = P2&0x1f|0xa0;
	buzz = 0;
	relay = 0;
	P2 = 0x00;
}

void keyscan()
{
	uchar keydate = P3^0xff;
	trg = keydate&(keydate^cont);
	cont = keydate;
}

void keyfun()
{
	if(alarm_flag == 0)
	{
	if((trg == 0x01)&&(mode == 0))
	{
			mode = 1;
	}

	if((trg == 0x01)&&(mode == 1))
	{
			if(++time_count1==4)
			{
				time_count1 = 0;
				set_sfm(shi,fen,miao);
				mode = 0;
			}
	}

	if((trg == 0x02)&&(mode == 0))
	{
			mode = 2;
	}

	if((trg == 0x02)&&(mode == 2))
	{
			if(++time_count2==4)
			{
				time_count2 = 0;
				mode = 0;
			}
	}

	if(trg == 0x04)
	{
		if((mode == 1)&&(time_count1 == 1))
		if(++shi == 24)shi=0;	
		if((mode == 1)&&(time_count1 == 2))
		if(++fen == 60)fen=0;
		if((mode == 1)&&(time_count1 == 3))
		if(++miao == 60)miao=0;
		if((mode == 2)&&(time_count2 == 1))
		if(++shi_set == 24)shi_set=0;	
		if((mode == 2)&&(time_count2 == 2))
		if(++fen_set == 60)fen_set=0;
		if((mode == 2)&&(time_count2 == 3))
		if(++miao_set == 60)miao_set=0;
	}

	if(trg == 0x08)
	{
		if((mode == 1)&&(time_count1 == 1))
		{if(shi == 0)shi=24;shi--;}	
		if((mode == 1)&&(time_count1 == 2))
		{if(fen == 0)fen=60;fen--;}
		if((mode == 1)&&(time_count1 == 3))
		{if(miao == 0)miao=60;miao--;}
		if((mode == 2)&&(time_count2 == 1))
		{if(shi_set == 0)shi_set=24;shi_set--;}	
		if((mode == 2)&&(time_count2 == 2))
		{if(fen_set == 0)fen_set=60;fen_set--;}
		if((mode == 2)&&(time_count2 == 3))
		{if(miao_set == 0)miao_set=60;miao_set--;}
	}

	if((mode == 0)&&(cont == 0x08))
	{
		 temp_flag = 1;
	}

	if((mode == 0)&&(cont == 0x00))
	{
		temp_flag = 0;
	}
	}

	if((trg != 0x00)&&(alarm_flag == 1))
	{
		alarm_flag = 0;
		sec = 0;
	}
}

void shownum()//显示数字函数
{
	if(mode == 0)
	{
	disbuff[0]=shi/10;
	disbuff[1]=shi%10;
	disbuff[2]=11;
	disbuff[3]=fen/10;
	disbuff[4]=fen%10;
	disbuff[5]=11;
	disbuff[6]=miao/10;
	disbuff[7]=miao%10;	
	}

	if(mode == 1)
	{		
		if((blink_flag == 1)&&(time_count1 == 1))
		{
			disbuff[0]=shi/10;
			disbuff[1]=shi%10;
			disbuff[2]=11;
			disbuff[3]=fen/10;
			disbuff[4]=fen%10;
			disbuff[5]=11;
			disbuff[6]=miao/10;
			disbuff[7]=miao%10;	
		}

		if((blink_flag == 0)&&(time_count1 == 1))
		{
			disbuff[0]=10;
			disbuff[1]=10;
			disbuff[2]=11;
			disbuff[3]=fen/10;
			disbuff[4]=fen%10;
			disbuff[5]=11;
			disbuff[6]=miao/10;
			disbuff[7]=miao%10;	
		}

		if((blink_flag == 1)&&(time_count1 == 2))
		{
			disbuff[0]=shi/10;
			disbuff[1]=shi%10;
			disbuff[2]=11;
			disbuff[3]=fen/10;
			disbuff[4]=fen%10;
			disbuff[5]=11;
			disbuff[6]=miao/10;
			disbuff[7]=miao%10;	
		}

		if((blink_flag == 0)&&(time_count1 == 2))
		{
			disbuff[0]=shi/10;
			disbuff[1]=shi%10;
			disbuff[2]=11;
			disbuff[3]=10;
			disbuff[4]=10;
			disbuff[5]=11;
			disbuff[6]=miao/10;
			disbuff[7]=miao%10;	
		}

		if((blink_flag == 1)&&(time_count1 == 3))
		{
			disbuff[0]=shi/10;
			disbuff[1]=shi%10;
			disbuff[2]=11;
			disbuff[3]=fen/10;
			disbuff[4]=fen%10;
			disbuff[5]=11;
			disbuff[6]=miao/10;
			disbuff[7]=miao%10;	
		}

		if((blink_flag == 0)&&(time_count1 == 3))
		{
			disbuff[0]=shi/10;
			disbuff[1]=shi%10;
			disbuff[2]=11;
			disbuff[3]=fen/10;
			disbuff[4]=fen%10;
			disbuff[5]=11;
			disbuff[6]=10;
			disbuff[7]=10;	
		}
	}

	if(mode == 2)
	{		
		if((blink_flag == 1)&&(time_count2 == 1))
		{
			disbuff[0]=shi_set/10;
			disbuff[1]=shi_set%10;
			disbuff[2]=11;
			disbuff[3]=fen_set/10;
			disbuff[4]=fen_set%10;
			disbuff[5]=11;
			disbuff[6]=miao_set/10;
			disbuff[7]=miao_set%10;	
		}

		if((blink_flag == 0)&&(time_count2 == 1))
		{
			disbuff[0]=10;
			disbuff[1]=10;
			disbuff[2]=11;
			disbuff[3]=fen_set/10;
			disbuff[4]=fen_set%10;
			disbuff[5]=11;
			disbuff[6]=miao_set/10;
			disbuff[7]=miao_set%10;	
		}

		if((blink_flag == 1)&&(time_count2 == 2))
		{
			disbuff[0]=shi_set/10;
			disbuff[1]=shi_set%10;
			disbuff[2]=11;
			disbuff[3]=fen_set/10;
			disbuff[4]=fen_set%10;
			disbuff[5]=11;
			disbuff[6]=miao_set/10;
			disbuff[7]=miao_set%10;	
		}

		if((blink_flag == 0)&&(time_count2 == 2))
		{
			disbuff[0]=shi_set/10;
			disbuff[1]=shi_set%10;
			disbuff[2]=11;
			disbuff[3]=10;
			disbuff[4]=10;
			disbuff[5]=11;
			disbuff[6]=miao_set/10;
			disbuff[7]=miao_set%10;	
		}

		if((blink_flag == 1)&&(time_count2 == 3))
		{
			disbuff[0]=shi_set/10;
			disbuff[1]=shi_set%10;
			disbuff[2]=11;
			disbuff[3]=fen_set/10;
			disbuff[4]=fen_set%10;
			disbuff[5]=11;
			disbuff[6]=miao_set/10;
			disbuff[7]=miao_set%10;	
		}

		if((blink_flag == 0)&&(time_count2 == 3))
		{
			disbuff[0]=shi/10;
			disbuff[1]=shi%10;
			disbuff[2]=11;
			disbuff[3]=fen/10;
			disbuff[4]=fen%10;
			disbuff[5]=11;
			disbuff[6]=10;
			disbuff[7]=10;	
		}
	}

	if(temp_flag == 1)
	{
	disbuff[0]=10;
	disbuff[1]=10;
	disbuff[2]=10;
	disbuff[3]=10;
	disbuff[4]=10;
	disbuff[5]=temp/10;
	disbuff[6]=temp%10;
	disbuff[7]=12;	
	}
}

void display()//数码管扫描函数
{
	static uchar index = 0;
	P2 = P2&0x1f|0xe0;
	P0 = 0xff;
	P2 = 0x00;

	P2 = P2&0x1f|0xc0;
	P0 = 1<<index;
	P2 = 0x00;

	P2 = P2&0x1f|0xe0;
	P0 = ~duan[disbuff[index]];
	P2 = 0x00;

	index++;
	index &= 0x07;

}

void Timer0Init(void)		//2毫秒@12.000MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x40;		//设置定时初值
	TH0 = 0xA2;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0 = 1;
	EA = 1 ; 
}

void time0() interrupt 1
{
	static uint count;
	static uchar alarm,count_time;
	if(++count==500)
	{
		blink_flag = ~blink_flag;
		count = 0;
		if(alarm_flag == 1)
		{sec++;}
	}

	if((++alarm == 100)&&(alarm_flag == 1))
	{
		led_blink_flag = ~led_blink_flag;		
		alarm = 0;
	}

	if(++count_time == 150)
	{
		count_time = 0;
		read_time_flag = 1;
	}

	display();
	keyscan();
	keyfun();		
}

void led_set()
{
	if((alarm_flag == 1)&&(led_blink_flag == 1))
	{
		P2 = P2&0x1f|0x80;
		P0 = ~0x01;
		P2 = 0x00;
	}
	if((alarm_flag == 1)&&(led_blink_flag == 0))
	{
		P2 = P2&0x1f|0x80;
		P0 = ~0x00;
		P2 = 0x00;
	}

	if(alarm_flag == 0)
	{
		P2 = P2&0x1f|0x80;
		P0 = ~0x00;
		P2 = 0x00;
	}
}

void main()
{
	uchar shi_temp,fen_temp,miao_temp;
	closebuzz();
	Timer0Init();
	set_sfm(23,59,55);//设置时间
	temp = (uchar)duwendu();

	while(1)
	{
		shownum();
		led_set();

		if((mode != 1)&&(read_time_flag == 1))
		{
		read_time_flag = 0;
		//读取时间
		shi_temp =Read_Ds1302_Byte(0x85);
		fen_temp=Read_Ds1302_Byte(0x83);
		miao_temp=Read_Ds1302_Byte(0x81);

		//将读取到的BCD码转化为十进制
		shi = shi_temp/16*10+shi_temp%16;
		fen = fen_temp/16*10+fen_temp%16;
		miao = miao_temp/16*10+miao_temp%16;

		if((shi == shi_set)&&(fen == fen_set)&&(miao == miao_set))
		alarm_flag = 1;	
		}

		if(temp_flag == 1)
		{
			temp = (uchar)duwendu();
		}

		if(sec >= 5)
		{
			alarm_flag = 0;
			sec = 0;	
		}
	}
}

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 基于51单片机的电子时钟项目需要通过Keil编写程序,并使用Proteus进行仿真电路搭建。该项目主要包括以下几个步骤: 1. 硬件搭建:按照电子时钟的设计需求,连接51单片机和相关的电子元件,如晶体振荡器、数码管、按键等。通过Proteus软件,可以将这些元件连接起来,搭建出完整的电路。 2. Keil程序编写:使用Keil软件,编写51单片机的C语言程序。该程序需要实现时钟的功能,包括时、分、秒的显示和计时、调整时间、闹钟功能等。通过编程,可以控制数码管的显示,以及对按键进行响应。 3. Proteus仿真:将编写好的程序通过Proteus软件连接至搭建好的电路。进行仿真测试时,可以通过模拟时钟的不同状态,调试和验证编写的程序的正确性和稳定性。仿真过程中,可以检查数码管的显示情况,以及程序对按键输入的响应。 4. 优化和调试:根据仿真过程中的结果,对程序进行优化和调试。可能需要根据具体的需求,修改程序中的一些逻辑或代码,确保电子时钟的功能正常运行,并符合设计要求。 总的来说,基于51单片机的电子时钟项目需要通过Keil编写程序,并结合Proteus进行仿真电路搭建和测试。通过这样的开发流程,可以实现一个功能完善、稳定可靠的电子时钟。 ### 回答2: 基于51单片机的电子时钟keil程序和protues仿真电路组成了一个完整的设计方案。 首先,keil程序是用于开发51单片机的集成开发环境,它提供了编译、调试和仿真等功能,能够帮助程序员快速开发出51单片机的应用程序。在电子时钟的设计中,我们可以使用keil来编写单片机的程序代码,实现时钟的各种功能。 其次,protues是一款电子设计自动化软件,它提供了电子电路仿真和PCB布局设计等功能,能够帮助我们快速验证电路的正确性。在电子时钟的设计中,我们可以使用protues来建立电子时钟的仿真电路,验证单片机代码的正确性和稳定性。 基于51单片机的电子时钟设计,我们可以使用keil来编写单片机的程序代码,实现时钟的各种功能,包括时间显示、报时功能、闹钟功能等。通过keil的编译、调试和仿真功能,我们可以验证代码的正确性和稳定性。 在电路设计方面,我们可以使用protues来建立电子时钟的仿真电路,通过仿真可以验证电路的正确性和稳定性,包括时钟电路、数码管驱动电路、按钮输入电路等。通过protues的电路仿真功能,我们可以检查电路设计的错误和漏洞,提前解决电路问题。 基于51单片机电子时钟keil程序和protues仿真电路的组合,我们可以全面验证电子时钟的功能和性能,确保设计的准确性和可靠性,为最终实现一个完整的电子时钟设计提供了有力的支持。 ### 回答3: 基于51单片机的电子时钟keil程序和protues仿真电路可以实现以下功能: 1. 显示当前时间:我们可以使用数码管或LCD显示模块来显示当前的时、分和秒。通过编写相应的程序,我们可以从单片机的时钟源获取当前时间,并将其转换为可以在数码管或LCD上显示的格式。 2. 时间调整功能:可以通过按钮或旋钮等输入设备来调整电子时钟的时间。当用户按下或旋转输入设备时,我们可以响应用户的操作,并对时钟的时间进行相应的调整。 3. 闹钟功能:我们可以设置闹钟功能,让电子时钟在特定的时间点发出警报声。通过在程序中设置闹钟时间和警报声的播放方式,我们可以实现这一功能。 4. 温湿度监测:如果我们希望电子时钟能够同时监测室内的温度和湿度,我们可以连接温湿度传感器,并在程序中读取传感器的数据。然后,我们可以将这些数据显示在数码管或LCD上。 程序开发过程中,我们可以使用keil来编写51单片机的程序,通过keil提供的调试工具来测试和调试程序的正确性。同时,我们可以在protues中设计和仿真电子时钟的电路,包括单片机、显示模块、输入设备和传感器等所有的硬件组件。这样,我们可以在protues中验证电路的功能和效果,并进行性能优化和调试。当电路和程序都满足我们的要求后,我们就可以将程序烧录到实际的硬件上,并使用它作为一台完整的电子时钟了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值