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

📄 oki2c_c02orc64.c

📁 用24C02或者24C64模拟IIC总线实验
💻 C
字号:
/***************************************************************************
注意:函数是采用软件延时的方法产生SCL 脉冲,对高晶振频率要作一定的修改
(本例是1us 机器周期,即晶振频率要小于12MHz)
**************************************************************************/
#include <reg52.h>              /*头文件的包含*/
#include <intrins.h>
#define uchar unsigned char     /*宏定义*/
#define uint unsigned int

sbit SDA=P2^6;                  /*模拟I2C 数据传送位*/
sbit SCL=P2^7;                  /*模拟I2C 时钟控制位*/
bit ack;                        /*应答标志位*/
/*********************************************************************
起动总线函数
函数原型: void Start_I2c();
功能:启动I2C 总线,即发送I2C 起始条件
********************************************************************/
void Start_I2c()
{
    SDA=1;                      /*发送起始条件的数据信号*/
    _nop_();
    SCL=1;
    _nop_();                    /*起始条件建立时间大于4.7us,延时*/
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    SDA=0;                      /*发送起始信号*/
    _nop_();                    /* 起始条件锁定时间大于4 s*/
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    SCL=0;                      /*钳住I2C 总线准备发送或接收数据*/
    _nop_();
    _nop_();
}
/***********************************************
结束总线函数
函数原型: void Stop_I2c();
功能:结束I2C 总线,即发送I2C 结束条件
***********************************************/
void Stop_I2c()
{
    SDA=0;                      /*发送结束条件的数据信号*/
    _nop_();                    /*发送结束条件的时钟信号*/
    SCL=1;                      /*结束条件建立时间大于4 s*/
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    SDA=1;                      /*发送I2C 总线结束信号*/
    _nop_();
    _nop_();
    _nop_();
    _nop_();
}
/*******************************************************************
字节数据传送函数
函数原型: void SendByte(uchar c);
功能:将数据c 发送出去,可以是地址,也可以是数据,发完后等待应答,并对此状
态位进行操作(不应答或非应答都使ack=0 假) 发送数据正常ack=1;
ack=0 表示被控器无应答或损坏
********************************************************************/
void SendByte(uchar c)
{
    uchar BitCnt;
    for(BitCnt=0;BitCnt<8;BitCnt++) /*要传送的数据长度为8 位*/
    {
      if((c<<BitCnt)&0x80)SDA=1;    /*判断发送位*/
      else SDA=0;
      _nop_();
      SCL=1;                    /*置时钟线为高通知被控器开始接收数据位*/
      _nop_();
      _nop_();                      /*保证时钟高电平周期大于4 s*/
      _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_();
}
/*******************************************************************
字节数据传送函数
函数原型: uchar RcvByte();
功能:用来接收从器件传来的数据,并判断总线错误(不发应答信号)
发完后请用应答函数
********************************************************************/
uchar RcvByte()
{
    uchar retc;
    uchar BitCnt;
    retc=0;
    SDA=1;                          /*置数据线为输入方式*/
    for(BitCnt=0;BitCnt<8;BitCnt++)
    {
      _nop_();
      SCL=0;                        /*置时钟线为低准备接收数据位*/
      _nop_();
      _nop_();                      /*时钟低电平周期大于4.7 s*/
      _nop_();
      _nop_();
      _nop_();
      SCL=1;                        /*置时钟线为高使数据线上数据有效*/
      _nop_();
      _nop_();
      retc=retc<<1;
      if(SDA==1)retc=retc+1;        /*读数据位,接收的数据位放入retc 中*/
      _nop_();
      _nop_();
    }
    SCL=0;
    _nop_();
    _nop_();
    return(retc);
}
/********************************************************************
应答子函数
原型: void Ack_I2c(bit a);
功能:主控器进行应答信号,(可以是应答或非应答信号)
********************************************************************/
void Ack_I2c(bit a)
{
    if(a==0)  SDA=0;            /*在此发出应答或非应答信号*/
    else SDA=1;
    _nop_();
    _nop_();
    _nop_();
    SCL=1;
    _nop_();
    _nop_();                    /*时钟低电平周期大于4 s*/
    _nop_();
    _nop_();
    _nop_();
    SCL=0;                      /*清时钟线钳住I2C 总线以便继续接收*/
    _nop_();
    _nop_();
}
/*******************************************************************
向无子地址器件发送字节数据函数
函数原型: bit ISendByte(uchar sla,ucahr c);
功能:从启动总线到发送地址数据结束总线的全过程,从器件地址sla 如果
返回1 表示操作成功否则操作有误
********************************************************************/
//bit ISendByte(uchar sla,uchar c)
//{
//    Start_I2c();                /*启动总线*/
//    SendByte(sla);              /*发送器件地址*/
//    if(ack==0) return(0);
//    SendByte(c);                /*发送数据*/
//    if(ack==0) return(0);
//    Stop_I2c();                 /*结束总线*/
//    return(1);
//}
/*******************************************************************
向有子地址器件发送多字节数据函数
函数原型: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
功能:从启动总线到发送地址子地址,数据结束总线的全过程,从器件地址sla
子地址suba 发送内容是s 指向的内容发送no 个字节如果返回1 表示
操作成功否则操作有误
********************************************************************/
bit ISendStr1(uchar sla,uchar suba,uchar *s,uchar no)
{
    uchar i;
    Start_I2c();                /*启动总线*/
    SendByte(sla);              /*发送器件地址*/
    if(ack==0) return(0);
    SendByte(suba);             /*发送器件子地址*/
    if(ack==0) return(0);
    for(i=0;i<no;i++)
    {
      SendByte(*s);             /*发送数据*/
      if(ack==0) return(0);
      s++;
    }
    Stop_I2c();                 /*结束总线*/
    return(1);
}
//////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
//bit ISendStr2(uchar sla,uchar subah,uchar subal,uchar *s,uchar no)
//{
//    uchar i;
//    Start_I2c();                /*启动总线*/
//    SendByte(sla);              /*发送器件地址*/
//    if(ack==0) return(0);
//    SendByte(subah);             /*发送器件子高地址*/
//    if(ack==0) return(0);
//    SendByte(subal);             /*发送器件子低地址*/
//    if(ack==0) return(0);    
//    for(i=0;i<no;i++)
//    {
//      SendByte(*s);             /*发送数据*/
//      if(ack==0) return(0);
//      s++;
//    }
//    Stop_I2c();                 /*结束总线*/
//    return(1);
//}
/*******************************************************************
向无子地址器件读字节数据函数
函数原型: bit IRcvByte(uchar sla,ucahr *c);
功能:从启动总线到发送地址读数据结束总线的全过程,从器件地址sla 返
回值在c 如果返回1 表示操作成功否则操作有误
********************************************************************/
//bit IRcvByte(uchar sla,uchar *c)
//{
//    Start_I2c();                /*启动总线*/
//    SendByte(sla+1);            /*发送器件地址*/
//    if(ack==0) return(0);
//    *c=RcvByte();               /*读取数据*/
//    Ack_I2c(1);                 /*发送非就答位*/
//    Stop_I2c();                 /*结束总线*/
//    return(1);
//}
/**********************************************************************
向有子地址器件读取多字节数据函数
函数原型: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
功能:从启动总线到发送地址子地址,读数据结束总线的全过程,从器件地址sla
子地址suba 读出的内容放入s 指向的存储区读no 个字节如果返回1
表示操作成功否则操作有误
**********************************************************************/
bit IRcvStr1(uchar sla,uchar suba,uchar *s,uchar no)
{
    uchar i;
    Start_I2c();                /*启动总线*/
    SendByte(sla);              /*发送器件地址*/
    if(ack==0) return(0);
    SendByte(suba);             /*发送器件子地址*/
    if(ack==0) return(0);
    Start_I2c();
    SendByte(sla+1);
    if(ack==0) return(0);
    for(i=0;i<no-1;i++)
    {
      *s=RcvByte();             /*发送数据*/
      Ack_I2c(0);               /*发送就答位*/
      s++;
    }
    *s=RcvByte();
    Ack_I2c(1);                 /*发送非应位*/
    Stop_I2c();                 /*结束总线*/
    return(1);
}
///////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//bit IRcvStr2(uchar sla,uchar subah,uchar subal,uchar *s,uchar no)
//{
//    uchar i;
//    Start_I2c();                /*启动总线*/
//    SendByte(sla);              /*发送器件地址*/
//    if(ack==0) return(0);
//    SendByte(subah);             /*发送器件子高地址*/
//    if(ack==0) return(0);
//    SendByte(subal);             /*发送器件子低地址*/
//    if(ack==0) return(0);    
//    Start_I2c();
//    SendByte(sla+1);
//    if(ack==0) return(0);
//    for(i=0;i<no-1;i++)
//    {
//      *s=RcvByte();             /*发送数据*/
//      Ack_I2c(0);               /*发送就答位*/
//      s++;
//    }
//    *s=RcvByte();
//    Ack_I2c(1);                 /*发送非应位*/
//   Stop_I2c();                 /*结束总线*/
//   return(1);
//}
/* END */

⌨️ 快捷键说明

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