你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM8S I2C总线中断程序

[复制链接]
磊元lystudio 发布时间:2015-10-2 01:49
阅读主题, 点击返回1楼
收藏 1 评论23 发布时间:2015-10-2 01:49
23个回答
磊元lystudio 回答时间:2015-10-2 01:53:54

/*==========================================================================================================
函数名称:  设置I2C总线为标准/快速模式和占空比
函数功能:  本函数用于设置I2C总线为标准/快速模式和占空比操作的函数。
函数入口参数:Model ----------------- 标准/快速模式和占空比, ON(快速模式)/ OFF(标准模式)。
函数返回值: 没有
调用函数:  1.
备注:        1.
==========================================================================================================*/
void  CommI2cBusModeDuty (unsigned char Model)
{
#if   (defined(_IAR_EW_AVR_))

#elif ((defined(_IAR_EW_MCS51_)) || (defined(_KEIL_UV_MCS51_)))

#elif (   defined(_IAR_EW_STM8_) \
       || defined(_COSMIC_STM8_) )                        // “......_STM8 编译器”条件编译开始
#ifdef _USE_STM8_FWLIB_                                   // “使用 STM8 FWLib 的库文件”条件编译开始

#else                                                     // “_USE_STM8_FWLIB_”
  I2CCR1         &= (u8)(~((1<<i2cEN   ) ));              // 禁止I2C模块,用以设置 I2CTRISER。
  if (Model == ON)                                        // 快速模式:占空比=Tlow/Thigh=2/1
  {
    I2CCCRH       = (u8)( ((0<<i2cDUTY )|                 // 快速模式下的占空比=0:Tlow/Thigh=2/1,1:Tlow/Thigh=16/9。
                           (1<<i2cSFM  )|                 // 标准/快速模式选择位=快速模式
                          cI2c0BrCcrF21H ));              // 置I2C比特率高位寄存器的数值,注:只有禁用I2C模块时,才能设置。
    I2CCCRL       = (u8)( cI2c0BrCcrF21L);                // 置I2C比特率低位寄存器的数值,注:只有禁用I2C模块时,才能设置。
    I2CTRISER     = (u8)( ((((cSysCpuClk / 1000000UL) * 3UL) / 10UL) + 1));
                                                          // 快速模式:最大上升时间=300ns,注:只有禁用I2C模块时,才能设置。
  }
  else                                                    // 标准模式:占空比=Tlow/Thigh=1/1
  {
    I2CCCRH       = (u8)( ((0<<i2cDUTY )|                 // 快速模式下的占空比=0:Tlow/Thigh=2/1,1:Tlow/Thigh=16/9。
                           (0<<i2cSFM  )|                 // 标准/快速模式选择位=标准模式
                          cI2c0BrCcrS11H ));              // 置I2C比特率高位寄存器的数值,注:只有禁用I2C模块时,才能设置。
    I2CCCRL       = (u8)( cI2c0BrCcrS11L);                // 置I2C比特率低位寄存器的数值,注:只有禁用I2C模块时,才能设置。
    I2CTRISER     = (u8)( ((cSysCpuClk / 1000000UL) + 1));// 标准模式:最大上升时间=1000ns,注:只有禁用I2C模块时,才能设置。
  }
  I2CCR1         |= (u8)( ((1<<i2cEN   ) ));              // 使能I2C模块
#endif                                                    // “_USE_STM8_FWLIB_”
#else
#error 错误:
#endif                                                    // “PreMcuIs__......”
}

#ifdef PreCommI2cUseSingleMasterMode                      // “I2C总线工作于单主机方式”的条件编译
/*==========================================================================================================
函数名称:  I2C总线工作于单主机方式,重新启动I2C总线前一个通讯收发作业
函数功能:  本函数用于I2C总线工作于单主机方式,重新启动I2C总线前一个通讯收发作业操作的函数。
函数入口参数:gbitI2c.Txd ------------- “正在进行发送数据作业”标志。
              gbitI2c.Rxd ------------- “正在进行接收数据作业”标志。
函数返回值: 没有
函数出口参数:gucvI2cEvent ---------- I2C总线的状态码变量,出口值= cI2cAllNoState(没有相关的状态信息) 。
              gstvI2c.TxBuf[0] ------ 每次发送数据缓冲区数组变量,出口值=要发送的地址。
              gstvI2c.ErrNum -------- I2C总线的通讯收发作业发生错误次数值变量,出口值=0。
              gstvI2c.RxCnt --------- 每次接收数据个数计数器变量,出口值=0。
调用函数:  1.
备注:        1.调用本函数将触发两线串行总线接口TWI中断请求和向I2C总线发出 START 信号(起始条件)。
==========================================================================================================*/
static void  CommI2cBusAgain (void)
{
#if cI2cTxBufSize < 256
  register unsigned char    i;                            // 循环变量
#else
  register unsigned int     i;
#endif
  unsigned char             temp;                         // 临时变量
  CommI2cDataStru           *pI2c;                        // 指向I2C总线通讯收发数据处理变量的指针

  pI2c                      = &gstvI2c;                   // 取I2C总线通讯收发数据处理变量的首个地址

  MFHI2cBusModSwRst( );                                   // 软件复位I2C模块,释放I2C总线

  gucvI2cEvent              =  cI2cAllNoState;            // 置I2C总线的状态码 = 没有相关的状态信息
  if (   (gbitI2c.Txd == SET)                             // 如果是先发送若干地址然后再进行发送数据作业?
      && (gbitI2c.Rxd == SET) )
  {
    pI2c->TxBuf[0]         &= (u8)(~BIT0);                // 设置数据传送方向为写入数据
  }
  pI2c->RxCnt               =  0x00;                      // I2C总线每次接收数据个数计数器清0
  pI2c->ErrNum              =  0x00;                      // I2C总线的通讯收发作业发生错误次数值清0
  MFHI2cFlgEventClr( );                                   // 清0I2C总线事件中断标志位
  MFHI2cIntEventOne( );                                   // 使能I2C总线事件中断、错误中断,禁止缓冲中断
  MFHI2cBusNackStar( );                                   // 发出 START 信号(起始条件),没有 ACK 脉冲
}

