<output id="lr9jh"></output>
<big id="lr9jh"><delect id="lr9jh"><del id="lr9jh"></del></delect></big>

      <output id="lr9jh"><delect id="lr9jh"><address id="lr9jh"></address></delect></output>
      <var id="lr9jh"><dl id="lr9jh"></dl></var>

            <output id="lr9jh"><listing id="lr9jh"><address id="lr9jh"></address></listing></output>
            <big id="lr9jh"></big>

                <output id="lr9jh"><delect id="lr9jh"></delect></output>

                  <video id="lr9jh"></video>
                  您好,歡迎訪問上海意泓電子科技有限責任公司網站!
                  4新聞資訊
                  您的位置: 首頁 ->  新聞資訊 -> 單片機

                  ?STM32模擬I2C程序

                  文章出處:單片機 責任編輯:上海意泓電子科技有限責任公司 發表時間:
                  2018
                  05-20

                  /*******************************************************************************

                    測試平臺:STM32F103ZET6最小系統

                  *******************************************************************************/

                  static void i2cDelay()

                  {

                      volatile int i = 7;

                      while (i)

                      i--;

                  }


                  // SCL高電平期間,SDA出現下降沿為起始信號

                  static bool i2cStart()

                  {

                      SDA_OUT;

                      SCL_H;

                      SDA_H;

                      i2cDelay();

                      if (!sdaRead)  // 如果SDA為低電平,則總線忙,退出

                          return false;

                      SDA_L;

                      if (sdaRead)  // 如果SDA為高電平,則總線忙,退出

                          return false;

                      SDA_L;

                      return true;

                  }


                  // SCL高電平期間,SDA出現上升沿為停止信號

                  static void i2cStop(void)

                  {

                      SDA_OUT;

                      SCL_L; 

                      SDA_L;

                      i2cDelay();  // STOP:when CLK is high DATA from low to high 

                      SCL_H;

                      SDA_H;  

                      i2cDelay();

                  }


                  static void i2cAck(void)

                  {

                      SDA_OUT;

                      SCL_L;

                      i2cDelay();

                      SDA_L;

                      i2cDelay();

                      SCL_H;

                      i2cDelay();

                      SCL_L;

                  }


                  static void i2cNoAck(void)

                  {

                      SDA_OUT;

                      SCL_L;

                      i2cDelay();

                      SDA_H;

                      i2cDelay();

                      SCL_H;

                      i2cDelay();

                      SCL_L;

                  }


                  // SCL高電平期間,SDA電平被從設備拉低表示應答

                  static bool i2cWaitAck(void)

                  {

                      uint8_t errTimes = 0;


                      SDA_IN;

                      SDA_H;

                      i2cDelay();

                      SCL_H;

                      i2cDelay();

                      while (sdaRead) {

                          if (errTimes++ > 20) {

                              SCL_L;

                              return false;

                          }           

                          i2cDelay();

                      }

                      SCL_L;

                      return true;

                  }


                  // 發送數據,數據從高位到低位傳輸  

                  static void i2cSendByte(uint8_t byte)  

                  {

                      uint8_t i = 8;


                      SDA_OUT;

                      while (i--) {      

                          SCL_L;  // 時鐘信號為低電平期間,允許數據線電平變化

                          i2cDelay();

                          if (byte & 0x80)

                              SDA_H;

                          else

                              SDA_L; 

                          byte <<= 1; 

                          i2cDelay();

                          SCL_H;

                          i2cDelay();

                      }

                      SCL_L;

                  }


                  static uint8_t i2cReceiveByte()  

                  {

                      uint8_t i = 8;

                      uint8_t byte = 0;


                      SDA_IN;

                      SDA_H;

                      while (i--) {

                          byte <<= 1;

                          SCL_H;

                          i2cDelay();

                          if (sdaRead) {

                              byte |= 0x01;

                          }

                          SCL_L;

                          i2cDelay();

                      }

                      SCL_L;

                      return byte; 

                  }



                  void i2cInit()

                  {

                      GPIO_InitTypeDef GPIO_InitStructure;


                      /* Enable GPIOB clock */

                      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);


                      /* Configure GPIOB.6 & GPIOB.7 as open-drain output */

                      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;

                      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

                      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;


                      GPIO_Init(GPIOB, &GPIO_InitStructure);

                  }


                  /**

                   * 通過I2C總線寫一字節數據

                   * @param[in] dev:設備I2C地址

                   * @param[in] reg:寄存器地址

                   * @param[in] data:要寫入的數據

                   */

                  bool i2cWriteOneByte(uint8_t dev, uint8_t reg, uint8_t data)

                  {

                      if (!i2cStart())        

                          return false;

                      i2cSendByte(dev << 1);  // 從機地址由高7位+讀寫位構成   

                      if (!i2cWaitAck()) {     

                          i2cStop();

                          return false;

                      }

                      i2cSendByte(reg);       

                      i2cWaitAck();

                      i2cSendByte(data);     

                      i2cWaitAck();

                      return true;

                  }


                  /**

                   *  

                   * @param[in] dev:設備I2C地址

                   * @param[in] reg:寄存器地址

                   * @param[in] len:字節數 

                   * @param[in] data:待寫入的數據 

                   */

                  bool i2cWriteBytes(uint8_t dev, uint8_t reg, uint8_t len, uint8_t *data)

                  {

                      uint8_t i;


                      if (!i2cStart())        

                          return false;

                      i2cSendByte(dev << 1);          

                      if (!i2cWaitAck()) {     

                          i2cStop();

                          return false;

                      }

                      i2cSendByte(dev);   

                      i2cWaitAck();

                      for (i = 0; i < len; i++) {

                          i2cSendByte(data[i]);

                          if (!i2cWaitAck()) {

                              i2cStop();

                              return false;

                          }

                      }

                      i2cStop();

                      return true;

                  }



                  /**

                   * 從I2C設備中讀取數據

                   * @param[in] dev:設備I2C地址

                   * @param[in] reg:寄存器地址

                   * @param[in] len:數據字節數

                   * @param[out] data:讀出的數據

                   */

                  bool i2cReadBytes(uint8_t dev, uint8_t reg, uint8_t len, uint8_t *data)

                  {

                      if (!i2cStart())        

                          return false;

                      i2cSendByte(dev << 1);      

                      if (!i2cWaitAck()) {     

                          i2cStop();

                          return false;

                      }

                      i2cSendByte(reg);     

                      i2cWaitAck();

                      i2cStart();           

                      i2cSendByte((dev << 1) | 0x01);  // 器件地址+讀命令    

                      i2cWaitAck();

                      while (len) {

                          *data = i2cReceiveByte();

                          if (len == 1)

                              i2cNoAck();  // 最后一個字節不應答

                          else

                              i2cAck();

                          data++;

                          len--;

                      }

                      i2cStop();

                      return true;

                  }


                  上海意泓電子科技有限責任公司 版權所有 未經授權禁止復制或鏡像

                  CopyRight 2020-2025 www.pj7112.com All rights reserved   滬ICP備2021005866號

                  大量国产情侣作爱视频