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

📄 iic.c

📁 PIC单片机模拟IIC通讯
💻 C
字号:

#include <pic.h>


/****************************************
iic引脚功能定义
****************************************/
#define	WP		RC1
#define	SCL		RC3
#define	SDA		RC4



/***************************************************************************************
			全局变量说明
**************************************************************************************/


unsigned char   ACK;			//应答标志

/******************************************************************** 
功    能:延时
说    明:i=1为24us ,2为34us,3为44us
入口参数:unsigned char i
***********************************************************************/
void delay(unsigned char i)        //延时
{
     
	while(i--)
	{
		NOP();
		CLRWDT();
		NOP();
		NOP();
	}
}   
///////////////////////////////////////////////////////////////////////////////
//////  	I2C总线在标准的方式下最高时钟为100KHZ,                 ///////
////时钟信号最小低电平时段为4.7us,高电平时段不得小于4us.		///////
////(1) 只有在总线空闲时才允许启动数据伟送				///////
////(2) 在数据传送过程中,当时钟线为高电平时,数据线必须保持稳定状态	///////							
////不允许有跳变。否将看作总线的起始或停止				///////
///////////////////////////////////////////////////////////////////////////////

/********************************************************************
功能: 		I2C开始
说明:时钟线保持高电平期间,数据线电平从高到低的跳变作为I2C总路线的起始信号
********************************************************************/
void iic_start (void)    
{
   	TRISC3=1;         //置输入
   	TRISC4=1;
   	NOP();
	TRISC3=1;	 //在至少4u秒期间SDA从高电平到低电平         
   	NOP();
   	NOP();
   	NOP();
   	SDA=0;
   	TRISC4=0;
   	NOP();
   	NOP();
   	NOP();
   	SCL=0;
   	TRISC3=0;
   	NOP();
   	NOP();
}
/*************************************************************
功能:		I2C结束
说明:时钟线保持高电平期间,数据线电平从低到高的跳变作为I2C的停止信号
*************************************************************/
void iic_stop(void)      
{ 
	SDA=0;
    	TRISC4=0;         //置输出
    	NOP();
    	NOP();		 //在至少4u秒期间SDA从低电平到高电平        
    	TRISC3=1;
    	NOP();
    	NOP();
    	NOP();
	TRISC4=1;
    	NOP();
    	NOP();
    	NOP();
    	SCL=0;
    	TRISC3=0;
    	NOP();
    	NOP();
	TRISC3=1;
}
 
 /**********************************************************
功能:  检查应答信号
备注:  每成功地传送一个字节数据后,接收器都必须产生一个应答
信号。应答的器件在第9个时钟周期时将SDA线拉低,表示其已收到
一个8位数据
说明:  ACK为0说明发送成功,否为错
******************************************************/  
 
unsigned char iic_check(void)      
{  
     	TRISC4=1;
     	SCL=0;
     	TRISC3=0;
	NOP();
     	NOP();
	TRISC3=1;
     	if (SDA)ACK = 1;
    	else ACK = 0;
    	SCL=0;
	TRISC3=0;
     	return(ACK);
}
/******************************************************
功能:主器件向从器件发送一个字节,同时检查从器件应答位
说明:入口参数是DATA,是将要发送到从器件的数据
数据是高位先发,即用左移一位<<1
***********************************************************/
void iic_send(unsigned char data)     
{
  unsigned char bitcount=8;       //发送8位
	do
                 { 
        		SCL=0;
        		TRISC3=0;     //置输出	             	
           		if((data&0x80)==0x80) TRISC4=1;	 //发送 1
             		else 
             		{
                		SDA=0;      //发送 0
                		TRISC4=0;
             		}
		TRISC3=1;
          		NOP();
          		NOP();
          		NOP();
          		NOP();
          		NOP();
          		SCL=0; 
		TRISC3=0;
               	data<<=1;
          	bitcount--;
          } while(bitcount);
           TRISC4=1 ;                  //释放总线等待应答
           NOP();
           NOP();
           NOP();
           NOP();
           NOP();   
}   
/*************************************************************
功能:	接受一个字节
*************************************************************/

