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

📄 24c01.c

📁 24C01的源代码 (1kb ROM)
💻 C
字号:
#include <reg51.h>
#include <absacc.h>
#include <intrins.h>
//*************************************************
//将2004 年1 月25 日星期日 上午11点10分30 秒的时间写入PCF8563
//以下在PCF8563 的CLKOUT 脚输出1Hz 的方波
//读出 年、月、日、星期、时、分、秒,以38400的波特率送往串口
//打开串口调试助手或其他串口调试软件设置波特率为38400,无校验,数据位8,停止位1
//**************************************************
#define PCF8563			0x0A	//器件地址
#define MAX_BYTE_NUM	10		//一次性接受或发送字节的最大数目

//内存数据定义
unsigned char 	SlvAdr;			//被控器地址
unsigned char   SubAdr;			//被控器单元地址
unsigned char 	ByteCnt;		//传送字节数存放单元 
unsigned char 	BitCnt;			//I2C 数据位计数器
unsigned char 	XmtDat [MAX_BYTE_NUM];		//发送数据缓冲区
unsigned char	RcvDat [MAX_BYTE_NUM]; 	//接收数据缓冲区
//unsigned char 	Second, Minute, Hour, Weekday, Day, Month, Year, Century;
bit				ERR=0;				//错误位

//端口位定义
sbit SDA = P3^7;		//模拟I2C 数据传送位
sbit SCL = P3^6;		//模拟I2C 时钟控制状态标志

sbit test1 = P1^0;
sbit test2 = P1^1;

void I2CSendData ();
//void Read8563();
void I2CSTA ();	
void I2CSendByte (unsigned char _24C01byte);
void I2CSTOP ();
void I2CRcvData ();	
unsigned char I2CRcvByte ();

void main ()
{
// 初始化设置

//以下准备送数
//将2004 年1 月25 日星期日 上午11点10分30 秒的时间写入PCF8563
	IE = 0x00;
/*
	XmtDat[0] = 0x00;		//启动时钟
	XmtDat[1] = 0x1F; 		//设置报警及定时器中断,定时器中断为脉冲形式
	XmtDat[2] = 0x30; 		//秒值(30s)
	XmtDat[3] = 0x10; 		//分值(10min)
	XmtDat[4] = 0x11;		//时值(11h)
	XmtDat[5] = 0x25;		//日期(25号)
	XmtDat[6] = 0x00;		//星期(0~6代表星期日~星期六)
	XmtDat[7] = 0x01;		//月份(如果首字节为1代表19XX年,首字节为0代表20XX年)
	XmtDat[8] = 0x04;		//年份(04年,与上一字节配合,确定为2004年)

	SlvAdr = PCF8563;		//送被控器地址	
	SubAdr = 0x00;			//送写入寄存器的首字节地址,从00H 开始写
*/	ByteCnt = 0x02;			//写七个时间信息和2 个控制命令

/*	I2CSTA();						//发送I2C 总线起始条件

	I2CSendByte (0xA0); //Chip selected bits=000, Write
	I2CSendByte (0xA1);
	I2CSendByte (0x55);
	I2CSendByte (0x56);
	I2CSTOP	();		//发送I2C 总线停止条件 */
/*
	I2CSTA();
	I2CSendByte (0xA0); //Write
	I2CSendByte (0x01);
	I2CSTA();
	I2CSendByte (0xA1); //Read
	RcvDat[0] = I2CRcvByte();
	I2CSTOP();
	if (RcvDat[0] == 0x55) test1 = 0;
*/
	SlvAdr = 0xA0;
	SubAdr = 0x01;
	XmtDat [0] = 0x55;
	XmtDat [1] = 0x66;
	I2CSendData ();
	while(1){
	SlvAdr = 0xA0;
	SubAdr = 0x01;
	I2CRcvData ();
	if (RcvDat[0] == 0x55 && RcvDat[1] == 0x66){ test2 = 1; test1 = ~test1;}
	}
//	if (ERR == 1) test1 = ~test1;

//	I2CSendData();			//送出数据
//	Read8563();

}