/*==========================================================================================================
函数名称:  启动I2C总线应用中断方式发送数据
函数功能:  本函数用于启动I2C总线使用中断方式,进行通讯发送数据作业操作的函数。
函数入口参数:Object ------------------ 要发送数据的的目标设备地址值。
              *pData ------------------ 指向首个要发送数据在SRAM中的地址指针。
              Length ------------------ 要发送数据的数据总长度。
函数返回值: 没有
函数出口参数:gbitI2c.Busy ------------ I2C总线〖忙〗,出口值=置位。
              gbitI2c.Txd ------------- “正在进行发送数据作业”标志,出口值=置位。
              gbitI2c.Rxd ------------- “正在进行接收数据作业”标志,出口值=清位。
              gucvI2cEvent ------------ I2C总线的状态码变量,出口值= cI2cAllNoState(没有相关的状态信息) 。
       gstvI2c.TxSize ---------- 每次发送数据个数大小变量,出口值=Length + cI2cAddrNum。
       gstvI2c.TxCnt ----------- 每次发送数据个数计数器变量,出口值=0。
       gstvI2c.TxBuf[] --------- 每次发送数据缓冲区数组变量,出口值=要发送的数据。
       gstvI2c.Cycle ----------- 重新启动通讯收发作业圈数,出口值=0。
       gstvI2c.ErrNum ---------- 通讯收发作业发生错误次数,出口值=0。
调用函数:  1.
备注:        1.注意:调用本函数之前,必须确定I2C总线在空闲状态。即必须先调用
            “unsigned char CommI2cBusBusy(void)”函数,来检查I2C总线的工作状态,
            只有I2C总线处于空闲状态,才允许调用本函数。
       2.调用本函数将触发两线串行总线接口TWI中断请求和向I2C总线发出 START 信号(起始条件)。
==========================================================================================================*/
#if cI2cTxBufSize < 256
void  CommI2cTxWithData (unsigned char Object, unsigned char *pData, unsigned char Length)
#else
void  CommI2cTxWithData (unsigned char Object, unsigned char *pData, unsigned int  Length)
#endif
{
#if cI2cTxBufSize < 256
  register unsigned char    i;                            // 循环变量
#else
  register unsigned int     i;
#endif
  unsigned char             temp;                         // 临时变量
  CommI2cDataStru           *pI2c;                        // 指向I2C总线通讯收发数据处理变量的指针

  pI2c                      = &gstvI2c;                   // 取I2C总线通讯收发数据处理变量的首个地址

#ifdef PreCommI2cWithRedundantCode                        // “使用冗余程序代码”条件编译开始
  if (   (Length >= (cI2cTxBufSize - 1))
      || (Length == 0)                   )
  {
    return;
  }
#endif                                                    // “PreCommI2cWithRedundantCode”

  MFHI2cBusModSwRst( );                                   // 软件复位I2C模块,释放I2C总线
//  while(CommI2cBusBusy( ));                               // 等待直到对TWI下一个收发作业准备就绪为止

  gbitI2c.Busy              =  SET;                       // 置“I2C总线〖忙〗”标志
  gbitI2c.Txd               =  SET;                       // 置“正在进行发送数据作业”标志
  gbitI2c.Rxd               =  CLEAR;                     // 清除“正在进行接收数据作业”标志
  gbitI2c.OverS             =  SET;                       // 置“通讯任务时间超时”标志
  gucvI2cEvent              =  cI2cAllNoState;            // 置I2C总线的状态码 = 没有相关的状态信息
  pI2c->OverS               =  RtcGetSecByte(cI2cOverSec);// 启动通讯任务时间计时秒表
//  pI2c->Object              =  Object;                    // 复制目标设备地址到每次发送数据的目标设备地址中
//  pI2c->Object             &= (u8)(~BIT0);                // 设置数据传送方向为写入数据
//  pUsart->pTxData           =  pData;                     // 保存要发送的数据序列的地址指针
  MemCopySramToSram(&Object, pI2c->TxBuf, cI2cAddrNum);   // 复制目标设备地址到发送数据缓冲区中
  pI2c->TxBuf[0]           &= (u8)(~BIT0);                // 设置数据传送方向为写入数据
  MemCopySramToSram(pData, &pI2c->TxBuf[cI2cAddrNum], Length);
                                                          // 复制发送的数据序列到发送数据缓冲区中
  pI2c->TxSize              =  Length + cI2cAddrNum;      // 置每次发送数据个数大小值
  pI2c->TxCnt               =  0x00;                      // 每次发送数据计数器值清0
  pI2c->Cycle               =  0x00;                      // 重新启动通讯收发作业圈数清0
  pI2c->ErrNum              =  0x00;                      // I2C总线的通讯收发作业发生错误次数清0
  MFHI2cFlgEventClr( );                                   // 清0I2C总线事件中断标志位
  MFHI2cIntEventOne( );                                   // 使能I2C总线事件中断、错误中断,禁止缓冲中断
  MFHI2cBusNackStar( );                                   // 发出 START 信号(起始条件),没有 ACK 脉冲
}
磊元lystudio 回答时间:2015-10-2 01:54:12

/*==========================================================================================================
函数名称:  启动I2C总线应用中断方式接收数据
函数功能:  本函数用于启动I2C总线使用中断方式,进行通讯接收数据作业操作的函数。
函数入口参数:Object ------------------ 要接收数据的的目标设备地址值。
              Length ------------------ 要接收数据的数据总长度。
函数返回值: 没有
函数出口参数:gbitI2c.Busy ------------ I2C总线〖忙〗,出口值=置位。
              gbitI2c.Txd ------------- “正在进行发送数据作业”标志,出口值=清位。
              gbitI2c.Rxd ------------- “正在进行接收数据作业”标志,出口值=置位。
              gucvI2cEvent ------------ I2C总线的状态码变量,出口值= cI2cAllNoState(没有相关的状态信息) 。
       gstvI2c.TxSize ---------- 每次发送数据个数大小变量,出口值=cI2cAddrNum。
       gstvI2c.TxCnt ----------- 每次发送数据个数计数器变量,出口值=0。
       gstvI2c.TxBuf[] --------- 每次发送数据缓冲区数组变量,出口值=要发送的数据。
       gstvI2c.Cycle ----------- 重新启动通讯收发作业圈数,出口值=0。
       gstvI2c.ErrNum ---------- 通讯收发作业发生错误次数,出口值=0。
              gstvI2c.RxSize ---------- 每次接收数据个数大小变量,出口值=Length。
              gstvI2c.RxCnt ----------- 每次接收数据个数计数器变量,出口值=0。
调用函数:  1.
备注:        1.注意:调用本函数之前,必须确定I2C总线在空闲状态。即必须先调用
            “unsigned char CommI2cBusBusy(void)”函数,来检查I2C总线的工作状态,
            只有I2C总线处于空闲状态,才允许调用本函数。
       2.调用本函数将触发两线串行总线接口TWI中断请求和向I2C总线发出 START 信号(起始条件)。
==========================================================================================================*/
#if cI2cRxBufSize < 256
void  CommI2cRxWithData (unsigned char Object, unsigned char Length)
#else
void  CommI2cRxWithData (unsigned char Object, unsigned int  Length)
#endif
{
#if cI2cRxBufSize < 256
  register unsigned char    i;                            // 循环变量
#else
  register unsigned int     i;
#endif
  unsigned char             temp;                         // 临时变量
  CommI2cDataStru           *pI2c;                        // 指向I2C总线通讯收发数据处理变量的指针

  pI2c                      = &gstvI2c;                   // 取I2C总线通讯收发数据处理变量的首个地址
#ifdef PreCommI2cWithRedundantCode                        // “使用冗余程序代码”条件编译开始
  if (   (Length > cI2cRxBufSize) )                       // 检查要接收数据的总个数是否超过缓冲区长度?
  {
    Length                  =  cI2cRxBufSize;             // 截断要接收数据的总个数
  }
#endif                                                    // “PreCommI2cWithRedundantCode”

  MFHI2cBusModSwRst( );                                   // 软件复位I2C模块,释放I2C总线
//  while(CommI2cBusBusy( ));                               // 等待直到对TWI下一个收发作业准备就绪为止

  gbitI2c.Busy              =  SET;                       // 置“I2C总线〖忙〗”标志
  gbitI2c.Txd               =  CLEAR;                     // 清除“正在进行发送数据作业”标志
  gbitI2c.Rxd               =  SET;                       // 置“正在进行发送数据作业”标志
  gbitI2c.OverS             =  SET;                       // 置“通讯任务时间超时”标志
  gucvI2cEvent              =  cI2cAllNoState;            // 置I2C总线的状态码 = 没有相关的状态信息
  pI2c->OverS               =  RtcGetSecByte(cI2cOverSec);// 启动通讯任务时间计时秒表
  MemCopySramToSram(&Object, pI2c->TxBuf, cI2cAddrNum);   // 复制目标设备地址到发送数据缓冲区中
  pI2c->TxBuf[0]           |= (u8)( BIT0);                // 设置数据传送方向为接收数据
  pI2c->TxSize              =  cI2cAddrNum;               // 置每次发送数据个数大小值
  pI2c->TxCnt               =  0x00;                      // 每次发送数据计数器值清0
  pI2c->Cycle               =  0x00;                      // 重新启动通讯收发作业圈数清0
  pI2c->ErrNum              =  0x00;                      // I2C总线的通讯收发作业发生错误次数清0

  pI2c->RxSize              =  Length;                    // 置I2C总线每次接收数据个数大小的值
  pI2c->RxCnt               =  0x00;                      // I2C总线每次接收数据个数计数器清0
  MFHI2cFlgEventClr( );                                   // 清0I2C总线事件中断标志位
  MFHI2cIntEventOne( );                                   // 使能I2C总线事件中断、错误中断,禁止缓冲中断
  MFHI2cBusNackStar( );                                   // 发出 START 信号(起始条件),没有 ACK 脉冲
}

