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

📄 iic.c

📁 iic_at24c03_lc72131_redio用于FM
💻 C
字号:
/*
* I2C D-òé
* ′|àí?÷ààDí£oC51
* °?±?£o1 è??ú£o2006-12-13
*
* °?±?£o2 è??ú£o2006-12-28
* ê1ó?°?±?2Dè?¨ò?I2C_V2
* ?ü??£o?°I2CWriteBunch?±·?·¨·??a?°dat?±2?êy?aêy?Yμ??·?°datAdd?±oí?°dat?±£?è¥3yá?2?êyautoStop
*
* ×÷??£o??μ?í?<yangdewang@gmail.com>

* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.  Or, point your browser to
* http://www.gnu.org/copyleft/gpl.html
*/
#include <intrins.h>
#include <global.h>
#include "iic.h"
#include "delay.h"

//#define DEBUG_IIC

#define clSCL()		(SCL_I2C = false)
#define setSCL()	(SCL_I2C = true)
#define clSDA()		(SDA_I2C = false)
#define setSDA()	(SDA_I2C = true)
/*
void clSCL()		{SCL_I2C = false;}
void setSCL()	{SCL_I2C = true;}
void clSDA()		{SDA_I2C = false;}
void setSDA()	{SDA_I2C = true;}*/
#if (IIC_WAITCYCLE>0)
bool waitSCL(uint8 c)//μè′y?y?ùéè±?,c?a0μè′yê±??×?3¤
{
	do
	{
		if(SCL_I2C == 1)return true;
	}
	while(--c);
	return false;//μè′y3?ê±
}
#else
#define waitSCL(x) SCL_I2C
#endif
bool waitAnswer()//μè′y?ìó|//·μ??oóSCL_I2C=1,SDA_I2C=1
{
	clSCL();//T.hd,dat?ó3ù5us//êy?Y±£3?ê±??//±ê×?IIC?a0us
	//Delay(0);
	setSDA();
	setSCL();
	if(waitSCL(IIC_WAITCYCLE))
	{
		if(SDA_I2C == 0)
			return true;
	}
	return false;
}
bool sendAnswer()
{
	clSDA();
	setSCL();
	if(!waitSCL(IIC_WAITCYCLE))
		return false;//μè′y3?ê±
	clSCL();
	setSDA();
	return true;
}
static bool write(uint8 add)//D′ò???×??úμ?×ü??//ê§°üoóSCL_I2C=1,SDA_I2C=1//3é1|SCL_I2C=1,SDA_I2C?′?¨
{				    //è?1?ê§°ü??·¢?íí£?1?ò??D??aê?D?o?£?μ?ò2??????ê§è¥?ù2?μ??é??
	bool sdav;
	uint8 i=8;
	do
	{
		clSCL();//T.hd,dat?ó3ù5us//êy?Y±£3?ê±??//±ê×?IIC?a0us
#if 0
		ACC = add;
#pragma asm
		//_RLC_();
		RLC A
#pragma endasm
			add = ACC;
#else
		add=(add<<1);//×¢òa£oê1ó?á?Cì???é???μ?′ú????è·±£?éò?ì???
#endif
		SDA_I2C = CY;//T.su,dat?ó3ù250ns//êy?Y?¨á¢ê±??
		sdav= CY;
		setSCL();//T.hgih?ó3ù4us SCL_I2Cê±?óμ???μ????ü?ú
		if(!waitSCL(IIC_WAITCYCLE))
			goto er;//μè′y3?ê±
#ifdef IIC_MULTI_MATER
		if(SDA_I2C != sdav)
		{
			goto er;//ê§è¥?ù2?
		}
#endif
	}while(--i);
	//SCL_I2C is 1

	return true;
er:
	//setSDA();
	return false;
}
bool read(uint8* dat)//?áò???×??ú′ó×ü??//ê§°üoóSCL_I2C=1,SDA_I2C=1//3é1|SCL_I2C=0,SDA_I2C=1
{
	uint8 datm = 0;
	uint8 i=8;
	clSCL();//T.hd,dat?ó3ù5us//êy?Y±£3?ê±??//±ê×?IIC?a0us
	do
	{
		setSCL();
		if(!waitSCL(IIC_WAITCYCLE))
			goto er;//μè′y3?ê±
#if 0
		CY  = SDA_I2C;//T.hgih?ó3ù4us SCL_I2Cê±?óμ???μ????ü?ú
		ACC = datm;
#pragma asm
		//_RLC_();
		RLC A
#pragma endasm
			datm= ACC;
#else
		datm=datm<<1;
		if(SDA_I2C)datm++;
#endif
		clSCL();//T.hd,dat?ó3ù5us//êy?Y±£3?ê±??//±ê×?IIC?a0us
	}while(--i);
	*dat = datm;
	return true;
er:
	return false;
}
void IICStop() //·¢?íí£?1D?o?
{
	clSCL();
	clSDA();
	setSCL();
	waitSCL(IIC_WAITCYCLE);//í£?1ì??tμ??¨á¢ê±???ó3ù 4.7us
#if (_CPU_INSTRUCTION_CLOCK_)>(1000000/5)
	_delay_us(5);
#endif
	setSDA();
}
//?°?·′ó?ú add μ??·/r_w?á/D′:true=read//·μ??oóSCL_I2C=1,SDA_I2C=1
bool I2CStart(uint8 add,bool r_w)
{
#ifdef IIC_MULTI_MATER
	//todo:2é?ˉ×ü?????D
#endif
	setSDA();
	setSCL();//Start Setup Time 4.7us
#if (_CPU_INSTRUCTION_CLOCK_)>(1000000/5)
	_delay_us(5);
#endif
	clSDA();
#if 0
	CY 	= r_w;
	ACC = add;
#pragma asm
	//_RLC_();
	RLC A
#pragma endasm
		add = ACC;
#else
	add=add<<1;
	if(r_w)add++;
#endif
	//	Delay(0);//?ó3ù
	/*if(!write(add))
	{
	setSDA();
	setSCL();
	return false;
	}*/

	return write(add)&&waitAnswer();
}
#ifdef I2C_V2
/***************************************************
D′ò???×??ú′?μ????¨éè±?
add:	éè±?μ??·
datAdd:	êy?Yμ??·
dat:	êy?Yê××??ú????
count:	′?3¤?è
autoStop:=true???ú3é1|?áê?oó2úéúí£?1D?o?
return:	3é1|D′è?×??úêy
*****************************************************/
uint8 I2CWriteBunch(uint8 add,uint8 datAdd,uint8* dat,uint8 count)
{
	uint8 i=0;
	if(I2CStart(add,0))
	{
		write(datAdd);
		if(!waitAnswer())goto end;
		for(;i<count;i++)
			if(!write(dat[i])||!waitAnswer())
				goto end;
	}
end:
	IICStop();
	return i;
}
/***************************************************
?áò???×??ú′?′óéè±?
devAdd:	éè±?μ??·
datAdd:	êy?Yμ??·
dat:	êy?Yê××??ú????
count:	′?3¤?è
return:	3é1|?áè?×??úêy
*****************************************************/
uint8 I2CReadBunch(uint8 devAdd,uint8 datAdd,uint8* dat,uint8 count)
{
	if(I2CStart(devAdd,0))
	{
		write(datAdd);
		if(!waitAnswer())return 0;
		clSCL();//?áê?′ó?úμ??ìó|D?o?
		return I2CReadStream(devAdd,dat,count);
	}
	return 0;
#if 0
	uint8 i = 0;
	if(I2CStart(devAdd,0))
	{
		write(datAdd);
		if(!waitAnswer())goto re;
		clSCL();//?áê?′ó?úμ??ìó|D?o?
		if(I2CStart(devAdd,1))
		{
			while(i<count-1)
			{
				if(!read(dat)||!sendAnswer())
				{
					goto re;
				}
				dat++;
				i++;
			}
			if(read(dat))i++;
		}
	}

re:	setSCL();//2??ìó|D?o?
	waitSCL(IIC_WAITCYCLE);
	//Delay(0);
	IICStop(); //·¢?íí£?1D?o?
	return i;
#endif
}
/***************************************************
?áò???×??ú′?′óéè±?
′?·?·¨????2?ó?ìá1?êy?Yμ??·μ?éè±??òá?D??áè?
devAdd:	éè±?μ??·
dat:	êy?Yê××??ú????
count:	′?3¤?è
return:	3é1|?áè?×??úêy
*****************************************************/
uint8 I2CReadStream(uint8 devAdd,uint8* dat,uint8 count)
{
	uint8 i;
	if(count==0)
		return 0;
	i= count-1;
	if(I2CStart(devAdd,1))
	{
		while(i)
		{
			if(!read(dat)||!sendAnswer())
			{
				goto re;
			}
			dat++;
			i--;
		}
		if(!read(dat))i++;
	}
re:	setSCL();//2??ìó|D?o?
	waitSCL(IIC_WAITCYCLE);
	//Delay(0);
	IICStop(); //·¢?íí£?1D?o?
	return count-i;
}
#else//I2C_V2
uint8 I2CWriteBunch(uint8 add,uint8* dat,uint8 count,bool autoStop)//D′ò???×??ú′?μ????¨éè±? 1:éè±?μ??· 2:êy?Yê××??ú???? 3£o′?3¤?è autoStop=true:???ú3é1|?áê?oó2úéúí£?1D?o? re£o3é1|D′è?×??úêy
{
	uint8 i=0;
	if(I2CStart(add,0))
	{
		for(;i<count;i++)
		{
			if(!write(dat[i]))
				goto end;
			if(!waitAnswer())
				goto end;
		}
	}
	else
	{
		goto rt;
	}
end:
	if(autoStop)
		IICStop();
rt:
	return i;
}