//*******************************************************************
//以下在PCF8563 的CLKOUT 脚输出1Hz 的方波,输出由0DH控制
//0DH  7 6 5 4 3 2  1   0 
//    PE - - - - - FD1 FD0
//   PE=0;CLKOUT禁止输出并设成高阻抗
//	PE=1;CLKOUT允许输出
//   FD1  FD0  输出频率
//    0    0  32768Hz
//    0    1  1024Hz
//    1    0  32Hz
//    1    1  1Hz
//要求输出32768Hz,1024Hz,32Hz,1Hz的数据分别为80H,81H,82H和83H
//********************************************************************
//以下每隔1s左右读取时间并将时间送往串口

/*;**********************************************************
;延时1s的子程序
;**********************************************************
D1S:
	PUSH	ACC
	PUSH	PSW
	SETB	RS0
	MOV	R7,#20
D11:	MOV	R6,#200
D12:	MOV	R5,#100
	DJNZ	R5,$
	DJNZ	R6,D12
	DJNZ	R7,D11
	POP		PSW
	POP		ACC
RET
;**********************************************************
;向串口送数的子程序
;***********************************************************
SEND:	
	MOV	SBUF,A
SLP:	
	JBC	TI,NEXT		;是否送完?
	AJMP	SLP
NEXT:	RET	 */

//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
//I2C总线的读写子程序										;;
//被控器地址在SlvAdr,单元地址在SubAdr中,所发送的数据字节数在ByteCnt中				;;
//所发送的数据在XmtDat中,所接收的数据在RcvDat中							;;
//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

//************************************************************************************************
//发送数据程序
//名称:I2CSendData
//描述:发送ByteCnt个字节给被控器
//被控器地址在SlvAdr中,单元地址在SubAdr中
//所发送数据的字节数在ByteCnt中,发送的数据在XmtDat缓冲区中
//发送数据正常返回标志ERR=0, ERR=1表示被控器无应答或损坏
//***********************************************************************************************

void I2CSendData ()
{
	unsigned char i;

//	SETB	RS0
	
	I2CSTA();						//发送I2C 总线起始条件

	I2CSendByte (SlvAdr);			//写一个字节
//	JB	ERR,I2CSRN		;错误返回
	I2CSendByte (SubAdr);
//	JB	ERR,I2CSRN
	for (i = 0; i < ByteCnt; i ++)	
	{
		I2CSendByte (XmtDat [i]);
		//	JB	ERR,I2CSRN
	}

	I2CSTOP	();		//发送I2C 总线停止条件

//	if (ERR == 1) test1 = 0;
}
/*************************************************************************************************
;接收数据程序
;名称:I2CRcvData
;描述:从被控器接收ByteCnt个字节数据
;被控器地址在SlvAdr中,单元地址在SubAdr中
;所接收数据的字节数在ByteCnt中,接收的数据在RcvDat缓冲区中
;接收数据正常返回标志ERR=0, ERR=1表示被控器无应答或损坏
;************************************************************************************************/

void I2CRcvData()
{
	unsigned char i;

//	SETB	RS0
	I2CSTA();					//发送I2C 总线起始条件
	I2CSendByte (SlvAdr);		//写入器件地址
//	JB	ERR,I2CRRN		;错误返回
	I2CSendByte (SubAdr);		//写入单元地址
//	JB	ERR,I2CRRN
	I2CSTA ();					//发送I2C 总线重复起始条件
	SlvAdr = SlvAdr | 0x01;
	I2CSendByte (SlvAdr);		//再次写入器件地址
//	JB	ERR,I2CRRN

	for (i = 0; i < ByteCnt; i ++) 	
	{
		RcvDat [i] = I2CRcvByte ();
		SDA	= 0;						//发送应答位
		SCL	= 1;						//250ns后置时钟线为高通知被控器开始接收应答位
		_nop_();						//保证时钟高周期大于4us
		_nop_();						
		_nop_();
		_nop_();	
		SCL	= 0;						//钳住I2C 总线以便继续接收字接数据

	}

	SDA = 1;					//发送非应答位
	SCL	= 1;					//250ns后置时钟线为高通知被控器开始接收非应答位
	_nop_();					//保证时钟高周期大于4us
	_nop_();
	_nop_();
	_nop_();
	SCL = 0;					//钳住I2C 总线以便发送停止条件
	SDA = 0;					//
	I2CSTOP ();
}


