专栏中心

EEPW首页 > 专栏 > I2C(TWI/SMBUS)LPC213X主机通讯例程

I2C(TWI/SMBUS)LPC213X主机通讯例程

发布人:mayer 时间:2009-05-23 来源:工程师 发布文章
I2C(TWI/SMBUS)LPC213X主机通讯例程


I2C(TWI/SMBUS)LPC213X主机通讯例程
雁塔菜农 发表于 2006-10-28 11:33:00

void TwiObj::TWStart(void)
{
  Busy = true;
  Status = 0;//主机准备发送启始位
  Count = 0;//发送数据个数
  I2C0->I2C_CONSET = (1 << I2EN) | (1 << STA);
}

void TwiObj::TWREStart(void)
{
  Busy = true;
  Status = 0x55;//主机准备发送启始位
  Count = 0;//接收数据个数
  I2C0->I2C_CONCLR = (1 << STA) | (1 << SI) | (1 << AA);
  I2C0->I2C_CONSET = (1 << I2EN) | (1 << STA);
}
//__inline
void TwiObj::TWStop(void)
{
  Busy = false;
  Status = 0x88;//通讯成功
  I2C0->I2C_CONSET = (1 << I2EN) | (1 << STO);
  I2C0->I2C_CONCLR = (1 << STA) | (1 << SI) | (1 << AA);
}

void TwiObj::TWExit(void)
{
  Busy = false;//通讯失败
  I2C0->I2C_CONSET = (1 << I2EN) | (1 << STO);
  I2C0->I2C_CONCLR = (1 << STA) | (1 << SI) | (1 << AA);
}

void TwiObj::Exec(void)
{
  switch(I2C0->I2C_STAT & 0xf8) {
    case I2C_START://主机收到自己发送的开始信号
        if (Status == 0) {//本次中断应该接收TW_START信号//pwy
          I2C0->I2C_DAT = SubAddr & 0xfe;//发送子机地址(写)
    Status = 1;//Status下次主发为1,主收为2
             I2C0->I2C_CONCLR = (1 << STA) | (1 << SI) | (1 << AA);//清除中断标志
     }
     else TWExit();//通讯失败
        break;
 case I2C_REP_START://主机收到自己发送的重新开始信号
        if ((Status == 0x55) && (SubAddr & 0xfe)) {//本次中断应该接收TW_START信号//pwy
          I2C0->I2C_DAT = SubAddr;//发送子机地址(读)
       Status = 2;//Status下次主发为1,主收为2
             I2C0->I2C_CONCLR = (1 << STA) | (1 << SI) | (1 << AA);//清除中断标志
     }
     else TWExit();//通讯失败
        break;
 case I2C_MT_SLA_ACK://主发机接收到从机的地址应答信号后发送命令
        if (Status == 1) {//本次中断应该接收TW_MT_SLA_ACK信号
       Status = 3;//Status下次应该收TW_MT_DATA_ACK
             I2C0->I2C_DAT = SubComm;//发送子机命令
             I2C0->I2C_CONCLR = (1 << STA) | (1 << SI) | (1 << AA);//清除中断标志
     }
     else TWExit();//通讯失败
        break;
 case I2C_MR_SLA_ACK://主收机接收到从机的地址应答信号
        if (SubCount && (Status == 2)) {//本次中断应该接收TW_MR_SLA_ACK信号
       Status = 4;//Status下次应该收TW_MR_DATA_ACK
             I2C0->I2C_CONCLR = (1 << STA) | (1 << SI);//清除中断标志,主机转入接收状态
    I2C0->I2C_CONSET = (1 << AA);
     }
     else TWExit();//通讯失败
     break;
 case I2C_MT_DATA_ACK:
        if ((Count < MainCount) && (Status == 3)) {//本次中断应该接收TW_MT_DATA_ACK信号
          I2C0->I2C_DAT = TxBuffer[Count ++];//发送子机数据
             I2C0->I2C_CONCLR = (1 << STA) | (1 << SI) | (1 << AA);//清除中断标志
     }
     else {
          if ((Count == MainCount) && (Status == 3) && (SubAddr & 1)) {//本次中断应该接收TW_MT_DATA_ACK信号
         TWREStart();//
    }
             else TWExit();//通讯失败
     }
     break;
// case I2C_MT_DATA_NACK://数据发送结束
//         TWExit();//通讯失败
//     break;
 case I2C_MR_DATA_ACK:
        if ((Count < SubCount) && (Status == 4)) {
          RxBuffer[Count ++] = I2C0->I2C_DAT;//接收子机数据
    if (Count < SubCount) {
               I2C0->I2C_CONCLR = (1 << STA) | (1 << SI);//主机转入接收状态
      I2C0->I2C_CONSET = (1 << AA);//
    }
    else {
               I2C0->I2C_CONCLR = (1 << STA) | (1 << SI) | (1 << AA);//清除中断标志,主机转入接收状态
      Status = 6;//下次进入I2C_MR_DATA_NACK,接收数据准备完成
    }
     }
     else TWExit();//通讯失败
     break;
 case I2C_MR_DATA_NACK://数据接收结束
        if ((Count == SubCount) && (Status == 6)) {
       SetDataBuff();//取出接收字节
       TWStop();//通讯成功
     }
     else TWExit();//通讯失败
     break;
 default:
     TWExit();//通讯失败
  }
}

专栏文章内容及配图由作者撰写发布,仅供工程师学习之用,如有侵权或者其他违规问题,请联系本站处理。 联系我们

关键词:

相关推荐

ysjabcd_速度里程计带时间显示.红外调时

视频 2011-12-16

从pc机的串行口获取单片机工作电源的方法

单片机复位和看门狗芯片max813 max705-708

Marvell,赌对了

智能计算 2025-06-06

肖特马来西亚欢庆50周年纪念: 坚守玻璃加工技术

串行接口16键 键盘控制接口芯片sk5278

IDC预计,2029年中国物联网支出规模将达到2515亿美元

串口扩展芯片MAX3100,给你的单片机扩展一个串口

AI服务器电源三大技术跃迁与测试破局

数据中心芯片,更香了

高温IC设计必懂基础知识:高温设计的优势

中国基础大语言模型市场格局初定

pzcc2010_流水灯演示

视频 2011-12-16

maj0308_点阵循环显示阿拉伯数字0—9

视频 2011-12-16

单芯片usb转串口uart的数据转换芯片 CP2101

Gartner:企业通过数据管理获取AI价值的五大要素

ylzhjy_日期、时间的显示与调整

视频 2011-12-16

ASIC市场,越来越大了

嵌入式系统 2025-06-06

朔萌阁主_八位灯交叉闪烁

视频 2011-12-16

BOE(京东方)控股子公司武汉京东方回购少数股东股权

更多 培训课堂
更多 焦点
更多 视频

技术专区