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

📄 i2c_slaver.c

📁 I2C slaver 的8051源码
💻 C
字号:
#include	"STC11L60XE.h"
#include  "INTRINS.H"
#include "globe.h"

bit 	SDA_LEVEL;
bit 	CLK_LEVEL;
bit 	SDA_LEVEL_BAK;

bit	Buffer_Return = 0;


extern unsigned char  xdata SDA_DATA[];


void Recevie_Byte( unsigned char *Recevie_Pointer);

unsigned int Byte_var1 = 0;
unsigned int var = 0;

void Recevie_Byte1(void)
{		
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 0)//等待CLK 的0完成
	{
		if(TF0 == 1)
			{				
				return;
			}
			
	}	
	//读 BYTE1 的第1 位			
	SDA_LEVEL = SDA_PIN;//读SDA数据	
	
	if(SDA_LEVEL == 1)
		{
			SDA_DATA[var]  |= 0x01;
			SDA_DATA[var] = SDA_DATA[var] << 1;
		}
	else
		{
			SDA_DATA[var]  &= 0xfe;
			SDA_DATA[var] = SDA_DATA[var] << 1;
		}				

	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 1)//等待CLK 的 1完成
	{
		if(TF0 == 1)
			{				
				return;
			}
			
	}
	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 0)//等待CLK 的0完成
	{
		if(TF0 == 1)
			{				
				return;
			}
			
	}	

	//读 BYTE1 的第2 位
	SDA_LEVEL = SDA_PIN;//读SDA数据
	if(SDA_LEVEL == 1)
		{
			SDA_DATA[var]  |= 0x01;
			SDA_DATA[var] = SDA_DATA[var] << 1;
		}
	else
		{
			SDA_DATA[var]  &= 0xfe;
			SDA_DATA[var] = SDA_DATA[var] << 1;
		}	
	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 1)//等待CLK 的 1完成
	{
		if(TF0 == 1)
			{				
				return;
			}
			
	}		
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 0)//等待CLK 的0完成
	{
		if(TF0 == 1)
			{				
				return;
			}
			
	}
	
	//读 BYTE1 的第3 位
	SDA_LEVEL = SDA_PIN;//读SDA数据
	if(SDA_LEVEL == 1)
		{
			SDA_DATA[var]  |= 0x01;
			SDA_DATA[var] = SDA_DATA[var] << 1;
		}
	else
		{
			SDA_DATA[var]  &= 0xfe;
			SDA_DATA[var] = SDA_DATA[var] << 1;
		}	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 1)//等待CLK 的1完成
	{
		if(TF0 == 1)
			{				
				return;
			}
			
	}	
	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 0)//等待CLK 的0完成
	{
		if(TF0 == 1)
			{				
				return;
			}
			
	}
	
	//读 BYTE1 的第4 位
	SDA_LEVEL = SDA_PIN;//读SDA数据
	if(SDA_LEVEL == 1)
		{
			SDA_DATA[var]  |= 0x01;
			SDA_DATA[var] = SDA_DATA[var] << 1;
		}
	else
		{
			SDA_DATA[var]  &= 0xfe;
			SDA_DATA[var] = SDA_DATA[var] << 1;
		}	
	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 1)//等待CLK 的1完成
	{
		if(TF0 == 1)
			{
				
				return;
			}
			
	}
	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 0)//等待CLK 的0完成
	{
		if(TF0 == 1)
			{				
				return;
			}
			
	}
	
	//读 BYTE1 的第5 位
	SDA_LEVEL = SDA_PIN;//读SDA数据
	if(SDA_LEVEL == 1)
		{
			SDA_DATA[var]  |= 0x01;
			SDA_DATA[var] = SDA_DATA[var] << 1;
		}
	else
		{
			SDA_DATA[var]  &= 0xfe;
			SDA_DATA[var] = SDA_DATA[var] << 1;
		}	
	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 1)//等待CLK 的 1完成
	{
		if(TF0 == 1)
			{				
				return;
			}
			
	}
	
	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 0)//等待CLK 的0完成
	{
		if(TF0 == 1)
			{				
				return;
			}
			
	}
	
	//读 BYTE1 的第6 位
	SDA_LEVEL = SDA_PIN;//读SDA数据
	if(SDA_LEVEL == 1)
		{
			SDA_DATA[var]  |= 0x01;
			SDA_DATA[var] = SDA_DATA[var] << 1;
		}
	else
		{
			SDA_DATA[var]  &= 0xfe;
			SDA_DATA[var] = SDA_DATA[var] << 1;
		}	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 1)//等待CLK 的1完成
	{
		if(TF0 == 1)
			{				
				return;
			}
			
	}	
	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 0)//等待CLK 的0完成
	{
		if(TF0 == 1)
			{				
				return;
			}			
	}	
	
	//读 BYTE1 的第7 位
	SDA_LEVEL = SDA_PIN;//读SDA数据
	if(SDA_LEVEL == 1)
		{
			SDA_DATA[var]  |= 0x01;
			SDA_DATA[var] = SDA_DATA[var] << 1;
		}
	else
		{
			SDA_DATA[var]  &= 0xfe;
			SDA_DATA[var] = SDA_DATA[var] << 1;
		}	
	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 1)//等待CLK 的 1完成
	{
		if(TF0 == 1)
			{				
				return;
			}
			
	}	
	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 0)//等待CLK 的0完成
	{
		if(TF0 == 1)
			{				
				return;
			}
			
	}
	
	//读 BYTE1 的第8 位
	SDA_LEVEL = SDA_PIN;//读SDA数据
	if(SDA_LEVEL == 1)
		{
			SDA_DATA[var]  |= 0x01;
			
		}
	else
		{
			SDA_DATA[var]  &= 0xfe;
		}
	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 1)//等待CLK 的 1完成
	{
		if(TF0 == 1)
			{				
				return;
			}			
	}
		
	
	//处理应答
	_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
	SDA_PIN = 0;//应答
	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 0)//等待CLK 应答0 的完成
	{
		if(TF0 == 1)
			{
				
				return;
			}
			
	}	

	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 1)//等待CLK 应答的 1完成
	{
		if(TF0 == 1)
			{				
				return;
			}			
	}
	
	SDA_PIN = 1;//应答完成,释放SDA
	
	//检测是否stop
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;	
	TF0 = 0;
	while(CLK_PIN == 0)//等待CLK 0 的完成
	{
		if(TF0 == 1)
			{				
				return;
			}
			
	}
	
	//CLK的0完成了, 接下来检测是否在1期间SDA有上升沿

	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;	
	TF0 = 0;		
	
	SDA_LEVEL= SDA_PIN;		
	if(SDA_LEVEL == 1) 
		{
			SDA_LEVEL_BAK = 1;
			while(CLK_PIN == 1)//如果 第一次就是1,肯定不是stop,等待1完
				{
					if(TF0 == 1)
					{
						return;
					}
				}
		}
	else//(SDA_LEVEL == 0) 
		{
			SDA_LEVEL_BAK = 0;
			while(CLK_PIN == 1)//等1 
				{
					if(TF0 == 1)
						{
							return;
						}
					SDA_LEVEL= SDA_PIN;			
	
					if(SDA_LEVEL == 1)
						{
							return;
						}							
				}					
		}	
	Recevie_Byte((&SDA_DATA[var + 1]));			
	
}

