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

📄 8583.c

📁 pcf8583实时时钟芯片单片机C51几口程序
💻 C
字号:
/******************************************************************
 *                    copyright  2004                          *
*******************************************************************
		文件名称:   8583.c
		文件版本:   1.00
		创建人:	
		创建日期:   2004.05.18
		功能描述:   8583日历时钟驱动
		相关硬件:    AT89S52,11.0592M晶震
					  
		
*******************************************************************/
#include <8583.h>

uchar year_base;
uchar year_buf;

/*+++++++++++++++++++++++++++++++++++++++++++++++++
i2cstart:发出i2c其始信号
++++++++++++++++++++++++++++++++++++++++++++++++++*/
static void i2cstart(void)
{
 
	_nop_();
	scl=1;
	somenop( );
	sda=0;
	somenop( );
	scl=0;
	somenop( );
}

/*+++++++++++++++++++++++++++++++++++++++++++++++++
i2cstop: 发出i2c总线结束信号
+++++++++++++++++++++++++++++++++++++++++++++++++++*/
static void i2cstop(void)
{
	sda=0;
	_nop_( );
	scl=1;
	somenop( );
	sda=1;
	somenop( );
	scl=0;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++
i2cinit: i2c总线初始化程序
++++++++++++++++++++++++++++++++++++++++++++++++++*/
static void i2cinit ( void )
{
	scl=0;
	somenop( );
	i2cstop( );
}

/*+++++++++++++++++++++++++++++++++++++++++++++++++++
i2cclock:发送总线时钟信号,并返回时钟高电平期间SDA的状态,
可用于发送也可用于接收
+++++++++++++++++++++++++++++++++++++++++++++++++++*/
static bit i2cclock (void)
{
	bit sample;
	somenop( );
	scl=1;
	_nop_( );_nop_( );_nop_( );
	sample=sda;
	_nop_( );_nop_( );
	scl=0;
	somenop( );
	return(sample);
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++
i2csendbyte:向I2C总线发送一个字节,并请求应答,若收到应答,则
返回1,否则返回0
++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
static bit i2csendbyte(uchar i2cdata)
{
	register uchar i;
	for (i=0;i<8;i++)
	{
		sda=(bit)(i2cdata&0x80);
		i2cdata<<=1;
		i2cclock( );
	}
	sda=1;
	return (~i2cclock( ));
}

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++
i2creceivebyte:从总线接收一个字节,并返回该字节,不回送应答信号
主函数调用本函数前应保证sda为1
++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
static uchar i2creceivebyte(void)
{
	uchar i2cdata=0;
	register uchar i;
	for (i=0;i<8;i++)
	{
		i2cdata<<=1;
		if (i2cclock( )) i2cdata++;
	}
	return (i2cdata);
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++
i2csendack:向i2c总线发送应答信号ack
++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
static void i2csendack (void)
{
	sda=0;
	i2cclock( );
	sda=1;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
i2csendnotack:发送非应答信号到i2c总线
+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
static void i2csendnotack(void)
{
	sda=1;
	i2cclock( );
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++
wr8583:对8583ram单元的读写操作
参数:addr: 指定的RAM单元地址
buf:读写数据缓冲区首地址
num:从addr开始读写的数据字节个数
wr: 读写标志,1为主机读,0为主机写
+++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
 void wr8583(uchar addr,uchar buf[ ],uchar num,uchar wr) reentrant
{
	uchar index;			//发送字节索引
	EA=0;					//发送期间禁止中断,防止干扰
	i2cinit( );
	i2cstart( );
	i2csendbyte (0xa0);		//发送 8583写地址
	i2csendbyte(addr);		//发送要操作的RAM地址
	if (wr==0)				//主机写数据
	{
		for (index=0;index<num;index++)
		{
			i2csendbyte(buf[index]);

		}
	}
	else if (wr==1)
	{						//主机读数据
		i2cstart ( );		//发送重复起始信号
		i2csendbyte(0xa1);	//发8583读地址
		for (index=0;index<num-1;index++)
		{
			sda=1;			//写之前将数据线置高
			buf[index]=i2creceivebyte( );
			i2csendack( );	//发送应答信号
		}
		buf[index]=i2creceivebyte( );//读最后一个数据
		i2csendnotack( );		//发送非应答信号
	}
	i2cstop( );
	EA=1;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++
fill8583:对8583RAM单元添丛固定的值
参数:
	filler:		要填充的字节内容
	startaddr:	指定的RAM单元首地址
	fillnum	:   从startaddr开始填充的字节个数
+++++++++++++++++++++++++++++++++++++++++++++++++++*/
 void fill8583(uchar filler,uchar startadr,uchar fillnum)
{
	uchar index;
	EA=0;
	i2cinit( );
	i2cstart( );
	i2csendbyte(0xa0);
	i2csendbyte(startadr);
	for (index=0;index<fillnum;index++)
	{
		i2csendbyte(filler);
	}
	i2cstop( );
	EA=1;
}



//该程序仅适用于本程序中计算bcd年加法
uchar yearbcdadd(uchar data1,uchar data2)
{
	uchar temp;
	temp=data1+data2;
	if(temp&0x0f>=0x0a) temp=(temp&0xf0)+(temp&0x0f-0x0a)+0x10;
	return temp;
}
/*******************************************************************
*	函数名称:	read_daytime	
*	创建人员:	gloria
*	函数版本:	1.00
*	创建日期:	2004.5.19 
*   功能描述:  读取8583内的日期和时间
*	入口参数:  daytime  存放读出的日期和时间的结构指针
*               buf      暂时存放读出的日期和时间的缓冲区首址
*	返回值: 	无
*	修改记录:
*******************************************************************/
/*+++++++++++++++++++++++++++++++++++++++++
	read_time:读出8583时间数据
+++++++++++++++++++++++++++++++++++++++++++*/
	void read_daytime(struct DAYTIME  *daytime,uchar *buf )
{
	uchar temp;

	fill8583(0x40,0x00,1);		//保持和捕捉数据,?准备读数据
	wr8583(0x02,buf,5,1);		//读时分秒年月日各寄存器
	fill8583(0x00,0x00,1);		//计数状态
	
	daytime->second=buf[0];
	daytime->minute=buf[1];
	daytime->hour=buf[2];
	temp=buf[3];
	daytime->day=temp&0x3f;
	temp=buf[3];
	daytime->yearl=(temp&0xc0)>>6;
	temp=buf[4];
	daytime->month=temp&0x1f;
	daytime->week=(buf[4]&0xe0)>>5;
	
	wr8583(0x0c,buf,1,1);						//年低位缓冲 
	year_buf=buf[0];
//	daytime->year_base=buf[1];
	if(daytime->yearl<year_buf)
	{
		//4位年进位
		//计算年基准,更新年基准和年缓冲单元
		year_base=yearbcdadd(year_base,4);
		year_buf=daytime->yearl;
	

		//将年基准和年低位缓冲存入8583中
		buf[0]=year_base;
		buf[1]=year_buf;
		wr8583(0x0b,buf,2,0);
		
	}
	else if(daytime->yearl>year_buf)
	{
		//年进位
		year_buf=daytime->yearl;
		buf[0]=year_buf;
		wr8583(0x0c,buf,1,0);
	}
	//相等,不作处理

	daytime->yearl=yearbcdadd(year_base,daytime->yearl);	//计算年低位值

		return;

}	

//设置8583数据
void set_8583(uchar *buf )
{
		fill8583(0x80,0x00,1);		//停止计数
		wr8583(0x01,buf,6,0);
	    fill8583(0x00,0x00,1);		//计数状态
				
	
}

⌨️ 快捷键说明

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