unsigned char iic_recive(void)      
{
	unsigned char temp1=0;
	unsigned char bitcount1=8;
	TRISC4=1;         //置输入
	SCL=0;
	TRISC3=0;
   	do
   	{
     		TRISC3=1;
    		NOP();
     		NOP();
     		NOP();
     		NOP();
   		if(SDA)                  //读 1
      		{ 
      			temp1=temp1|0x01;
      		}
    		else                    //读 0
    		{
      			temp1=temp1&0xfe;
    		}
    		SCL=0;
		TRISC3=0;
      		if(bitcount1-1)
     		{
       			temp1<<=1;
      		}
      		bitcount1--;  
     	}while(bitcount1);
	return(temp1);
}       

//停止继续读    
void iic_nack(void)      
{         
   	SCL=0;
   	TRISC3=0;
	TRISC4=1;          
   	TRISC3=1;
   	NOP();
   	NOP();
   	NOP();
   	NOP();
   	NOP();       
   	SCL=0;
   	TRISC3=0;
}  

/*********************************************************
功能: 	给24LC01写数据 
备注:	address:是待写入首地址 采用连续写模式
*********************************************************/

void iic_writebyte(unsigned address)  
{
	unsigned char i,j;
	CLRWDT();	
	iic_start();               //起始信号
    	iic_send(0xa0);          //写从器件识别地址00xa0;0xa2;0xa4;0xa6;0xa8;0xaa;0xac;0xae;
	for(i=10;i>0;i--)
	{
		CLRWDT();	
		if(iic_check()==0) break;
		NOP();
		NOP();
		NOP();
		NOP();
		NOP();//10ms扬时
	}	
    	iic_send(address);     //0x00--0xff;      
	for(i=10;i>0;i--)
	{
		CLRWDT();	
		if(iic_check()==0) break;
		NOP();
		NOP();
		NOP();
		NOP();
		NOP();//10ms扬时
	}
	CLRWDT();
	for(j=0;j<16;j++)	//hour[j]连续存入
	{	
    		iic_send(MM[j]);            //发送数据
		for(i=0;i<10;i++)
		{
			CLRWDT();	
			if(iic_check()==0) break;
			NOP();
			NOP();
			NOP();
			NOP();
			NOP();//10ms扬时
		}
	}
	CLRWDT();
   	iic_stop();                 //停止
   	delay(100);                //延时,下次发数据
     
}
/*******************************************************************
功能:		从24C01中读数据
*******************************************************************/
unsigned char iic_readbyte(unsigned char address)   
{
	unsigned char pdata,i;
	NOP(); 
	CLRWDT();	
    	iic_start();               //开始
    	iic_send(0xa0);              //写主控器识别地址(写)
	for(i=10;i>0;i--)
	{
		CLRWDT();	
		if(iic_check()==0) break;
		NOP();
		NOP();
		NOP();
		NOP();
		NOP();//10ms扬时
	}	
    	iic_send(address);               //送地址
	for(i=10;i>0;i--)
	{
		CLRWDT();	
		if(iic_check()==0) break;
		NOP();
		NOP();
		NOP();
		NOP();
		NOP();//10ms扬时
	}	
	iic_start();                  //开始读数据
    	iic_send(0xa1);               //写主控器识别地址(读)
	for(i=10;i>0;i--)
	{
		CLRWDT();	
		if(iic_check()==0) break;
		NOP();
		NOP();
		NOP();
		NOP();
		NOP();//10ms扬时
	}
	CLRWDT();	
	pdata=iic_recive();
    	iic_nack();
    	iic_stop(); 
	return pdata;
}      

⌨️ 快捷键说明

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