/*==========================================================================================================
函数名称:  启动I2C总线应用中断方式先发送若干地址然后再进行发送数据作业的函数。
函数功能:  本函数用于启动I2C总线使用中断方式,进行通讯先发送若干地址然后再进行发送数据作业操作的函数。
函数入口参数:Object ------------------ 要发送数据的的目标设备地址值。
              *pAddr ------------------ 指向首个要发送地址在SRAM中的地址指针。
              LenAddr ----------------- 要发送地址的地址总长度。
              *pData ------------------ 指向首个要发送数据在SRAM中的地址指针。
              Length ------------------ 要发送数据的数据总长度。
函数返回值: 没有
函数出口参数:gbitI2c.Busy ------------ I2C总线〖忙〗,出口值=置位。
              gbitI2c.Txd ------------- “正在进行发送数据作业”标志,出口值=置位。
              gbitI2c.Rxd ------------- “正在进行接收数据作业”标志,出口值=清位。
              gucvI2cEvent ------------ I2C总线的状态码变量,出口值= cI2cAllNoState(没有相关的状态信息) 。
       gstvI2c.TxSize ---------- 每次发送数据个数大小变量,出口值=LenAddr + Length + cI2cAddrNum。
       gstvI2c.TxCnt ----------- 每次发送数据个数计数器变量,出口值=0。
       gstvI2c.TxBuf[] --------- 每次发送数据缓冲区数组变量,出口值=要发送的地址和数据。
       gstvI2c.Cycle ----------- 重新启动通讯收发作业圈数,出口值=0。
       gstvI2c.ErrNum ---------- 通讯收发作业发生错误次数,出口值=0。
调用函数:  1.
备注:        1.注意:调用本函数之前,必须确定I2C总线在空闲状态。即必须先调用
            “unsigned char CommI2cBusBusy(void)”函数,来检查I2C总线的工作状态,
            只有I2C总线处于空闲状态,才允许调用本函数。
       2.调用本函数将触发两线串行总线接口TWI中断请求和向I2C总线发出 START 信号(起始条件)。
==========================================================================================================*/
#if cI2cTxBufSize < 256
void  CommI2cTxWithAddr (unsigned char Object, unsigned char *pAddr, unsigned char LenAddr, unsigned char *pData, unsigned char Length)
#else
void  CommI2cTxWithAddr (unsigned char Object, unsigned char *pAddr, unsigned char LenAddr, unsigned char *pData, unsigned int  Length)
#endif
{
#if cI2cTxBufSize < 256
  register unsigned char    i;                            // 循环变量
#else
  register unsigned int     i;
#endif
  unsigned char             temp;                         // 临时变量
  CommI2cDataStru           *pI2c;                        // 指向I2C总线通讯收发数据处理变量的指针

  pI2c                      = &gstvI2c;                   // 取I2C总线通讯收发数据处理变量的首个地址

#ifdef PreCommI2cWithRedundantCode                        // “使用冗余程序代码”条件编译开始
  if (   ((LenAddr + Length) > (cI2cTxBufSize - 1))       // 检查要接收数据的总个数是否超过缓冲区长度?
      || (LenAddr == 0)                   )
  {
    return;
  }
#endif                                                    // “PreCommI2cWithRedundantCode”

  MFHI2cBusModSwRst( );                                   // 软件复位I2C模块,释放I2C总线
//  while(CommI2cBusBusy( ));                               // 等待直到对TWI下一个收发作业准备就绪为止

  gbitI2c.Busy              =  SET;                       // 置“I2C总线〖忙〗”标志
  gbitI2c.Txd               =  SET;                       // 置“正在进行发送数据作业”标志
  gbitI2c.Rxd               =  CLEAR;                     // 清除“正在进行接收数据作业”标志
  gbitI2c.OverS             =  SET;                       // 置“通讯任务时间超时”标志
  gucvI2cEvent              =  cI2cAllNoState;            // 置I2C总线的状态码 = 没有相关的状态信息
  pI2c->OverS               =  RtcGetSecByte(cI2cOverSec);// 启动通讯任务时间计时秒表
//  pI2c->Object              =  Object;                    // 复制目标设备地址到每次发送数据的目标设备地址中
//  pI2c->Object             &= (u8)(~BIT0);                // 设置数据传送方向为写入数据
//  pUsart->pTxData           =  pData;                     // 保存要发送的数据序列的地址指针
  MemCopySramToSram(&Object, pI2c->TxBuf, cI2cAddrNum);   // 复制目标设备地址到发送数据缓冲区中
  pI2c->TxBuf[0]           &= (u8)(~BIT0);                // 设置数据传送方向为写入数据
  MemCopySramToSram(pAddr, &pI2c->TxBuf[cI2cAddrNum], LenAddr);
                                                          // 复制发送的地址序列到发送数据缓冲区中
  MemCopySramToSram(pData, &pI2c->TxBuf[LenAddr + cI2cAddrNum], Length);
                                                          // 复制发送的数据序列到发送数据缓冲区中
  pI2c->TxSize              =  LenAddr + Length + cI2cAddrNum;
                                                          // 置每次发送数据个数大小值
  pI2c->TxCnt               =  0x00;                      // 每次发送数据计数器值清0
  pI2c->Cycle               =  0x00;                      // 重新启动通讯收发作业圈数清0
  pI2c->ErrNum              =  0x00;                      // I2C总线的通讯收发作业发生错误次数清0

  MFHI2cFlgEventClr( );                                   // 清0I2C总线事件中断标志位
  MFHI2cIntEventOne( );                                   // 使能I2C总线事件中断、错误中断,禁止缓冲中断
  MFHI2cBusNackStar( );                                   // 发出 START 信号(起始条件),没有 ACK 脉冲
}
磊元lystudio 回答时间:2015-10-2 01:54:42


