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

STM8S I2C总线中断程序

[复制链接]
磊元lystudio 发布时间:2015-10-2 01:49
阅读主题, 点击返回1楼
收藏 1 评论23 发布时间:2015-10-2 01:49
23个回答
磊元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包错误检查寄存器
皈依 回答时间:2015-10-2 08:28:22
感谢分享~一大串
你好我好大家好! 回答时间:2015-10-2 09:36:00
这是干什么呢,求关注吗
#define 回答时间:2015-10-3 11:09:15
MARK   最近在弄    问下   3.5的库 现在I2C中断还有问题吗
cos12a-21701 回答时间:2015-10-3 20:46:56
时光飞逝,都2016了。
磊元lystudio 回答时间:2015-10-22 22:45:50
修改一处错误:将
      case cI2cMrxAddrAck:                                // SLA+R 已发送,接收到 ACK
      {
        MFHI2cBusRdataAck( );                             // 在接收之后发出 ACK 脉冲
        MFHI2cIntEventOnn( );                             // 使能缓冲中断
        break;
      }
改为:
      case cI2cMrxAddrAck:                                // SLA+R 已发送,接收到 ACK
      {
        if (pI2c->RxSize <= 1)                            // 如果只接收1个字节?
        {
          MFHI2cBusRdatNack( );                           // 在接收之后发出 NOT ACK
          MFHI2cBusNackStop( );                           // 发出 STOP 信号(结束条件),没有 ACK 脉冲
        }
        else
        {
          MFHI2cBusRdataAck( );                           // 在接收之后发出 ACK 脉冲
        }
        MFHI2cIntEventOnn( );                             // 使能缓冲中断
        break;
      }
以避免只接收1个字节时,发生溢出错误。
samsamhoo 回答时间:2015-10-25 18:50:25
好资料,谢谢分享。
12
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版