void Recevie_Byte( unsigned char *Recevie_Pointer)
{			
	//Recevie_Pointer++;			
	if(SDA_LEVEL_BAK== 1)
		{
			*Recevie_Pointer  |= 0x01;
			*Recevie_Pointer =*Recevie_Pointer << 1;
		}
	else
		{
			*Recevie_Pointer  &= 0xfe;
			*Recevie_Pointer =*Recevie_Pointer << 1;
		}		
	
	///////////////////////////////////////
	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 0)//等待CLK 的0完成
	{
		if(TF0 == 1)
			{
				return;
			}
			
	}		
	
	SDA_LEVEL = SDA_PIN;//读SDA数据
	if(SDA_LEVEL== 1)
		{
			*Recevie_Pointer  |= 0x01;
			*Recevie_Pointer =*Recevie_Pointer << 1;
		}
	else
		{
			*Recevie_Pointer  &= 0xfe;		
			*Recevie_Pointer =*Recevie_Pointer << 1;
		}
	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 1)//等待CLK 的 1完成
	{
		if(TF0 == 1)
			{
				return;
			}
			
	}				
	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 0)//等待CLK 的0完成
	{
		if(TF0 == 1)
			{
				return;
			}
			
	}
				
	SDA_LEVEL = SDA_PIN;//读SDA数据
	if(SDA_LEVEL== 1)
		{
			*Recevie_Pointer  |= 0x01;
			*Recevie_Pointer =*Recevie_Pointer << 1;
		}
	else
		{
			*Recevie_Pointer  &= 0xfe;
			*Recevie_Pointer =*Recevie_Pointer << 1;
		}
	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 1)//等待CLK 的 1完成
	{
		if(TF0 == 1)
			{
				return;
			}
			
	}
				
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 0)//等待CLK 的0完成
	{
		if(TF0 == 1)
			{
				return;
			}
			
	}			
	
	SDA_LEVEL = SDA_PIN;//读SDA数据
	if(SDA_LEVEL== 1)
		{
			*Recevie_Pointer  |= 0x01;
			*Recevie_Pointer =*Recevie_Pointer << 1;
		}
	else
		{
			*Recevie_Pointer  &= 0xfe;	
			*Recevie_Pointer =*Recevie_Pointer << 1;
		}
	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 1)//等待CLK 的 1完成
	{
		if(TF0 == 1)
			{
				return;
			}
			
	}			
	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 0)//等待CLK 的0完成
	{
		if(TF0 == 1)
			{
				return;
			}
			
	}
	
	SDA_LEVEL = SDA_PIN;//读SDA数据
	if(SDA_LEVEL== 1)
		{
			*Recevie_Pointer  |= 0x01;
			*Recevie_Pointer =*Recevie_Pointer << 1;
		}
	else
		{
			*Recevie_Pointer  &= 0xfe;
			*Recevie_Pointer =*Recevie_Pointer << 1;
		}
	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 1)//等待CLK 的1完成
	{
		if(TF0 == 1)
			{
				return;
			}
			
	}			
	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 0)//等待CLK 的0完成
	{
		if(TF0 == 1)
			{
				return;
			}
			
	}
	
	SDA_LEVEL = SDA_PIN;//读SDA数据
	if(SDA_LEVEL== 1)
		{
			*Recevie_Pointer  |= 0x01;
			*Recevie_Pointer =*Recevie_Pointer << 1;
		}
	else
		{
			*Recevie_Pointer  &= 0xfe;
			*Recevie_Pointer =*Recevie_Pointer << 1;
		}
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 1)//等待CLK 的 1完成
	{
		if(TF0 == 1)
			{
				return;
			}
			
	}
	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 0)//等待CLK 的0完成
	{
		if(TF0 == 1)
			{
				return;
			}
			
	}
	
	SDA_LEVEL = SDA_PIN;//读SDA数据
	if(SDA_LEVEL== 1)
		{
			*Recevie_Pointer  |= 0x01;
			*Recevie_Pointer =*Recevie_Pointer << 1;
		}
	else
		{
			*Recevie_Pointer  &= 0xfe;
			*Recevie_Pointer =*Recevie_Pointer << 1;
		}
	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TR0  = 1; 
	TF0 = 0;
	while(CLK_PIN == 1)//等待CLK 的 1完成
	{
		if(TF0 == 1)
			{
				return;
			}
			
	}
	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 0)//等待CLK 的0完成
	{
		if(TF0 == 1)
			{
				return;
			}
			
	}			
				
	SDA_LEVEL = SDA_PIN;//读SDA数据
	if(SDA_LEVEL == 1)
		{
			*Recevie_Pointer  |= 0x01;
			
		}
	else
		{
			*Recevie_Pointer  &= 0xfe;
		}
	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 1)//等待CLK 的 1完成
	{
		if(TF0 == 1)
			{
				return;
			}
			
	}		
	
	//处理应答
	_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
	SDA_PIN = 0;//应答
	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 0)//等待应答的 CLK 的0完成
	{
		if(TF0 == 1)
			{
				return;
			}
			
	}
	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 1)//等待应答的CLK的1完成
	{
		if(TF0 == 1)
			{
				return;
			}
			
	}
	
	SDA_PIN = 1;//完成应答,

	//检测是否stop
	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;			
	TF0 = 0;
	while(CLK_PIN == 0)//等待CLK 0 的完成
	{
		if(TF0 == 1)
			{
				return;
			}
			
	}
	//CLK的0完成了, 接下来检测是否在1期间SDA有上升沿

	TH0 =0xed;//18.432MHz晶体,16位方式3ms
	TL0 =0xef;	
	TF0 = 0;		
	SDA_LEVEL= SDA_PIN;	
	if(SDA_LEVEL == 1) 
		{
			SDA_LEVEL_BAK = 1;
			while(CLK_PIN == 1)//如果 第一次就是1,肯定不是stop,等待1完
				{
					if(TF0 == 1)
					{
						return;
					}
				}
		}
	else//(SDA_LEVEL == 0) 
	{
		SDA_LEVEL_BAK = 0;
		while(CLK_PIN == 1)//等和读
			{
				if(TF0 == 1)
					{
						return;
					}
				SDA_LEVEL= SDA_PIN;
				
				if(SDA_LEVEL == 1)//是stop
					{
/*
					Recevie_Pointer--;
					SBUF = *Recevie_Pointer;
					while(TI == 0);
					TI = 0;
					
					*Recevie_Pointer = 0;
					
					Recevie_Pointer++;
					SBUF = *Recevie_Pointer;
					while(TI == 0);
					TI = 0;
					
					*Recevie_Pointer = 0;*/
						var = (Recevie_Pointer - SDA_DATA) + 1;//需要更新var给下一次中断Recevie_Byte()调用

						Byte_var1= (Recevie_Pointer - SDA_DATA) ;//必须要的
						//if(Byte_var1 >= 199)//就是0-199,返回到buffer开头放入数据
						if(Byte_var1 >= (Buffer_Len - 1))
						{
								Buffer_Return = 1;//返回标记置位
								var = 0;
							}
						return;
					}							
			}
			
	}
	Recevie_Pointer++;
	Byte_var1= (Recevie_Pointer - SDA_DATA) ;
	//if(Byte_var1 > 199)//就是0-199(共200字节),返回到buffer开头放入数据
	if(Byte_var1 > (Buffer_Len - 1))
	{
			Recevie_Pointer = SDA_DATA;
	}										
	Recevie_Byte(Recevie_Pointer);
}