/*==========================================================================================================
函数名称:  启动I2C总线应用中断方式先发送若干地址然后再进行接收数据作业的函数。
函数功能:  本函数用于启动I2C总线使用中断方式,进行通讯先发送若干地址然后再进行接收数据作业操作的函数。
函数入口参数:Object ------------------ 要接收数据的的目标设备地址值。
              *pAddr ------------------ 指向首个要发送地址在SRAM中的地址指针。
              LenAddr ----------------- 要发送地址的地址总长度。
              Length ------------------ 要接收数据的数据总长度。
函数返回值: 没有
函数出口参数:gbitI2c.Busy ------------ I2C总线〖忙〗,出口值=置位。
              gbitI2c.Txd ------------- “正在进行发送数据作业”标志,出口值=置位。
              gbitI2c.Rxd ------------- “正在进行接收数据作业”标志,出口值=置位。
              gucvI2cEvent ------------ I2C总线的状态码变量,出口值= cI2cAllNoState(没有相关的状态信息) 。
       gstvI2c.TxSize ---------- 每次发送数据个数大小变量,出口值=LenAddr + cI2cAddrNum。
       gstvI2c.TxCnt ----------- 每次发送数据个数计数器变量,出口值=0。
       gstvI2c.TxBuf[] --------- 每次发送数据缓冲区数组变量,出口值=要发送的地址。
       gstvI2c.Cycle ----------- 重新启动通讯收发作业圈数,出口值=0。
       gstvI2c.ErrNum ---------- 通讯收发作业发生错误次数,出口值=0。
              gstvI2c.RxSize ---------- 每次接收数据个数大小变量,出口值=Length。
              gstvI2c.RxCnt ----------- 每次接收数据个数计数器变量,出口值=0。
调用函数:  1.
备注:        1.注意:调用本函数之前,必须确定I2C总线在空闲状态。即必须先调用
            “unsigned char CommI2cBusBusy(void)”函数,来检查I2C总线的工作状态,
            只有I2C总线处于空闲状态,才允许调用本函数。
       2.调用本函数将触发两线串行总线接口TWI中断请求和向I2C总线发出 START 信号(起始条件)。
==========================================================================================================*/
#if cI2cTxBufSize < 256
#if cI2cRxBufSize < 256
void  CommI2cRxWithAddr (unsigned char Object, unsigned char *pAddr, unsigned char LenAddr, unsigned char Length)
#else
void  CommI2cRxWithAddr (unsigned char Object, unsigned char *pAddr, unsigned char LenAddr, unsigned int  Length)
#endif
#else
#if cI2cRxBufSize < 256
void  CommI2cRxWithAddr (unsigned char Object, unsigned char *pAddr, unsigned int  LenAddr, unsigned char Length)
#else
void  CommI2cRxWithAddr (unsigned char Object, unsigned char *pAddr, unsigned int  LenAddr, unsigned int  Length)
#endif
#endif
{
#if cI2cTxBufSize < 256
  register unsigned char    i;                            // 循环变量
#else
  register unsigned int     i;
#endif
  unsigned char             temp;                         // 临时变量
  CommI2cDataStru           *pI2c;                        // 指向I2C总线通讯收发数据处理变量的指针

  pI2c                      = &gstvI2c;                   // 取I2C总线通讯收发数据处理变量的首个地址

#ifdef PreCommI2cWithRedundantCode                        // “使用冗余程序代码”条件编译开始
  if (   (LenAddr >= (cI2cTxBufSize - 1))
      || (LenAddr == 0)                   )
  {
    return;
  }
  if (   (Length > cI2cRxBufSize) )                       // 检查要接收数据的总个数是否超过缓冲区长度?
  {
    Length                  =  cI2cRxBufSize;             // 截断要接收数据的总个数
  }
#endif                                                    // “PreCommI2cWithRedundantCode”

  MFHI2cBusModSwRst( );                                   // 软件复位I2C模块,释放I2C总线
//  while(CommI2cBusBusy( ));                               // 等待直到对TWI下一个收发作业准备就绪为止

  gbitI2c.Busy              =  SET;                       // 置“I2C总线〖忙〗”标志
  gbitI2c.Txd               =  SET;                       // 置“正在进行发送数据作业”标志
  gbitI2c.Rxd               =  SET;                       // 置“正在进行接收数据作业”标志
  gbitI2c.OverS             =  SET;                       // 置“通讯任务时间超时”标志
  gucvI2cEvent              =  cI2cAllNoState;            // 置I2C总线的状态码 = 没有相关的状态信息
  pI2c->OverS               =  RtcGetSecByte(cI2cOverSec);// 启动通讯任务时间计时秒表
//  pI2c->Object              =  Object;                    // 复制目标设备地址到每次发送数据的目标设备地址中
//  pI2c->Object             &= (u8)(~BIT0);                // 设置数据传送方向为写入数据
//  pUsart->pTxData           =  pData;                     // 保存要发送的数据序列的地址指针
  MemCopySramToSram(&Object, pI2c->TxBuf, cI2cAddrNum);   // 复制目标设备地址到发送数据缓冲区中
  pI2c->TxBuf[0]           &= (u8)(~BIT0);                // 设置数据传送方向为写入数据
  MemCopySramToSram(pAddr, &pI2c->TxBuf[cI2cAddrNum], LenAddr);
                                                          // 复制发送的地址序列到发送数据缓冲区中
  pI2c->TxSize              =  LenAddr + cI2cAddrNum;     // 置每次发送数据个数大小值
  pI2c->TxCnt               =  0x00;                      // 每次发送数据计数器值清0
  pI2c->Cycle               =  0x00;                      // 重新启动通讯收发作业圈数清0
  pI2c->ErrNum              =  0x00;                      // I2C总线的通讯收发作业发生错误次数清0

  pI2c->RxSize              =  Length;                    // 置I2C总线每次接收数据个数大小的值
  pI2c->RxCnt               =  0x00;                      // I2C总线每次接收数据个数计数器清0
  MFHI2cFlgEventClr( );                                   // 清0I2C总线事件中断标志位
  MFHI2cIntEventOne( );                                   // 使能I2C总线事件中断、错误中断,禁止缓冲中断
  MFHI2cBusNackStar( );                                   // 发出 START 信号(起始条件),没有 ACK 脉冲
}
磊元lystudio 回答时间:2015-10-2 01:55:23

