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

📄 iic.c

📁 凌阳单片机(SPCE061A)IIC总线驱动程序
💻 C
字号:
//=================================================================
//
//IIC.C开始
//
//=================================================================

//===========================================================
extern unsigned int *P_IOB_Data;
extern unsigned int *P_IOB_Dir;

#define  Set_IIC_SCL      0x0001    //IOB0 SCL
#define  Clear_IIC_SCL    0xfffe
#define  Set_IIC_SDA      0x0002    //IOB1 SDA
#define  Clear_IIC_SDA    0xfffd

void IIC_Start(void);                 //启动信号
void IIC_Stop(void);                  //停止信号
void IIC_Ack(void);                   //应答信号
void IIC_Unack(void);                 //非应答信号
unsigned int IIC_Cack(void);          //应答信号检测
void IIC_Wrbyte(unsigned int data);   //写一字节
unsigned int IIC_Rdbyte(void);        //读一字节
void Wrnbyte(unsigned int Addr,unsigned int *P,unsigned int N);//写N字节
void Rdnbyte(unsigned int *P,unsigned int Addr,unsigned int N);//读N字节

//===========================================================

//===========================================================
//函数名称:void Delay1us(unsigned int counter)
//函数功能:延时1us
//输入参数:无
//输出参数:无
//作者: 张 丰 盛
//日期:2007.03.16
//===========================================================
void delay1us(unsigned int counter)
{
	unsigned int i;
	for(;counter>0;counter--)
		for(i=20;i>0;i--);
}
//===========================================================

//===========================================================
//函数名称:void IIC_Start(void)
//函数功能:IIC的启动信号  时序:在SCL高电平期间SDA发生负跳变
//输入参数:无
//输出参数:无
//作者: 张 丰 盛
//日期:2007.03.16
//===========================================================
void IIC_Start(void)
{
	unsigned int IOB;
	IOB=*P_IOB_Data;              //SDA=1
	IOB=IOB|Set_IIC_SDA;        
	*P_IOB_Data=IOB;
	IOB=*P_IOB_Data;             //SCL=1
	IOB=IOB|Set_IIC_SCL;        
	*P_IOB_Data=IOB;
	delay1us(6);
	IOB=*P_IOB_Data;             //SDA=0
	IOB=IOB&Clear_IIC_SDA;     
	*P_IOB_Data=IOB;
	delay1us(5);
	IOB=*P_IOB_Data;            //SCL=0
	IOB=IOB&Clear_IIC_SCL;     
	*P_IOB_Data=IOB;	
}
	
//===========================================================	

//===========================================================
//函数名称:void IIC_IIC_Stop(void)
//函数功能:IIC的启动信号  时序:在SCL高电平期间SDA发生正跳变
//输入参数:无
//输出参数:无
//作者: 张 丰 盛
//日期:2007.03.16
//============================================================
void IIC_Stop(void)
{
	unsigned int IOB;
	IOB=*P_IOB_Data;             //SDA=0
	IOB=IOB&Clear_IIC_SDA;      
	*P_IOB_Data=IOB;
	IOB=*P_IOB_Data;             //SCL=1
	IOB=IOB|Set_IIC_SCL;       
	*P_IOB_Data=IOB;
	delay1us(5);
	IOB=*P_IOB_Data;             //SDA=1
	IOB=IOB|Set_IIC_SDA;        
	*P_IOB_Data=IOB;
	delay1us(6);
	IOB=*P_IOB_Data;             //SCL=0
	IOB=IOB&Clear_IIC_SCL;     
	*P_IOB_Data=IOB;
	IOB=*P_IOB_Data;             //SDA=0
	IOB=IOB&Clear_IIC_SDA;      
	*P_IOB_Data=IOB;	
}
	
//===========================================================	

//===========================================================
//函数名称:void IIC_Ack(void)
//函数功能:IIC的启动信号  时序:在SDA负电平期间SCL发生一个正脉冲
//输入参数:无
//输出参数:无
//作者: 张 丰 盛
//日期:2007.03.16
//===========================================================
void IIC_Ack(void)
{
	unsigned int IOB;
	IOB=*P_IOB_Data;             //SDA=0
	IOB=IOB&Clear_IIC_SDA;      
	*P_IOB_Data=IOB;
	IOB=*P_IOB_Data;             //SCL=1
	IOB=IOB|Set_IIC_SCL;       
	*P_IOB_Data=IOB;
	delay1us(5);
	IOB=*P_IOB_Data;             //SCL=0
	IOB=IOB&Clear_IIC_SCL;     
	*P_IOB_Data=IOB;
	IOB=*P_IOB_Data;             //SDA=1
	IOB=IOB|Set_IIC_SDA;        
	*P_IOB_Data=IOB;	
}
	
//===========================================================

//===========================================================
//函数名称:void IIC_Unack(void)
//函数功能:IIC的启动信号  时序:在SDA高电平期间SCL发生一个正脉冲
//输入参数:无
//输出参数:无
//作者: 张 丰 盛
//日期:2007.03.16
//===========================================================
void IIC_Unack(void)
{
	unsigned int IOB;
	IOB=*P_IOB_Data;             //SDA=1
	IOB=IOB|Set_IIC_SDA;        
	*P_IOB_Data=IOB;
	IOB=*P_IOB_Data;             //SCL=1
	IOB=IOB|Set_IIC_SCL;       
	*P_IOB_Data=IOB;
	delay1us(5);
	IOB=*P_IOB_Data;             //SCL=0
	IOB=IOB&Clear_IIC_SCL;     
	*P_IOB_Data=IOB;
	IOB=*P_IOB_Data;             //SDA=0
	IOB=IOB&Clear_IIC_SDA;      
	*P_IOB_Data=IOB;		
}
	
//===========================================================

//===========================================================
//函数名称:unsigned int IIC_Cack(void)
//函数功能:IIC的应答位检测子程序  
//输入参数:无
//输出参数:正常应答返回0,否则返回1
//作者: 张 丰 盛
//日期:2007.03.17
//===========================================================
unsigned int IIC_Cack(void)
{
	unsigned int IOB;
	unsigned int result;
	IOB=*P_IOB_Dir;                     //SDA为输入线
	IOB=IOB&Clear_IIC_SDA;
	*P_IOB_Dir=IOB;                     
	IOB=*P_IOB_Data;                    //SCL=1
	IOB=IOB|Set_IIC_SCL;               
	*P_IOB_Data=IOB;                   
	if(*P_IOB_Data&Set_IIC_SDA)
    	result=1;                       //非正常应答返回1
	else
	    result=0;                        //正常应答返回0
	IOB=*P_IOB_Data;                     //SCL=0
	IOB=IOB&Clear_IIC_SCL;
	*P_IOB_Data=IOB; 
		IOB=*P_IOB_Dir;                     //SDA为输出线
	IOB=IOB|Set_IIC_SDA;
	*P_IOB_Dir=IOB;                     
	return result;		
}
	
//===========================================================

//===========================================================
//函数名称:void IIC_Wrbyte(unsigned int data)
//函数功能:IIC的发送一字节子程序 
//输入参数:要发送的数据
//输出参数:无
//作者: 张 丰 盛
//日期:2007.03.17
//===========================================================
void IIC_Wrbyte(unsigned int data)
{
	unsigned int i;
	unsigned int IOB;
	data=data<<8;                         //数据整体左移八位
	for(i=8;i>0;i--)
	{
		IOB=*P_IOB_Data;
		if(data&0x8000)
			IOB=IOB|Set_IIC_SDA;
		else
		    IOB=IOB&Clear_IIC_SDA;
		*P_IOB_Data=IOB;                   //送数据位到SDA
		IOB=*P_IOB_Data;                   //SCL=1
		IOB=IOB|Set_IIC_SCL;               
		*P_IOB_Data=IOB; 
		IOB=*P_IOB_Data;                   //SCL=0
	    IOB=IOB&Clear_IIC_SCL;
	    *P_IOB_Data=IOB; 
	    data=data<<1;
	}	    	
}
	
//===========================================================

//===========================================================
//函数名称:unsigned int IIC_Rdbyte(void)
//函数功能:从IIC总线上读取一字节的数据  
//输入参数:无
//输出参数:从IIC总线上读取一字节的数据 
//作者: 张 丰 盛
//日期:2007.03.17
//===========================================================
unsigned int IIC_Rdbyte(void)
{
	unsigned int i;
	unsigned int IOB;
	unsigned int result=0;
	IOB=*P_IOB_Dir;                     //SDA为输入线
	IOB=IOB&Clear_IIC_SDA;
	*P_IOB_Dir=IOB; 
	for(i=8;i>0;i--)
	{
		IOB=*P_IOB_Data;
		if(IOB&Set_IIC_SDA)
			result=result|0x0001;
		result=result<<1;
		IOB=*P_IOB_Data;                   //SCL=1
		IOB=IOB|Set_IIC_SCL;               
		*P_IOB_Data=IOB; 
		IOB=*P_IOB_Data;                   //SCL=0
	    IOB=IOB&Clear_IIC_SCL;
	    *P_IOB_Data=IOB; 
	}	
	result=result>>1;  
	IOB=*P_IOB_Dir;                     //SDA为输出线
	IOB=IOB|Set_IIC_SDA;
	*P_IOB_Dir=IOB; 
	return result;  
}
	
//===========================================================

//===========================================================
//函数名称:void Wrnbyte(unsigned int Addr,unsigned int *P,unsigned int N)
//函数功能:从IIC总线上写N字节的数据  
//输入参数:Addr为器件地址,*P为要写数据的起始地址,N为要写的数据的字节数
//输出参数:无 
//作者: 张 丰 盛
//日期:2007.03.17
//===========================================================
void Wrnbyte(unsigned int Addr,unsigned int *P,unsigned int N)
{
	IIC_Start(); 
	                           //启动IIC总线
	do
    {
		IIC_Wrbyte(Addr);              //发送器件地址和写命令
    }while(IIC_Cack!=0);
	for(;N>0;N--)                     //发送N字节数据
	{
		do
		{
	    	IIC_Wrbyte(*P);
		}while(IIC_Cack()!=0);          //等待发送完成
		P++;
	}		
	IIC_Stop();                            //停止IIC总线
}
	
//===========================================================

//===========================================================

//===========================================================
//函数名称:void Rdnbyte(unsigned int *P,unsigned int Addr,unsigned int N)
//函数功能:从IIC总线上读取N字节的数据  
//输入参数:*P为要读取数据的起始地址Addr为器件地址,N为要读取的数据的字节数
//输出参数:无
//作者: 张 丰 盛
//日期:2007.03.17
//===========================================================
void Rdnbyte(unsigned int *P,unsigned int Addr,unsigned int N)
{
	//unsigned int IOB;
	IIC_Start();                            //启动IIC总线
	do
    {
		IIC_Wrbyte(Addr);              //发送器件地址和写命令
    }while(IIC_Cack!=0);
	for(;N>0;N--)                     //读N字节数据
	{
		do
		{
	    	*P=IIC_Rdbyte();
		}while(IIC_Cack()!=0);          //等待读完成
		P++;
	}
	IIC_Unack();		
	IIC_Stop();                            //停止IIC总线
}
	
//===========================================================

//=================================================================
//
//IIC.C结束
//
//=================================================================

⌨️ 快捷键说明

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