void INT0_SDA_INT(void) interrupt 0 using 1
{
	/***************************************************

	//SDA 下降沿产生 了我们看SCL  是否为1

  	//SDA --------\                   /-----------\                                
  		         	     \________/____________\____...........

	//SCL--------------\              /------\                           
					       \______/              \______...........

	*****************************************************/
		
	//LED1 = !LED1; //已经进入中断	
	
	EX0 = 0;//关外部0 (SDA)中断
	CLK_LEVEL = CLK_PIN;
	if(CLK_LEVEL == 1)//SDA下降沿时SCL为1,说明I2C start开始了
		{			
			//LED2 = 0;//是start			
			TH0 =0xed;//18.432MHz晶体,16位方式3ms
			TL0 =0xef;			
			TF0 = 0;
			while(CLK_PIN == 1)//等待CLK 的start 1完成
			{
				if(TF0 == 1)
					{
						goto end;						
					}
					
			}			
			Recevie_Byte1();								
		}
	else
		{
			EX0 = 1;
			//LED2 = 1;//不是start
		}
	end:
	EX0 = 1;
	//LED1 = 1;	
}

#if 0
void T0_INT(void)  interrupt 1 using 2
{
	
	TH0 =0xed;//18.432MHz晶体,16位方式3ms,重装计数初值
	TL0 =0xef;
}
#endif


⌨️ 快捷键说明

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