原创 万能I2C通讯

2009-11-7 14:02 1804 4 4 分类: MCU/ 嵌入式

应用在没有集成I2C的MCU上或MPU、DSP

void SendByte(uchar c)
{
uchar BitCnt;

for(BitCnt=0;BitCnt<8;BitCnt++) /*要传送的数据长度为8位
*/
    {
     if((c<<BitCnt)&0x80)SDA=1;   /*判断发送位
*/   以最高位一位一位的读 高电平SDA=1反之SDA=0
       else SDA="0";               
     _Nop();
     SCL=1;              用SCL串行时钟来控制SDA同步发送,所以这个循环里面要有SCL的高低电平(代表一个周期)


      _Nop();
      _Nop();             /*保证时钟高电平周期大于
4μs*/
      _Nop();
      _Nop();
      _Nop();         
     SCL=0;                  最终的低电平也是为了后来能够读取SDA  因为只有scl低电平sda才能被读取
    }
   
    _Nop();
    _Nop();
    SDA="1";                /*8位发送完后释放数据线,准备接收应答位
*/ 记住高电平释放数据总线就行了
                           主机通过SDA是否被被控机置1来判断是否应答!
    _Nop();
    _Nop();   
    SCL="1";                 第九个周期高电平期判断SDA的状态  
    _Nop();
    _Nop();
    _Nop();
    if(SDA==1)ack=0;     
       else ack="1";        /*判断是否接收到应答信号
*/
    SCL="0";
    _Nop();
    _Nop();



/*******************************************************************
                 字节数据接收函数               
函数原型: uchar RcvByte();
功能:    用来接收从器件传来的数据,并判断总线错误(不发应答信号),
          发完后请用应答函数应答从机。
********************************************************************/
uchar RcvByte()
{
uchar retc;
uchar BitCnt;

retc=0;
SDA=1;                /*置数据线为输入方式*/    这是主机在释放数据线,释放后由被控机控制
for(BitCnt=0;BitCnt<8;BitCnt++)
      {
        _Nop();           
        SCL=0;                  /*置时钟线为低,准备接收数据位*/  因为只有低电平SDA才能改变
        _Nop();
        _Nop();                 /*时钟低电平周期大于4.7μs*/
        _Nop();
        _Nop();
        _Nop();
        SCL=1;                  /*置时钟线为高使数据线上数据有效*/
        _Nop();
        _Nop();
        retc=retc<<1;
        if(SDA==1)retc=retc+1; /*读数据位,接收的数据位放入retc中 */
        _Nop();
        _Nop();
      }
SCL=0;   
_Nop();
_Nop();
return(retc);
}


PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
4
关闭 站长推荐上一条 /3 下一条