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

📄 i2c.c

📁 基于i2c总线控制的24c32C程序读写
💻 C
字号:
#include <reg52.h>
#include<intrins.h>
#define BYTE unsigned char   //宏定义
#define WORD int  
#define _Nop()  _nop_()      //定义空指令
/*常量、变量定义区*/
/*端口位定义区*/
sibt   SCL=P3^0;             //模拟I2C时钟控制位
sibt   SDA=P3^1;             //模拟I2C数据传送位
/*状态标志*/
bit  ack;
/**************************************************
启动总线函数
函数原形:
void   start_I2C();
功能:
启动I2C总线,即发送I2C起始条件
参数:无
返回值:无
*****************************************************/
void  start_I2C()
{   SDA=1;                      //发送起始条件的数据信号\
    _Nop();
    SCL=1;
    _Nop();                     //起始条件建立时间大于4uS
    _Nop();
    _Nop();
    _Nop();
    _Nop();
    SDA=0;                      //发送起始信号
    _Nop();                     //起始条件锁定时间大于4us
    _Nop(); 
    _Nop();
    _Nop();
    _Nop();
    SCL=0;                      //准备发送或接受数据
    _Nop();
    _Nop();
}
/**************************************************
结束总线函数
函数原形:
void   stop_I2C();
功能:
结束I2C总线,即发送I2C结束条件
参数:无
返回值:无
*****************************************************/
void  stop_I2C()
{   SDA=0;                      //发送结束条件的数据信号
    _Nop();
    SCL=1;                      //发送结束条件的时钟信号
    _Nop();                     //结束条件建立时间大于4uS
    _Nop();
    _Nop();
    _Nop();
    _Nop();
    SDA=1;                      //发送结束信号
    _Nop();                     //结束条件锁定时间大于4us
    _Nop(); 
    _Nop();
    _Nop();
}
/*******************************************************
字节数据传送函数
函数原形:
void  sendbyte(BYTE data);
功能:
发送数据,可以是地址,发送后等待回应,并对此状态位进行操作.
应答或非应答都使ack=0,发送正常,ack=1;
 ack=0,表示接收器无应答或损坏
参数:
data:需要发送的数据
返回值:无
********************************************************/
void sendbyte(BYTE data)
{
  BYTE  bitcount;
  for(bitcount=0;bitcount<8;bitcount++)    //要传送的数据长度为8位
   {
     if((data<<bitcount)&0x80)             //判断发送位
      SDA=1;
     else 
	  SDA=0;
      _Nop();
       SCL=1;                              //置时钟线为高,通知被控器开始接收数据位
      _Nop();                              //保证时钟高电平周期大于4um
      _Nop();
      _Nop();
      _Nop();
      _Nop();
	  SCL=0;
   }
      _Nop();
      _Nop();
       SDA=1;                               //8位发送后释放数据线,准备接收应答位
      _Nop();
      _Nop();
      SCL=1;
      _Nop();
      _Nop();
      _Nop();
	  if(SDA==1)
	    ack=0;
	  else  ack=1;        、                 //判断是否接收到应答信号
	  SCL=0;
      _Nop();
      _Nop();
}
  /*******************************************************
字节数据接收函数
函数原形:
BYTE  recbyte();
功能:用来接收从器件传来的数据,并判断总线错误(不发生应答信号),发送后请用应答函数
参数:无
返回值:读到的数据
********************************************************/
BYTE  recbyte()
{ BYTE recdata;
  BYTE bitcount;
  recdata=0;
  SDA=1;                                 //置数据线为输入方式
  for(bitcount=0;bitcount<8;bitcount++)
    { _Nop();
 	  _Nop();						
      SCL=0;                            、//置时钟线为低,准备接收数据位
      _Nop();                              //保证时钟低电平周期大于4um
      _Nop();
      _Nop();
      _Nop();
      _Nop();
       SCL=1;	                            //置时钟为高使数据线上数据有效
      _Nop();
      _Nop();
      _Nop();
      recdata=recdata<<1;
      if(SDA=1)
        recdata=recdata+1;                 //读数据位,接收的数据位放入recdata中
      _Nop();
      _Nop();
      _Nop();
     }
	 SCL=0;
	 _Nop();
     _Nop();
     _Nop();
	 return(recdata);
	 	 、、
} 
 /*******************************************************
应答子函数
函数原形:void ack_i2c(bit a);
功能:主控器进行应答信号,可以是应答或非应答信号。
参数:a应答信号
返回值:无
********************************************************/
void ack_i2c(bit a)
{ if(a==0)
    SDA=0;
  else SDA=1;
    _Nop();
    _Nop();
    _Nop();
    _Nop();
       SCL=1;
    _Nop();
    _Nop();
    _Nop();
    _Nop();
    _Nop();
    _Nop();
       SCL=0; // 清除时钟线,以便继续接收
    _Nop();
    _Nop();
    _Nop();
    _Nop();
 }

 /**********************************************************************************
 向无子地址器件发送字节数据函数
 函数原形:
 bit  sendbytedata(BYTE slave,BYTE data);
 功能:
 从启动总线到发送地址、数据,结束总线的过程
 参数:
 Slave:从器件地址
 Data:要发送的数据
 返回值: 
 如果返回1,表示操作成功;否则操作有误
 注意:使用前必须已结束总线
 **********************************************************************************/
 bit  sendbytedate(BYTE slave,BYTE Data)
 {
   start_I2C();                          //启动总线
   sendbyte(slave);                      //发送器件地址
   if(ack==0)
   return(0);
   sendbyte(Data);                       //发送数据
   if(ack==0)
   return(0);
   stop_I2C();                           //结束总线
   return(1);
 }