/*==========================================================================================================
函数名称:  I2C总线工作于单主机方式,使用中断进行接收和发送数据的中断服务程序。
函数功能:  本函数用于I2C总线工作于单主机方式,使用中断进行接收和发送数据的中断服务程序。
函数入口参数:gbitI2c.Rxd ------------- “正在进行接收数据作业”标志。
       gstvI2c.TxSize ---------- 每次发送数据个数大小变量。
       gstvI2c.TxCnt ----------- 每次发送数据个数计数器变量。
       gstvI2c.TxBuf[] --------- 每次发送数据缓冲区数组变量。
              gstvI2c.RxSize ---------- 每次接收数据个数大小变量。
函数返回值: 没有
函数出口参数:gbitI2c.Busy ------------ I2C总线〖忙〗,出口值=清位(可能)。
              gbitI2c.Error ----------- 通讯收发作业发生错误,出口值=置位(可能)。
              gucvI2cEvent ------------ I2C总线的状态码变量,出口值= 不确定。
       gstvI2c.TxCnt ----------- 每次发送数据个数计数器变量,出口值=gstvI2c.TxCnt。
       gstvI2c.ErrNum ---------- 通讯收发作业发生错误次数,出口值=不确定。
              gstvI2c.RxCnt ----------- 每次接收数据个数计数器变量,出口值=gstvI2c.RxSize。
              gstvI2c.RxBuf[] --------- 每次接收数据缓冲区变量,出口值=从I2C总线上接收到的数据。
调用函数:  1.
备注:        1.注意:本函数需在I2C总线中断请求的中断向量函数中调用。
                     在调用之前需对该中断向量进行初始化,使能该中断。
       2.全部完成通讯收发作业后,本函数将禁止I2C总线中断。
==========================================================================================================*/
#if   (   defined(_IAR_EW_AVR_)   \
       || defined(_IAR_EW_STM8_)  )
#pragma vector = int_I2C_vector
INTERRUPT_KEY void  CommI2c_isr (void)
#elif (defined(_KEIL_UV_MCS51_) )
void  CommI2c_isr (void) INTERRUPT_KEY int_I2C_vector using 0
#elif (   defined(_COSMIC_STM8_)  )
INTERRUPT_KEY void  CommI2c_isr (void)
#else
void CommI2cIsr(void);
#endif                                                    // “_IAR_EW_......”
#if   (defined(_IAR_EW_AVR_))
{
#if ((cI2cTxBufSize < 256) && (cI2cRxBufSize < 256))
  register unsigned char    cnt;                          // USART每次发送数据个数计数器变量
#else
  register unsigned int     cnt;
#endif
  unsigned char             temp;                         // 临时变量
  CommI2cDataStru           *pI2c;                        // 指向I2C总线通讯收发数据处理变量的指针

  pI2c                      = &gstvI2c;                   // 取I2C总线通讯收发数据处理变量的首个地址
  switch (TWSR & cI2cTwsrMask)                            // 判断已屏蔽非状态位的 TWI 状态寄存器状态位值?
  {
    case cI2cAllStart:                                    // START 信号已发送
    case cI2cAllRepStart:                                 // 重复 START 信号已发送
    {
      pI2c->TxCnt           =  0x00;                      // 每次发送数据计数器值清0
    }
    case cI2cMtxAddrAck:                                  // SLA+W 已发送,接收到 ACK
    case cI2cMtxDataAck:                                  // 数据已发送,接收到 ACK
    {
      cnt                   =  pI2c->TxCnt;               // 取I2C总线每次发送数据个数计数器变量
      if (cnt >= pI2c->TxSize)                            // 检查是否己完成发送通讯任务的全部数据?
      {                                                   // 是,在最后一个字节之后发出 STOP 信号
        if (gbitI2c.Rxd == SET)                           // 检查是否为读取I2C总线数据?
        {
          pI2c->TxBuf[0]   |= (u8)( BIT0);                // 设置数据传送方向为接收数据
          MFHI2cBusNackReps( );                           // 发出重复 START 信号(重新开始条件),没有 ACK 脉冲
        }
        else
        {
          gbitI2c.Busy      =  CLEAR;                     // 清除“I2C总线〖忙〗”标志
          gbitI2c.OverS     =  CLEAR;                     // 清除“通讯任务时间超时”标志
          MFHI2cIntEventOff( );                           // 禁止I2C总线事件中断
          MFHI2cBusNackStop( );                           // 发出 STOP 信号(结束条件),没有 ACK 脉冲
        }
      }
      else
      {
        I2CDR               =  pI2c->TxBuf[cnt];          // 从发送缓冲区中将发送数据写入到I2C总线
        cnt++;                                            // I2C总线每次发送数据个数计数器+1
        pI2c->TxCnt         =  cnt;                       // 返回I2C总线每次发送数据个数计数器值
        // 通过先读 I2CSR1,然后写入 I2CDR,来清0发送结束、发送数据寄存器空标志
        MFHI2cIntEventClr( );                             // 进入中断后,在中断句柄中,清0I2C总线事件中断标志位(在中断服务程序中)
      }
      break;
    }
    case cI2cMrxDataAck:                                  // 接收到数据,ACK 已返回
    {
      cnt                   =  pI2c->RxCnt;               // 取I2C总线每次接收数据个数计数器变量
      pI2c->RxBuf[cnt]      =  I2CDR;                     // 复制I2C总线读取到的字节到接收数据缓冲区中
      cnt++;                                              // I2C总线每次接收数据个数计数器+1
      pI2c->RxCnt           =  cnt;                       // 返回I2C总线每次接收数据个数计数器值
    }
    case cI2cMrxAddrAck:                                  // SLA+R 已发送,接收到 ACK
    {
      cnt                   =  pI2c->RxCnt;               // 取I2C总线每次接收数据个数计数器变量
      if (cnt < (pI2c->RxSize - 1))                       // 检查是否完成需要读取的数据长度?
      {
        MFHI2cBusRdataAck( );                             // 在接收之后发出 ACK 脉冲
      }
      else                                                // 在最后一个字节数据接收之后发出 NOT ACK
      {
        MFHI2cBusRdatNack( );                             // 在接收之后发出 NOT ACK
      }
      break;
    }
    case cI2cMrxDataNack:                                 // 接收到数据,NOT ACK 已返回
    {
      cnt                   =  pI2c->RxCnt;               // 取I2C总线每次接收数据个数计数器变量
      pI2c->RxBuf[cnt]      =  I2CDR;                     // 复制I2C总线读取到的字节到接收数据缓冲区中
      gbitI2c.Busy          =  CLEAR;                     // 清除“I2C总线〖忙〗”标志
      gbitI2c.OverS         =  CLEAR;                     // 清除“通讯任务时间超时”标志
      MFHI2cIntEventOff( );                               // 禁止I2C总线事件中断
      MFHI2cBusNackStop( );                               // 发出 STOP 信号(结束条件),没有 ACK 脉冲
      break;
    }
    case cI2cAllArbLost:                                  // SLA+W 或数据的仲裁失败
    {
      if (pI2c->ErrNum > cI2cErrorMax)                    // 检查通讯收发作业发生错误次数是否大于最大值?
      {
        gbitI2c.Error       =  SET;                       // 置“通讯收发作业发生错误”标志
        MFHI2cInnEventMem( );                             // 存储I2C总线的事件和状态存储器值
        MFHI2cIntEventOff( );                             // 禁止I2C总线事件中断
      }
      else
      {
        pI2c->ErrNum++;                                   // I2C总线的通讯收发作业发生错误次数值+1
        MFHI2cBusNackReps( );                             // 发出 START 或重复的 START 信号(起始条件),没有 ACK 脉冲
      }
      break;
    }
    case cI2cMtxAddrNack:                                 // SLA+W 已发送,接收到 NOT ACK
    case cI2cMrxAddrNack:                                 // SLA+R 已发送,接收到 NOT ACK
    case cI2cMtxDataNack:                                 // 数据已发送,接收到 NOT ACK
    case cI2cAllNoState:                                  // 没有相关的状态信息; TWINT = "0"
    case cI2cAllBusError:                                 // 由于非法的 START 信号或 STOP 信号引起的总线错误
    default:
    {
      gbitI2c.Error         =  SET;                       // 置“通讯收发作业发生错误”标志
      MFHI2cInnEventMem( );                               // 存储I2C总线的事件和状态存储器值
      MFHI2cIntEventOff( );                               // 禁止I2C总线事件中断
    }
  }

  INTERRUPT_RETURN( );
}
磊元lystudio 回答时间:2015-10-2 01:55:49