/*******************************************************************************
; 子程序
;******************************************************************************
;名称:I2CSTA
;描述:启动I2C 总线子程序--发送I2C 总线起始条件
;------------------------------------------------------------------------------
*/

void I2CSTA ()
{
	SCL = 0;
	SDA = 1;		//发送起始条件的数据信号
	SCL	= 1;		//250ns后发送起始条件的时钟信号
	_nop_();			//起始条件建立时间大于4.7us
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	SDA	= 0;		//发送起始信号
	_nop_();			//起始条件锁定时间大于4us
	_nop_();
	_nop_();
	_nop_();
	SCL = 0;		//钳住I2C 总线准备发送或接收数据
}

/*------------------------------------------------------------------------------
;名称:I2CSTOP
;描述:停止I2C 总线子程序--发送I2C 总线停止条件
;------------------------------------------------------------------------------
*/

void I2CSTOP ()
{
 	SDA	= 0;		//发送停止条件的数据信号
	SCL	= 1;		//250ns后发送停止条件的时钟信号
	_nop_();			//停止条件建立时间大于4us
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	SDA	= 1;		//发送I2C 总线停止信号
}

/*------------------------------------------------------------------------------
;名称:I2CSentByte
;描述:字节数据传送子程序--发送一个字节数据或地址给被控器
;要发送的数据在ACC中
;发送数据正常返回标志ERR=0,ERR=1表示被控器无应答或损坏.
;------------------------------------------------------------------------------
*/

void I2CSendByte (unsigned char _8563byte)
{
	unsigned char i;

	BitCnt = 0x08;		//向VSDA线上发送1个数据字节 
	for ( i = BitCnt; i > 0; i --)
	{
//		_nop_();
		SDA = (_8563byte >> (i - 1)) % 2; //发送数据位
		SCL	= 1;					//250ns后置时钟线为高通知被控器开始接收数据位
		_nop_();						//保证时钟高周期大于4us
		_nop_();
		_nop_();
		_nop_();
		SCL = 0;					//钳住时钟总线准备接收下一个数据位
		_nop_();						//保证时钟低周期大于4.7us
	 }
	_nop_();
	_nop_();
	SDA	= 1;						//8位发送完后释放数据线准备收应答位
	SCL	= 1;						//开始接收应答信号
//	_nop_();
	ERR = 0;
	if (SDA == 1) ERR = 1;
	SCL = 0;
}

/*------------------------------------------------------------------------------
;名称:I2CRcvByte
;描述:字节数据接收子程序--从被控器接收一个字节数据
;接收的字节数据在ACC中
;------------------------------------------------------------------------------*/

unsigned char I2CRcvByte ()
{
	unsigned char res, i;

 	BitCnt = 0x08;		//从VSDA线上读取1个数据字节 
	res = 0x00;

	for (i = 0; i < BitCnt; i ++)
	{
		SDA = 1;				//置数据线为输入方式
		SCL	= 1;				//置时钟线为高使数据线上数据有效
		res = (res << 1) | SDA;	//接收数据存入res
		SCL	= 0;				//接收结束钳住总线准备下一步接收或发送(非)应答位
		_nop_();					//时钟低周期大于4.7us
	}

	return res;
}

⌨️ 快捷键说明

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