/**********************************************************************************
 向有子地址器件发送多字节数据函数
 函数原形:
 bit  sendstr(BYTE slave,BYTE subaddress,BYTE *source,BYTE num);
 功能:
 从启动总线到发送地址,子地址,结束总线的过程
 参数:
 Slave:从器件地址
 subaddress:子地址
 source:发送内容的指针
 num:发送字节个数
 返回值: 
 如果返回1,表示操作成功;否则操作有误
 注意:使用前必须已结束总线
 **********************************************************************************/
/* bit  sendstr(BYTE slave,BYTE subaddress,BYTE *source,BYTE num)
 { 
   BYTE i;
   start_I2C();                              //启动总线
   sendbyte(slave);                          //发送器件地址
   if(ack==0)
   return(0);
   sendbyte(subaddress);                     //发送器件子地址    
   if(ack==0)
   return(0);
   for(i=0;i<num;i++)
   {
     sendbyte(*source);                       //发送数据
     if(ack==0)
     return(0);
     source++;
	 }
   stop_I2C();                                //结束总线
   return(1);                         
 }
 */
/**********************************************************************************
 向有子地址器件发送多字节数据函数
 函数原形:
 bit  sendstr(BYTE slave,BYTE subaddress,BYTE *source,BYTE num);
 功能:
 从启动总线到发送地址,子地址,结束总线的过程
 参数:
 Slave:从器件地址
 subaddress:子地址
 source:发送内容的指针
 num:发送字节个数
 返回值: 
 如果返回1,表示操作成功;否则操作有误
 注意:使用前必须已结束总线
 **********************************************************************************/
 bit  sendstr(BYTE slave,BYTE subaddress,BYTE zuzhi)
 { 
   BYTE i;
   start_I2C();                              //启动总线
   sendbyte(slave);                          //发送器件地址
   if(ack==0)
   return(0);
   sendbyte(subaddress);                     //发送器件子地址    
   if(ack==0)
   return(0);
   sendbyte(zuzhi);                       //发送数据
   stop_I2C();                                //结束总线
   return(1);                         
 }
  /**********************************************************************************
 向无子地址器件读字节数据函数
 函数原形:
 bit  recbytedata(BYTE slave,BYTE *Data);
 功能:
 从启动总线到发送地址,读数据,结束总线的过程
 参数:
 Slave:从器件地址,返回值在Data
 返回值: 
 如果返回1,表示操作成功;否则操作有误
 注意:使用前必须已结束总线
 **********************************************************************************/

  bit recbytedata(BYTE slave,BYTE *Data)
  { start_I2C(); 				 // 启动总线
    sendbyte(slave);             //发送器件地址
	if(ack==0)return(0);
	 *Data=recbyte();            //读取数据
	 ack_i2c(1)	 ;               //发非应答位
	 stop_I2C();                 //结束总线
     return(1);
  }
 /**********************************************************************************
 向有子地址器件读多字节数据函数
 函数原形:
 bit  recstr(BYTE slave,BYTE subaddress,BYTE *source,BYTE num);
 功能:
 从启动总线到发送地址,子地址,读数据,结束总线的过程
 参数:
 Slave:从器件地址,subaddress:子地址,source:指向读出的内容放入的存储区的指针,num:读字节个数
 返回值: 
 如果返回1,表示操作成功;否则操作有误
 注意:使用前必须已结束总线
 **********************************************************************************/
bit  recstr(BYTE slave,BYTE subaddress,BYTE *source,BYTE num)
』{BYTE i;
   	start_I2C();                // 启动总线
	sendbyte(slave);             //发送器件地址
	if(ack==0)return(0);
	  sendbyte(subaddress);             //发送器件子地址
	if(ack==0)return(0); 
	for(i=0;i<num-1;num++)	
	  {  source=recbyte();               //发送数据
	   ack_i2c(0);               //发应答位
	   source++;
	   stop_I2C();                 //结束总线
       return(1);
      }
  }
void main()
{start_I2C();
 sendstr(50H,90H,BYTE *source,BYTE num);
}
   

⌨️ 快捷键说明

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