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

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扩展软件包
关注我们
st-img 微信公众号
st-img 手机版