#ifdef I2C_WRITEBYTE_U
bool I2CWriteByte(uint8 add,uint8 dat)//D′ò???×??úμ????¨éè±?
{
	return I2CWriteBunch(add,&dat,1,true); //todo
}
#endif//I2C_WRITEBYTE_U
uint8 I2CReadBunch(uint8 devAdd,uint8 datAdd,uint8* dat,uint8 count)//?áò???×??ú′?′óéè±?divAdd:éè±?μ??· datAdd:êy?Yê××??úμ??· dat:êy?Yê××??ú???? count£o′?3¤?è re£o3é1|?áè?×??úêy
{
	uint8 i = 0;
	if(I2CWriteBunch(devAdd,&datAdd,1,false))
	{
		clSCL();//?áê?′ó?úμ??ìó|D?o?
		if(I2CStart(devAdd,1))
		{
			while(i<count-1)
			{
				if(!read(dat)||!sendAnswer())
				{
					goto re;
				}
				dat++;
				i++;
			}
			if(read(dat))i++;
		}
	}
re:	setSCL();//2??ìó|D?o?
	waitSCL(IIC_WAITCYCLE);
	//Delay(0);
	IICStop(); //·¢?íí£?1D?o?
	return i;
}
#endif//I2C_V2

⌨️ 快捷键说明

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