#elif ((defined(_IAR_EW_MCS51_)) || (defined(_KEIL_UV_MCS51_)))

#elif (   defined(_IAR_EW_STM8_) \
       || defined(_COSMIC_STM8_) )                        // “......_STM8 编译器”条件编译开始
{
#if ((cI2cTxBufSize < 256) && (cI2cRxBufSize < 256))
  register unsigned char    cnt;                          // USART每次发送数据个数计数器变量
#else
  register unsigned int     cnt;
#endif
  unsigned char             temp;                         // 临时变量
  CommI2cDataStru           *pI2c;                        // 指向I2C总线通讯收发数据处理变量的指针

  temp                      =  I2CSR2;                    // 取I2C状态寄存器2值
  if (temp & cI2cEvtSr2Mask)                              // 判断已屏蔽非状态位的I2C状态寄存器2值?
  {
    pI2c                    = &gstvI2c;                   // 取I2C总线通讯收发数据处理变量的首个地址
    switch (temp & cI2cEvtSr2Mask)                        // 判断已屏蔽非状态位的 TWI 状态寄存器状态位值?
    {
      case cI2cAllArbLost:                                // 仲裁失败【I2CSR2】
      {
        if (pI2c->ErrNum > cI2cErrorMax)                  // 检查通讯收发作业发生错误次数是否大于最大值?
        {
          gbitI2c.Error     =  SET;                       // 置“通讯收发作业发生错误”标志
          MFHI2cInnEventMem( );                           // 存储I2C总线的事件和状态存储器值
          MFHI2cIntEventOff( );                           // 禁止I2C总线事件中断
          MFHI2cBusNackStop( );                           // 发出 STOP 信号(结束条件),没有 ACK 脉冲
        }
        else
        {
          pI2c->ErrNum++;                                 // I2C总线的通讯收发作业发生错误次数值+1
          MFHI2cBusNackReps( );                           // 发出 START 或重复的 START 信号(起始条件),没有 ACK 脉冲
        }
        break;
      }
//      case cI2cMasterNack:                                // SLA 已发送,接收到 NOT ACK;或者数据已发送/接收到数据,接收到 NOT ACK/NOT ACK 已返回【I2CSR2】
//      case cI2cAllNoState:                                // 没有相关的状态信息; TWINT = "0"
//      case cI2cAllBusError:                               // 由于非法的 START 信号或 STOP 信号引起的总线错误
      default:
      {
        gbitI2c.Error       =  SET;                       // 置“通讯收发作业发生错误”标志
        MFHI2cInnEventMem( );                             // 存储I2C总线的事件和状态存储器值
        MFHI2cIntEventOff( );                             // 禁止I2C总线事件中断
        MFHI2cBusNackStop( );                             // 发出 STOP 信号(结束条件),没有 ACK 脉冲
      }
    }
  }
  else                                                    // I2C总线没有错误
  {
    // 通过先读 I2CSR1,然后再读 I2CSR3,来清0地址已被发送(主模式)/地址匹配(从模式)标志
    temp                    =  I2CSR1;                    // 取I2C状态寄存器1值
    if ((I2CSR3 & (u8)( (1<<i2cRXTX ))) == (u8)( (1<<i2cRXTX )))
    {                                                     // 检查I2C总线是否为发送数据?
      temp                 |= (u8)( BIT5);                // 是,
    }
    pI2c                    = &gstvI2c;                   // 取I2C总线通讯收发数据处理变量的首个地址
    switch (temp)                                         // 判断I2C状态寄存器1+I2C状态寄存器3值?
    {
      case cI2cAllStart:                                  // START 信号已发送
      case cI2cAllRepStart:                               // 重复 START 信号已发送
      {
        pI2c->TxCnt         =  0x00;                      // 每次发送数据计数器值清0
      }
      case cI2cMtxAddrAck:                                // SLA+W 已发送,接收到 ACK
      {
//        if (temp == cI2cMtxAddrAck)
//        {
          MFHI2cIntEventOnn( );                           // 使能缓冲中断
//        }
      }
      case cI2cMtxDataAck:                                // 数据已发送,接收到 ACK
      case cI2cMtxDataAckWait:                            // 数据已发送,接收到 ACK,且没有写新的数据到 I2CDR
      {
        cnt                 =  pI2c->TxCnt;               // 取I2C总线每次发送数据个数计数器变量
        if (cnt >= pI2c->TxSize)                          // 检查是否己完成发送通讯任务的全部数据?
        {                                                 // 是,在最后一个字节之后发出 STOP 信号
          if (gbitI2c.Rxd == SET)                         // 检查是否为读取I2C总线数据?
          {
            MFHI2cBusNackReps( );                         // 发出重复 START 信号(重新开始条件),没有 ACK 脉冲
            pI2c->TxBuf[0] |= (u8)( BIT0);                // 设置数据传送方向为接收数据
            // 通过先读 I2CSR1,然后写入 I2CDR,来清0发送数据寄存器空,字节发送结束,起始位(主模式)标志
//            MFHI2cIntEventClr( );                         // 进入中断后,在中断句柄中,清0I2C总线事件中断标志位(在中断服务程序中)
            I2CDR           =  pI2c->TxBuf[0];            // 从发送缓冲区中将发送数据写入到I2C总线
            MFHI2cIntEventOff( );                         // 禁止I2C总线事件中断
            MFHI2cIntEventOne( );                         // 使能I2C总线事件中断、错误中断,禁止缓冲中断
          }
          else
          {
            gbitI2c.Busy    =  CLEAR;                     // 清除“I2C总线〖忙〗”标志
            gbitI2c.OverS   =  CLEAR;                     // 清除“通讯任务时间超时”标志
            MFHI2cIntEventOff( );                         // 禁止I2C总线事件中断
            MFHI2cBusNackStop( );                         // 发出 STOP 信号(结束条件),没有 ACK 脉冲
          }
        }
        else
        {
          // 通过先读 I2CSR1,然后写入 I2CDR,来清0发送数据寄存器空,字节发送结束,起始位(主模式)标志
//          MFHI2cIntEventClr( );                           // 进入中断后,在中断句柄中,清0I2C总线事件中断标志位(在中断服务程序中)
          I2CDR             =  pI2c->TxBuf[cnt];          // 从发送缓冲区中将发送数据写入到I2C总线
          cnt++;                                          // I2C总线每次发送数据个数计数器+1
          pI2c->TxCnt       =  cnt;                       // 返回I2C总线每次发送数据个数计数器值
        }
        break;
      }
      case cI2cMrxDataAck:                                // 接收到数据,ACK 已返回
      case cI2cMrxDataAckWait:                            // 接收到数据,ACK 已返回,且 I2CDR 中的数据没有被读取
      {
        cnt                 =  pI2c->RxCnt;               // 取I2C总线每次接收数据个数计数器变量
        // 通过先读 I2CSR1,然后读取 I2CDR,来清0接收数据寄存器非空标志
//        MFHI2cIntEventClr( );                             // 进入中断后,在中断句柄中,清0I2C总线事件中断标志位(在中断服务程序中)
        pI2c->RxBuf[cnt]    =  I2CDR;                     // 复制I2C总线读取到的字节到接收数据缓冲区中
        cnt++;                                            // I2C总线每次接收数据个数计数器+1
        pI2c->RxCnt         =  cnt;                       // 返回I2C总线每次接收数据个数计数器值
        cnt                 =  pI2c->RxCnt;               // 取I2C总线每次接收数据个数计数器变量
        if      (cnt >= pI2c->RxSize)                     // 检查是否完成需要读取的数据长度?
        {
          gbitI2c.Busy      =  CLEAR;                     // 清除“I2C总线〖忙〗”标志
          gbitI2c.OverS     =  CLEAR;                     // 清除“通讯任务时间超时”标志
          MFHI2cIntEventOff( );                           // 禁止I2C总线事件中断
        }
        else if (cnt >= (pI2c->RxSize - 1))               // 在最后一个字节数据接收之后发出 NOT ACK
        {
          MFHI2cBusRdatNack( );                           // 在接收之后发出 NOT ACK
          MFHI2cBusNackStop( );                           // 发出 STOP 信号(结束条件),没有 ACK 脉冲
        }
        else
        {
          MFHI2cBusRdataAck( );                           // 在接收之后发出 ACK 脉冲
        }
        break;
      }
      case cI2cMrxAddrAck:                                // SLA+R 已发送,接收到 ACK
      {
        MFHI2cBusRdataAck( );                             // 在接收之后发出 ACK 脉冲
        MFHI2cIntEventOnn( );                             // 使能缓冲中断
        break;
      }
      default:
      {
        gbitI2c.Error       =  SET;                       // 置“通讯收发作业发生错误”标志
        MFHI2cInnEventMem( );                             // 存储I2C总线的事件和状态存储器值
        MFHI2cIntEventOff( );                             // 禁止I2C总线事件中断
        MFHI2cBusNackStop( );                             // 发出 STOP 信号(结束条件),没有 ACK 脉冲
      }
    }
  }

  (void)temp;                                             // 用以阻止编译器产生[temp]未使用的警告消息
  INTERRUPT_RETURN( );
}
#else
#error 错误:
#endif                                                    // “PreMcuIs__......”





