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

2009-3-24 23:28 4361 3 5 分类: MCU/ 嵌入式




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();//通讯失败
  }
}

PARTNER CONTENT

文章评论2条评论)

登录后参与讨论

雁塔菜农 2009-4-2 00:07

哈哈~~~这是俺多年I2C悟出的裸奔道理,可惜很多人不明白它的真谛~~~

用户31709 2009-4-1 21:13

很好的I2C程序,可惜电源界中理解的人几乎没有,他们不知道I2C是电源管理总线PMBUS的姐妹。
相关推荐阅读
雁塔菜农 2012-04-05 17:51
2012年度新唐Cortex-M0助学开发套件有约束条件赠送申报贴
2012年度新唐Cortex-M0助学套件从4月起每月有约束条件发放16套。 申报人必须是21ic或 EDNC 会员 并具备1月的会龄。 申报时必须注明“遵守约束条件,缴纳250元订金,上...
雁塔菜农 2012-04-05 17:04
2012年度Cortex-M0助学园地推广框图
...
雁塔菜农 2012-04-01 17:59
2012年度Cortex-M0助学园地奖励计划细则
抢楼请点击:菜地公告:即日起创建《菜农Cortex-M0助学园地》(盖楼入口) 每月10号和25号的下午2:50进行2次抢楼,规则同去年12月的疯狂抢楼活动。 奖品由21IC、北航、广州迪圣...
雁塔菜农 2012-02-03 08:19
菜农谋略:搞定牛人宋俊德,对女牛人孙昌旭说:“记住,俺是雁塔菜农~~~ ”
http://www.baidu.com/s?wd=%B2%CB%C5%A9%D0%A6%CC%B8%A1%B6%D0%C2%C0%CB%C3%FB%C8%CB%D0%A7%D3%A6%A1%B7...
EE直播间
更多
我要评论
2
3
关闭 站长推荐上一条 /3 下一条