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

📄 clock.c

📁 单片机用DS1302进行计时
💻 C
字号:
#include<reg52.h>
#include<string.h>
#define uchar unsigned char
#define uint unsigned int 
sbit rs=P1^0;
sbit rw=P1^1;
sbit lcden=P1^2;

sbit sclk=P3^7;
sbit io=P3^5;
sbit rst=P3^6;
void delay(uint z)
{
	uint x;
	for(;z>0;z--)
		for(x=10;x>0;x--)
		;
}
void write_com(uchar command)
{
	lcden=0;
	rs=0;
	rw=0;
	P0=command;
	lcden=1;
	delay(1);
	lcden=0;
	
}
void write_data(uchar date)
{
	lcden=0;
	rs=1;
	rw=0;
	P0=date;
	lcden=1;
	delay(1);
	lcden=0;
}

void init()
{
	write_com(0x38);
	write_com(0x0c);
	write_com(0x06);
}

/*****************************************
函数名称:write_byte
功能:向DS1302写入一个字节数据(无RST操作)
参数:byte 要写入数据
返回值:无
*****************************************/

void write_byte(uchar byte)
{
	uchar i;		//8位数据计数

	for(i=0;i<8;i++)
	{
		sclk=0;			//拉低时钟信号
		io=byte&0x01;	//给数据最低位
		delay(1);		//调整时钟和脉冲宽度
		sclk=1;			//提供时钟上升沿
		byte=byte>>1;	//数据右移一位,为送出新数据做准备
	}
}

uchar read_byte(void)		//读一个字节
{
	uchar i,byte=0;
	for(i=0;i<8;i++)
	{
		byte>>=1;		//保存输出数据
		sclk=1;			//时钟是高电平
		delay(1);		//延时,调整时钟脉冲宽度
		sclk=0;			//时钟下降沿,准备读数据位
		delay(1);
		if(io==1)		//读出数据位为1,给最高位置1
		byte=byte|0x80;
		if(io==0)		//读出数据位为0,给最高位置0
		byte=byte&0x7f;	
	}
	return byte;		//返回读出数据
}

void write_D(uchar addr,uchar date)		//向某个地址写入一个字节的数据
{
	rst=0;			//拉低片选端
	sclk=0;			//拉低时钟端
	delay(1);
	rst=1;			//拉高片选端
	delay(1);
	write_byte(addr);		//写入操作命令(地址)
	delay(1);
	sclk=0;			//拉低时钟端端
	delay(1);
	write_byte(date);		//写入数据
	sclk=0;			//拉低时钟端
	delay(1);
	rst=0;		//拉低片选端
}

/*uchar read_D(uchar addr)		//在某地址读一个字节数据
{
	uchar date;
	rst=0;			//拉低片选端
	sclk=0;			//拉低时钟端
	delay(1);
	rst=1;			//拉高片选端
	delay(1);
	write_byte(addr);	//写入操作命令(地址)
	delay(1);
	date=read_byte;		//读出数据
	delay(1);
	sclk=0;				//拉低时钟端
	rst=0;				//拉低片选端
	return date;		//返回读出数据

}*/
void set_time(uchar ptime[])		//设置时间
{
	uchar i;
    uchar addr=0x80;
	write_D(0x8e|0x00,0x00);		//写入控制命令,WP为0,允许写操作
	delay(200);					//稍长延时
	for(i=0;i<7;i++)
	{
		write_D(addr|0x00,ptime[i]);		//写入秒 分 时 日 月 星期 年
		addr=addr+2;					//地址加2
		delay(10);
	}
	write_D(0x8e|0x00,0x80);			//写控制命令,WP为1
}

void get_time(uchar time[])		//读取当前时间
{
	uchar i;
/****************************************
//单次读写	
	uchar addr=0x80;
	for(i=0;i<7;i++)
	{
		time[i]=read_D(addr|0x00);		//秒 分 时 日 月 星期 年
		addr=addr+2;
	}
*******************************************/
//多字节读取
	rst=0;		//拉低片选
	delay(1);
	rst=1;		//拉高片选
	delay(1);
	write_byte(0xbf);		//写入时钟多字节读取命令 0xbf
 	for (i=0;i<8;i++)       //时间数据的存放格式是:
    {                        //秒,分,时,日,月,星期,年,控制
        time[i]=read_byte(); //【7个数据(BCD格式)+1个控制】 
    }
	rst=0;	//拉低片选
//
	sclk=0;		//拉低时钟端

}

void DS_init()	//初始化DS1302
{
	write_D(0x8e|0x00,0x00);		//写入写允许命令
	write_D(0x80|0x00,0x00);		//启动振荡器,DS1302开始工作
	write_D(0x8e|0x00,0x80);		//写控制命令,不允许写操作

}

void bcd_asc(uchar bcd,uchar pasc[])
{
	pasc[0]=bcd/16|0x30;	//转换十位
	pasc[1]=bcd&0x0f|0x30;		//转换个位
}

void disp(uchar time[])
{
	uchar i,asc[2];
	uchar line1[11]={0,0,'-',0,0,'-',0,0,' ',0,'\0'};//显示第1行的字符数组
 	uchar line2[9]={0,0,':',0,0,':',0,0,'\0'};		  //显示第2行的字符数组
	for(i=0;i<3;i++)		//
	{
		bcd_asc(time[2-i],asc);
		line2[i*3]=asc[0];
  		line2[i*3+1]=asc[1];
	}
	bcd_asc(time[6],asc);
	line1[0]=asc[0];
	line1[1]=asc[1];
	bcd_asc(time[4],asc);						  //为第1行的月赋值
	line1[3]=asc[0];
	line1[4]=asc[1];
	bcd_asc(time[3],asc);						  //为第1行的日赋值
	line1[6]=asc[0];
	line1[7]=asc[1];
	bcd_asc(time[5],asc);						  //为第1行的星期赋值
	line1[9]=asc[1];

	write_com(0x80+0x01);
	for(i=0;i<strlen(line1);i++)
	{
		write_data(line1[i]);
	}											//显示第一行
	write_com(0x80+0x44);
	for(i=0;i<strlen(line2);i++)
	{
		write_data(line2[i]);
	}											//显示第二行


}
void main()
{


	
//	uchar setadd,setdat,shift;	  //setadd指定将当前数值送入DS1302的哪个寄存器
		   						  //setdat是当前设置的数值,即被送入DS1302指定寄存器的数
							  //shift来实现十位和各位的设置相互独立(因为十位和个位是在一个寄存器里的)
 //uchar dis_x,dis_y;			  //存储1602液晶当前光标的位置
 uchar settime[7]={0x50,0x27,0x19,0x05,0x02,0x06,0x09};//设置的秒,分,时,日,月,星期,年
 uchar gettime[7]={0x00,0x00,0x00,0x00,0x00,0x00,0x00};//保存当前时间的数组
// LCD1602_initial(); 		//初始化1602液晶
 //DS1302_portinit();			//初始化DS1302的三根数据线
init(); 
 DS_init();				//启动振荡器,DS1302开始工作 
 set_time(settime);		//设置初始时间
 while(1)					//以下程序完成显示和设置时间
 {
   get_time(gettime);	//获得当前时间
   
   disp(gettime);		//显示当前时间
 }



	
//	while(1);
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -