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

📄 pcf8583.c

📁 通过DSP对电池的各种状态信息进行采集
💻 C
字号:
// 软件延时子程序 
void delay()
{
	nop();nop();nop();//int  i;
	//for(i=0X07D;i--;)	{	i=i;}
}
// 启动I2C总线子程序 
void START()
{
	*PFDATDIR=*PFDATDIR|0X03;		// SDA=SCL=1 
	delay( );							// 软件延时,以使时序匹配 
	*PFDATDIR=*PFDATDIR&0X0FFFD;	// SDA=0 
	delay();							// 软件延时,以使时序匹配 
	*PFDATDIR=*PFDATDIR&0X0FFFE;		// SCL=0 
	delay();							// 软件延时,以使时序匹配 
}
// 发送字节子程序 
void TRANSMIT(int TRAN)
{
	int flag,sz;						// 定义需要的局部变量 
	*PFDATDIR=*PFDATDIR&0X0FFFE;		// SCL=0    
	delay();							// 软件延时,以使时序匹配 
	for(flag=0x0080;flag!=0x00;flag=flag/2)	
	{
		sz=TRAN&flag;				// 屏蔽掉不需要的位 
		if(sz==0)	*PFDATDIR=*PFDATDIR&0X0FFFD;// 如果相应的位为0,则SDA=0 
		else	*PFDATDIR=*PFDATDIR|0X02;// 如果相应的位为1,则SDA=1 
		delay();						// 软件延时,以使时序匹配 
		*PFDATDIR=*PFDATDIR|0X01;	// SCL=1 
		delay();						// 软件延时,以使时序匹配 
		*PFDATDIR=*PFDATDIR&0X0FFFE;	// SCL=0 
		delay();						// 软件延时,以使时序匹配 
	}
}
// 从机(即PCF8583芯片)应答子程序。返回值为0时,代表操作成功;返回值为1时,代表操作失败 
int	SLAVE_ACK()
{
	int sz,k=0;					// 定义所需要的局部变量 
	*PFDATDIR=*PFDATDIR|0X02;		// SDA=1 
	delay();							// 软件延时,以使时序匹配 
	*PFDATDIR=*PFDATDIR&0X0FDFF;	// 设置IOPC5(SDA)为输入 
	delay();							// 软件延时,以使时序匹配 
	*PFDATDIR=*PFDATDIR|0X01;		// SCL=1 
	delay();							// 软件延时,以使时序匹配 
	sz=*PFDATDIR&0X0002;				// 检测数据位 
	if(sz==0X0020)  k=1;				// 如果数据位为1,则证明失败,则令k=1 
	else  k=0;  	 					// 如果数据位为0,则证明成功,则保持k=0不变 
	*PFDATDIR=*PFDATDIR|0X0200;		// 设置IOPC5(SDA)为输出 
	*PFDATDIR=*PFDATDIR&0X0FFFC;	// SCL=SDA=0 
	return(k);
}
// I2C停止子程序 
void    STOP()
{ 
	*PFDATDIR=*PFDATDIR&0X0FFFD;	// SDA=0 
	delay();
	*PFDATDIR=*PFDATDIR|0X0001;		// SCL=1 
	delay( );							// 软件延时,以使时序匹配 
	*PFDATDIR=*PFDATDIR|0X0002;		// SDA=1 
}
// 字节写子程序,即向I2C器件写1个字节的数据,入口为地址BYTE_ADDR和需要写入的字节
// 内容T_DATA。返回值为0时,代表操作成功;返回值为1时,代表操作失败 
int	BYTE_WR(int BYTE_ADDR,int T_DATA)
{
	int  k;
	START();							// 启动I2C总线 
	TRANSMIT(0X0A0);					// 送写控制字 
	k=SLAVE_ACK();					// 从机(即PCF8583芯片)应答 
	if(k==0)	 TRANSMIT(BYTE_ADDR);	// 送出地址 
	if(k==0)	 k=SLAVE_ACK();			// 从机(即PCF8583芯片)应答 
	if(k==0)	TRANSMIT(T_DATA);		// 送出需要保存的数据 
	if(k==0)	k=SLAVE_ACK();			// 从机(即PCF8583芯片)应答 
	if(k==0)	STOP();					// 设置停止状态 
	return(k);
}
// 接收一个字节子程序,出口为接收到的数据R_DATA 
int RECEIVE()	
{
	int  R_DATA=0,sz,i;
	*PFDATDIR=*PFDATDIR&0X0FDFF;	// 设置IOPC5(SDA)为输入 
	*PFDATDIR=*PFDATDIR&0X0FFFE;		// SCL=0 
	delay();							// 软件延时,以使时序匹配  
	for(i=0;i<8;i++)	
	{
		R_DATA=R_DATA<<1;			// R_DATA左移一位 
		*PFDATDIR=*PFDATDIR|0X0001;	// SCL=1 
		delay();						// 软件延时,以使时序匹配   
		sz=*PFDATDIR&0X0002;			// 取得相应的数据位 
		if(sz==0)	 R_DATA=R_DATA&0XFFFE;	// 如果数据位为0,则R_DATA最低位清0 
		else  R_DATA=R_DATA|0x0001;		// 如果数据位为1,则R_DATA最低位置1 
		*PFDATDIR=*PFDATDIR&0X0FFFE;		// SCL=0 
		delay();							// 软件延时,以使时序匹配  
	}
	*PFDATDIR=*PFDATDIR|0X0200;		// 设置IOPC5(SDA)为输出 
	return(R_DATA);					// 返回接收的字节 
}
// 主机无应答信号子程序 
void NO_ACK()
{
	*PFDATDIR=*PFDATDIR|0X0001;		// SCL=1 
	delay();							// 软件延时,以使时序匹配 
	*PFDATDIR=*PFDATDIR&0X0FFFE;		// SCL=0 
}
// 主机应答子程序 
void MASTER_ACK()
{
	*PFDATDIR=*PFDATDIR&0X0FFFE;		// SCL=0 
	*PFDATDIR=*PFDATDIR&0X0FFFD;	// SDA=0 
	*PFDATDIR=*PFDATDIR|0X0001;		// SCL=1 
	delay();							// 软件延时,以使时序匹配 
	*PFDATDIR=*PFDATDIR&0X0FFFE;		// SCL=0 
}
// 字节读子程序,即从I2C器件读出1个字节的数据,入口为需要读出的地址BYTE_ADDR,出口
// 为读出的数据R_DATA,通过C语言的参数传递功能实现。返回值为0X0FFFF时,表示操作失败;
// 否则操作成功 
int	BYTE_RD(int  BYTE_ADDR)
{
	int	k,R_DATA;
	START();						// 启动I2C总线 
	TRANSMIT(0XA0);				// 送出写控制字,以写入地址字节 
	k=SLAVE_ACK( );				// 从机(即PCF8583芯片)应答 
	if(k==0)	TRANSMIT(BYTE_ADDR);// 送出需要读出数据的地址 
	k=SLAVE_ACK();				// 从机(即PCF8583芯片)应答 
	if(k==0)  
	{
		START( );					// 启动I2C总线 
	TRANSMIT(0XA1);
	}							// 送出读控制字 
	k=SLAVE_ACK();				// 从机(即PCF8583芯片)应答 
	if(k==0)	
	{
		R_DATA=RECEIVE();		// 接收PCF8583发出的数据 
		NO_ACK();				// 主机不作应答 
		STOP();					// 设置停止状态 
	}
	if(k==0)  return(R_DATA);			// 返回一个读出的数据 
	else   return(0X0FFFF);			// 如果整个读过程有误,则返回0X0FFFF 
}
// 连续写子程序,入口为需要写的起始地址ADDR,存储需要写入数据的数组的首地址ARRY,需要
// 写入的数据的个数N 
int	CON_WR(int ADDR,int* ARRAY,int N)
{
	int	k;
	START();						// 启动I2C总线 
	TRANSMIT(0X0A0);				// 送写控制字 
	k=SLAVE_ACK();				// 从机(即PCF8583芯片)应答 
	if(k==0) TRANSMIT(ADDR);	// 送出要写数据的起始地址 
	if(k==0) k=SLAVE_ACK();		// 从机(即PCF8583芯片)应答 
	if(k==0)	 
	{
	for(;N>0;N--,ARRAY++)	
	{ 
		TRANSMIT(*ARRAY);	// 送出需要保存的数据,保存在数组ARRAY中 
		k=SLAVE_ACK();		// 从机(即PCF8583芯片)应答,地址自动加1 
		if(k==1)	break;
	}
	}
	STOP();						// 设置停止状态 
	return(k);
}
// 连续读子程序,入口为需要读的起始地址ADDR,存储读出数据的数组首地址ARRY,需要读出的
// 数据的个数N 
int	CON_RD(int ADDR,int* ARRAY,int N)
{
	int	k,R_DATA;
	START();						// 启动I2C总线 
	TRANSMIT(0XA0);				// 送出写控制字,以写入地址字节 
	k=SLAVE_ACK();				// 从机(即PCF8583芯片)应答 
	if(k==0)	TRANSMIT(ADDR);		// 送出需要读出数据的地址 
	k=SLAVE_ACK();				// 从机(即PCF8583芯片)应答 
	if(k==0)	
	{
		START();					// 启动I2C总线 
		TRANSMIT(0XA1);
	}							// 送出读控制字 
	k=SLAVE_ACK();				// 从机(即PCF8583芯片)应答 
	if(k==0)	
	{
		for(;N>1;N--,ARRAY++)	
		{
			R_DATA=RECEIVE();	// 接收PCF8583发出的数据 
			*ARRAY=R_DATA;		// 读出的数据存入数组 
			MASTER_ACK();		// 主机应答,地址自动加1   
		}
		R_DATA=RECEIVE();		// 接收PCF8583发出的数据        
		*ARRAY=R_DATA;			// 读出的数据存入数组 
		NO_ACK();				// 主机不作应答 
		STOP();					// 设置停止状态 
	}
	return(k);						// k=0时表示操作成功,k=1时表示操作失败 
}
//连续写入N个浮点数
int	CON_WRF(int ADDR,float* ARRAY,int N)
{
	int i,ch[4];
	for(i=0;i<N;i++,ARRAY++)
	{
		int* p=(int*)ARRAY;
		ch[0]=*p&0x00FF;
		ch[1]=(*p&0xFF00)>>8;
		p++;
		ch[2]=*p&0x00FF;
		ch[3]=(*p&0xFF00)>>8;
		CON_WR(ADDR+4*i,ch,4);
	}
}
//连续读出N个浮点数
int	CON_RDF(int ADDR,float* ARRAY,int N)
{
	int *p,i,ch[4];
	for(i=0;i<N;i++,ARRAY++)
	{
		CON_RD(ADDR+4*i,ch,4);
		*p=ch[0];
		*p=*p|(ch[1]<<8);
		p++;
		*p=ch[2];
		*p=*p|(ch[3]<<8);
		p--;
		ARRAY=(float*)p;
	}
}
//计算时间差ARRAY1-ARRAY2精确到分
int CalPlaceTime(int *ARRAY1,int *ARRAY2)

{
/*	int Ratio[7]=[0, 0, 1, 60, 24*60, 30*24*60, 12*30*24*60];//毫秒、秒、分、...
	int k=0, i;
	for(i=0; i<7;i++, ARRAY1++,ARRAY2++)
	{
		if(*ARRAY1-*ARRAY2)
			k+=(*ARRAY1-*ARRAY2)*Ratio[i];
	}*/
	if(*(ARRAY1+6)-*(ARRAY2+6))	return 0x7FFF;
	else if(*(ARRAY1+5)-*(ARRAY2+5))	return 0x7FFF;
	else if(*(ARRAY1+4)-*(ARRAY2+4))	return 0x7FFF;
	else if(*(ARRAY1+3)-*(ARRAY2+3))	return (*(ARRAY1+3)-*(ARRAY2+3))*60+(*(ARRAY1+2)-*(ARRAY2+2));
	else return (*(ARRAY1+2)-*(ARRAY2+2));
}

⌨️ 快捷键说明

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