• STM8 I/O口模拟I2C


    STM8I/O口模拟I2C所读数据不正确
    STM8 I/O口模拟I2C
    
    
    #define I2C_ERR   0
    
    #define I2C_CRR   1
    
    #define  I2CDataIn  1
    
    #define  I2CDataOut 0
    
    #define I2C_PORT  (GPIOC)
    
    #define I2CSCL   (GPIO_PIN_7)
    
    #define I2CSDA   (GPIO_PIN_6)
    
    
    //***************************************************************
    
    // I2C Data input/output
    
    // 0-Output, 1-Input
    
    //***************************************************************
    
    void I2CDataInOut(bool InOut)
    
    {
    
    if(InOut)
    
      {
    
      GPIO_Init(I2C_PORT,I2CSDA,GPIO_MODE_IN_FL_NO_IT);
    
      }
    
    else
    
      {
    
      GPIO_Init(I2C_PORT,I2CSDA,GPIO_MODE_OUT_OD_LOW_FAST);
    
      }
    
    }
    
    //***************************************************************
    
    //  Send start condition
    
    //  ensure data is high then issue a start condition
    
    //  see also i2c_Start() macro
    
    //***************************************************************
    
    void I2C_Start (void)
    
    {
    
    GPIO_WriteHigh(I2C_PORT, I2CSDA);
    
    _delay_5us(5);
    
    GPIO_WriteHigh(I2C_PORT, I2CSCL);
    
    _delay_5us(5);
    
    GPIO_WriteLow(I2C_PORT, I2CSDA);
    
    _delay_5us(5);
    
    }
    
    //***************************************************************
    
    //   Send stop condition
    
    //   data low-high while clock high
    
    //***************************************************************
    
    void I2C_Stop (void)
    
    {
    
    GPIO_WriteLow(I2C_PORT, I2CSDA);
    
    _delay_5us(5);
    
    GPIO_WriteHigh(I2C_PORT, I2CSCL);
    
    _delay_5us(5);
    
    GPIO_WriteHigh(I2C_PORT, I2CSDA);
    
    }
    
    //***************************************************************
    
    //ROUTINE NAME : I2C_Ack
    
    //INPUT/OUTPUT : None.
    
    //DESCRIPTION  : Acknoledge generation from now.
    
    //COMMENTS     : Transfer sequence = DATA, ACK.
    
    //***************************************************************
    
    void I2C_Rack(void)
    
    {
    
    GPIO_WriteLow(I2C_PORT, I2CSDA);
    
    _delay_5us(5);
    
    GPIO_WriteHigh(I2C_PORT, I2CSCL);
    
    _delay_5us(5);
    
    GPIO_WriteLow(I2C_PORT, I2CSCL);
    
    _delay_5us(5);
    
    }
    
    
    //***************************************************************
    
    //ROUTINE NAME : I2C_nAck
    
    //INPUT/OUTPUT : None.
    
    //DESCRIPTION  : Non acknoledge generation from now.
    
    //COMMENTS     : Transfer sequence = DATA, NACK.
    
    //***************************************************************
    
    void I2C_nAck (void)
    
    {
    
    GPIO_WriteHigh(I2C_PORT, I2CSDA);
    
    _delay_5us(5);
    
    GPIO_WriteHigh(I2C_PORT, I2CSCL);
    
    _delay_5us(5);
    
    GPIO_WriteLow(I2C_PORT, I2CSCL);
    
    _delay_5us(5);
    
    }
    
    //***************************************************************
    
    //  Send a byte to the slave 写一个数据没有应答
    
    //  return I2C_ERR OR I2C_CRR
    
    //***************************************************************
    
    bool SendByte(UCHAR I2cData)
    
    {
    
    UCHAR i;
    
    bool I2CStatus;
    
    
    for(i=0; i<8; i++)
    
      {
    
      GPIO_WriteLow(I2C_PORT, I2CSCL);
    
      _delay_5us(5);
    
      if(I2cData & 0x80)
    
       {GPIO_WriteHigh(I2C_PORT, I2CSDA);}
    
      else
    
       {GPIO_WriteLow(I2C_PORT, I2CSDA);}
    
      GPIO_WriteHigh(I2C_PORT, I2CSCL);
    
      _delay_5us(5);
    
      I2cData <<= 1;
    
      }
    
      GPIO_WriteLow(I2C_PORT, I2CSCL);
    
      GPIO_WriteHigh(I2C_PORT, I2CSDA);//发送完一字节,接收应答
    
      
    
      I2CDataInOut(I2CDataIn);
    
    
      GPIO_WriteHigh(I2C_PORT, I2CSCL);
    
      _delay_5us(5);
    
      if(GPIO_ReadInputPin(I2C_PORT,I2CSDA) == 0)
    
       {
    
       I2CStatus = I2C_CRR;
    
       }
    
      else
    
       {
    
       I2CStatus = I2C_ERR;
    
       }
    
      I2CDataInOut(I2CDataOut);
    
      return I2CStatus;
    
    }
    
    
    //***************************************************************
    
    //ROUTINE NAME : I2Cm_RxData
    
    //INPUT/OUTPUT : Last byte to receive flag (active high)/Received data byte.
    
    //DESCRIPTION  : Receive a data byte.
    
    //COMMENTS     : Transfer sequence = DATA, ACK, EV7...
    
    //***************************************************************
    
    UCHAR RcvByte(void)
    
    {   
    
        UCHAR i;
    
        UCHAR ReadByte=0;
    
       GPIO_WriteHigh(I2C_PORT, I2CSDA);
    
    
    I2CDataInOut(I2CDataIn);
    
    _delay_5us(10);
    
    for(i=0; i<8; i++)
    
      {
    
       ReadByte <<= 1;
    
       GPIO_WriteLow(I2C_PORT, I2CSCL);
    
       _delay_5us(5);
    
       GPIO_WriteHigh(I2C_PORT, I2CSCL);
    
       _delay_5us(5);
    
    
       if(GPIO_ReadInputPin(I2C_PORT,I2CSDA) == 1)
    
        {ReadByte |= 0x01;}
    
       _delay_5us(5);
    
      }  
    
    GPIO_WriteLow(I2C_PORT, I2CSCL);
    
    I2CDataInOut(I2CDataOut);
    
    _delay_5us(10);
    
       return ReadByte;
    
    }
    
    
    /*******************************************************
    
      读N个数据,参数:?
    
       wrDAdr: write device-address 写器件地址??
    
       wordAdr: word address 读数据的寄存器地址??
    
       rdDAdr: read device-address 读器件地址
    
       *pRdDat: p->read data 读数据指针
    
       num: number 需要读数据的个数
    
    *******************************************************/
    
    bool I2C_Read(UCHAR wrDAdr,UCHAR wordAdr,UCHAR *pRdDat,UCHAR num)
    
    {
    
    bool I2CAck;
    
    UCHAR i=0;
    
    UCHAR rdDAdr;
    
    rdDAdr = wrDAdr+1; //读器件地址为写地址加1
    
    I2C_Start();  /*启动I2C*/
    
    _delay_5us(5);
    
    I2CAck = SendByte(wrDAdr); /*发写器件地址*/
    
    if(!I2CAck)
    
      {
    
       return I2C_ERR;
    
      }
    
    I2CAck = SendByte(wordAdr); /*发寄存器地址*/
    
    if(!I2CAck)
    
      {
    
       return I2C_ERR;
    
      }
    
    
    I2C_Start();   /*重启I2C*/
    
      I2CAck = SendByte(rdDAdr); /*发读器件地址*/
    
    if(!I2CAck)
    
      {
    
       return I2C_ERR;
    
      }
    
    _delay_5us(5);
    
    for(i=0;i<num-1;i++)
    
      {
    
      *(pRdDat+i) = RcvByte();
    
      I2C_Rack();
    
       }
    
    if(i==num-1)
    
      {
    
      *(pRdDat+i) = RcvByte();
    
      I2C_nAck();
    
      }
    
    I2C_Stop();
    
    return I2C_CRR;
    
    }
    
    
    /*******************************************************
    
    写N个数据,前N-1个要应答,最后一个不要应答
    
    wrDAdr: write device-address 写器件地址??
    
      wordAdr: word address 写数据的寄存器地址?
    
      *pWrDat: p->write data 写数据指针
    
      num: number  需要写入的数据个数
    
    *******************************************************/
    
    bool I2C_Write(UCHAR wrDAdr,UCHAR wordAdr,UCHAR *pWrDat,UCHAR num)
    
    {
    
    bool I2CAck;
    
    unsigned char i;
    
    
    I2C_Start();      /*启动I2C*/
    
    _delay_5us(5);
    
    I2CAck = SendByte(wrDAdr); /*发写器件地址*/
    
    if(!I2CAck)
    
      {
    
       return I2C_ERR;
    
      }
    
    I2CAck = SendByte(wordAdr);  /*发要写的寄存器地址*/
    
    if(!I2CAck)
    
      {
    
       return I2C_ERR;
    
      }
    
    for(i=0;i<num-1;i++)
    
      {
    
      I2CAck = SendByte(*(pWrDat+i));
    
      if(!I2CAck)
    
       {return I2C_ERR;}
    
      }
    
    if(i==num-1)
    
      {
    
      I2CAck = SendByte(*(pWrDat+num-1));
    
      if(!I2CAck)
    
       {return I2C_ERR;}
    
      }
    
    I2C_Stop();
    
    return I2CAck;
    
    } 

    以上代码不知为何读出数据不正确,用示波器看我发送的器件地址,寄存器地址这些都对,器件输出的数据是0xFF,程序中读出返回的数据是0x00,弄了一天没对相当郁闷,同志们指点下



    终于搞定了, 应该跟我的器件有关,另外if(GPIO_ReadInputPin(I2C_PORT,I2CSDA) == 1)这种不能写成==1,要直接写成if(GPIO_ReadInputPin(I2C_PORT,I2CSDA)),太郁闷了


  • 相关阅读:
    python基础学习1-函数相关
    python基础学习1-SET 集合
    Linux命令学习笔记1
    python基础学习1-字典的使用
    python基础学习1-列表使用
    Jzoj4743 积木
    Jzoj4786 小a的强迫症
    Jzoj4746 树塔狂想曲
    Jzoj5246 Trip
    Jzoj5245 Competing Souls
  • 原文地址:https://www.cnblogs.com/yuzaipiaofei/p/4124350.html
Copyright © 2020-2023  润新知