#endif                                                    // “I2C总线工作于单主机方式”条件编译结束
磊元lystudio 回答时间:2015-10-2 01:56:07


/*==========================================================================================================
函数功能:    本函数是I2C总线通信接收和发送作业不间断循环调用运行函数。
备注:        ▲.注意:本函数为消息任务队列函数,要在主函数中不间断循环调用运行。
              ▲.当I2C总线工作于从机方式时,I2C总线中断总是处于使能状态,以便
                  I2C总线处于随时接收数据状态。
==========================================================================================================*/
void  CommI2cCircleFunc (void)
{
#ifdef DEBUG
  unsigned char i;                           // 循环计数器变量
  unsigned char j;
  unsigned char hex_data[2];
  unsigned char *ptr;
#endif
  unsigned char              i;                           // 循环计数器变量
  CommI2cDataStru           *pI2c;                        // 指向I2C总线通讯收发数据处理变量的指针

  pI2c                      = &gstvI2c;                   // 取I2C总线通讯收发数据处理变量的首个地址
#ifdef PreCommI2cUseSingleMasterMode                      // “I2C总线工作于单主机方式”的条件编译
  if (   (gbitI2c.Error == SET)                           // 如果I2C总线通讯收发作业发生错误,
      && ( ! CommI2cBusBusy( )) )                         // 且I2C总线收发器处于空闲状态?
  {
    if (pI2c->Cycle > cI2cErrorMax)                       // 检查重新启动收发作业错误次数是否大于最大值?
    {
      pI2c->Cycle           =  0x00;                      // I2C总线的重新启动收发作业发生错误次数清0
      gbitI2c.Error         =  CLEAR;                     // 清除“通讯收发作业发生错误”标志
      gbitI2c.Busy          =  CLEAR;                     // 清除“I2C总线〖忙〗”标志
#ifdef _SYSTEM_ERROR_MANAGE_H_
      sys_error_type       |=  SYS_ERROR_TYPE_IS_GENERAL; // 置【普通】错误类型消息任务标志位
      sys_error_value       =  SYS_ERROR_COMM_I2CBUS    ; // 置“I2C总线通信收发作业”错误代码值
#endif
    }
    else
    {
      pI2c->Cycle++;                                      // I2C的重新启动收发作业发生错误次数值+1
      gbitI2c.Error         =  CLEAR;                     // 清除“通讯收发作业发生错误”标志
      CommI2cBusAgain( );                                 // 重新启动I2C总线前一个通讯收发作业操作
    }
  }
  // 通讯任务时间超时计时处理,用以处理I2C总线直处于“BUSY”状态。
  if (gbitI2c.OverS == SET)
  {
    if (RtcSecByteOverflow(pI2c->OverS))                  // 如果通讯任务时间计时秒表时间已溢出?
    {
      I2CCR2      = (u8)( ((0<<i2cSTART)|                 // 禁止 START 信号(起始条件)
                           (0<<i2cSTOP )|(0<<i2cACKEN)|   // 禁止 STOP 信号(停止条件),使能 ACK 应答
                           (0<<i2cPOS  )|(1<<i2cRST  ) ));// 应答的位置=当前字节,复位I2C模块
      CLKPECR1   &= (u8)(~((1<<clkI2C  )));               // 禁止I2C外设时钟
      I2CCR1      = (u8)( ((0<<i2cEN   )|(0<<i2cGCEN )|   // 禁止I2C模块,禁止广播呼叫
                           (0<<i2cCKTEN) ));              // 禁止时钟延展
      MFH_PIN_CFG_OUTH_I2cScl;                            // 设置I2C时钟引脚为推挽输出,并为H电平(释放 SCL)
      MFH_PIN_CFG_OUTH_I2cSda;                            // 设置I2C数据引脚为推挽输出,并为H电平(释放 SDA)
      for (i=0; i<9; i++)                                 // 发送 9 个 SCL 时钟脉冲;在此过程中,SDA 为高电平,以复位从设备
      {
        DelayUs(1);
        MFH_PIN_OUT_CLRL_I2cScl;
        DelayUs(1);
        MFH_PIN_OUT_SETH_I2cScl;
      }
      CLKPECR1   |= (u8)( ((1<<clkI2C  )));               // 使能I2C外设时钟
      CommI2cInit( );                                     // 重新初始化I2C总线
    }
  }
#endif                                                    // “PreCommI2cUseSingleMasterMode”

}





#ifdef __cplusplus
}                                                         // extern "C" 链接指示符作用域结束
#endif


/*
************************************************************************************************************
                     本C语言源程序文件到此结束
************************************************************************************************************
*/


磊元lystudio 回答时间:2015-10-2 01:56:49
/*------------------------------------------------------------------------------------------------
         两线串行总线接口(I2C)
------------------------------------------------------------------------------------------------*/
// I2CCR1(I2C_CR1)——— I2C控制寄存器1
#define i2cEN                 0                           // I2C启动/停止使能位
#define i2cGCEN               6                           // 广播呼叫使能位
#define i2cCKTEN              7                           // 时钟延展禁止位

// I2CCR2(I2C_CR2)——— I2C控制寄存器2
#define i2cSTART              0                           // 起始位状态
#define i2cSTOP               1                           // 结束位状态
#define i2cACKEN              2                           // 应答使能位
#define i2cPOS                3                           // 应答的位置
#define i2cRST                7                           // 软件复位

// I2CARL(I2C_OARL)——— I2C(从机)地址低位寄存器
#define i2cADD0               0                           // I2C从机地址位0
#define i2cADD1               1                           // I2C从机地址位1
#define i2cADD2               2                           // I2C从机地址位2
#define i2cADD3               3                           // I2C从机地址位3
#define i2cADD4               4                           // I2C从机地址位4
#define i2cADD5               5                           // I2C从机地址位5
#define i2cADD6               6                           // I2C从机地址位6
#define i2cADD7               7                           // I2C从机地址位7
#define i2cADD17              1                           // I2C从机地址位1~7

// I2CARH(I2C_OARH)——— I2C(从机)地址高位寄存器
#define i2cADD8               1                           // I2C从机地址位8
#define i2cADD9               2                           // I2C从机地址位9
#define i2cCFG                6                           // 地址模式配置
#define i2cMODE               7                           // 寻址模式
#define i2cADD89              1                           // I2C从机地址位8~9

// I2CSR1(I2C_SR1)——— I2C状态寄存器1
#define i2cSTAF               0                           // 起始位(主模式)
#define i2cADDTR              1                           // 地址已被发送(主模式)/地址匹配(从模式)
#define i2cTXC                2                           // 字节发送结束
#define i2cADD10              3                           // 10位头序列已发送(主模式)
#define i2cSTODF              4                           // 停止条件检测位(从模式)
#define i2cRXNE               6                           // 接收数据寄存器非空
#define i2cDRE                7                           // 发送数据寄存器空

// I2CSR2(I2C_SR2)——— I2C状态寄存器2
#define i2cBERR               0                           // 总线错误
#define i2cARLO               1                           // 仲裁失败(主模式)
#define i2cACKF               2                           // 应答失败
#define i2cOVF                3                           // 溢出标志位
#define i2cWUF                5                           // 从停机(Halt)模式唤醒标志

// I2CSR3(I2C_SR3)——— I2C状态寄存器3
#define i2cMSF                0                           // 主/从机模式标志位
#define i2cBSY                1                           // 总线忙标志
#define i2cRXTX               2                           // 接收器/发送器,0:接收,1:发送
#define i2cGCF                4                           // 广播呼叫头序列(从模式)

// I2CICR(I2C_ITR)——— I2C中断控制寄存器
#define i2cERRIE              0                           // 错误中断使能位
#define i2cEVTIE              1                           // 事件中断使能位
#define i2cBUFIE              2                           // 缓冲中断使能位

// I2CCCRL(I2C_CCRL)——— I2C时钟控制低位寄存器
#define i2cCS0                0                           // 预分频器时钟选择位0
#define i2cCS1                1                           // 预分频器时钟选择位1
#define i2cCS2                2                           // 预分频器时钟选择位2
#define i2cCS3                3                           // 预分频器时钟选择位3
#define i2cCS4                4                           // 预分频器时钟选择位4
#define i2cCS5                5                           // 预分频器时钟选择位5
#define i2cCS6                6                           // 预分频器时钟选择位6
#define i2cCS7                7                           // 预分频器时钟选择位7

// I2CCCRH (I2C_CCRH)——— I2C时钟控制高位寄存器
#define i2cCS8                0                           // 预分频器选择控制位8
#define i2cCS9                1                           // 预分频器选择控制位9
#define i2cCSA                2                           // 预分频器选择控制位10
#define i2cCSB                3                           // 预分频器选择控制位11
#define i2cDUTY               6                           // 快速模式下的占空比
#define i2cSFM                7                           // 标准/快速模式选择位
磊元lystudio 回答时间:2015-10-2 01:57:14
__IO_REG8_BIT(I2CCR1    , 0x5210, __READ_WRITE, __BITS_I2C_CR1      );// I2C控制寄存器1
__IO_REG8_BIT(I2CCR2    , 0x5211, __READ_WRITE, __BITS_I2C_CR2      );// I2C控制寄存器2
__IO_REG8_BIT(I2CFR     , 0x5212, __READ_WRITE, __BITS_I2C_FREQR    );// I2C频率寄存器
__IO_REG8_BIT(I2CARL    , 0x5213, __READ_WRITE, __BITS_I2C_OARL     );// I2C(从机)地址低位寄存器
__IO_REG8_BIT(I2CARH    , 0x5214, __READ_WRITE, __BITS_I2C_OARH     );// I2C(从机)地址高位寄存器
__IO_REG8    (I2CDR     , 0x5216, __READ_WRITE                      );// I2C数据寄存器
__IO_REG8_BIT(I2CSR1    , 0x5217, __READ,       __BITS_I2C_SR1      );// I2C状态寄存器1
__IO_REG8_BIT(I2CSR2    , 0x5218, __READ_WRITE, __BITS_I2C_SR2      );// I2C状态寄存器2
__IO_REG8_BIT(I2CSR3    , 0x5219, __READ,       __BITS_I2C_SR3      );// I2C状态寄存器3
__IO_REG8_BIT(I2CICR    , 0x521A, __READ_WRITE, __BITS_I2C_ITR      );// I2C中断控制寄存器
__IO_REG8    (I2CCCRL   , 0x521B, __READ_WRITE                      );// I2C比特率低位寄存器
__IO_REG8_BIT(I2CCCRH   , 0x521C, __READ_WRITE, __BITS_I2C_CCRH     );// I2C比特率高位寄存器
__IO_REG8_BIT(I2CTRISER , 0x521D, __READ_WRITE, __BITS_I2C_TRISER   );// I2CTRISE寄存器
__IO_REG8    (I2CPECR   , 0x521E, __READ_WRITE                      );// I2C包错误检查寄存器
guiyi 回答时间:2015-10-2 08:28:22
感谢分享~一大串
你好我好大家好! 回答时间:2015-10-2 09:36:00
这是干什么呢,求关注吗

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版