<tfoot id="ygvxt"><menuitem id="ygvxt"></menuitem></tfoot>
    • <kbd id="ygvxt"></kbd>
      <th id="ygvxt"><progress id="ygvxt"></progress></th>

      您好,歡迎訪問上海意泓電子科技有限責(zé)任公司網(wǎng)站!
      4新聞資訊
      您的位置: 首頁 ->  新聞資訊 -> 單片機(jī)

      ?STM32模擬I2C程序

      文章出處:?jiǎn)纹瑱C(jī) 責(zé)任編輯:上海意泓電子科技有限責(zé)任公司 發(fā)表時(shí)間:
      2018
      05-20

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

        測(cè)試平臺(tái):STM32F103ZET6最小系統(tǒng)

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

      static void i2cDelay()

      {

          volatile int i = 7;

          while (i)

          i--;

      }


      // SCL高電平期間,SDA出現(xiàn)下降沿為起始信號(hào)

      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出現(xiàn)上升沿為停止信號(hào)

      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電平被從設(shè)備拉低表示應(yīng)答

      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;

      }


      // 發(fā)送數(shù)據(jù),數(shù)據(jù)從高位到低位傳輸  

      static void i2cSendByte(uint8_t byte)  

      {

          uint8_t i = 8;


          SDA_OUT;

          while (i--) {      

              SCL_L;  // 時(shí)鐘信號(hào)為低電平期間,允許數(shù)據(jù)線電平變化

              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總線寫一字節(jié)數(shù)據(jù)

       * @param[in] dev:設(shè)備I2C地址

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

       * @param[in] data:要寫入的數(shù)據(jù)

       */

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

      {

          if (!i2cStart())        

              return false;

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

          if (!i2cWaitAck()) {     

              i2cStop();

              return false;

          }

          i2cSendByte(reg);       

          i2cWaitAck();

          i2cSendByte(data);     

          i2cWaitAck();

          return true;

      }


      /**

       *  

       * @param[in] dev:設(shè)備I2C地址

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

       * @param[in] len:字節(jié)數(shù) 

       * @param[in] data:待寫入的數(shù)據(jù) 

       */

      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設(shè)備中讀取數(shù)據(jù)

       * @param[in] dev:設(shè)備I2C地址

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

       * @param[in] len:數(shù)據(jù)字節(jié)數(shù)

       * @param[out] data:讀出的數(shù)據(jù)

       */

      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();  // 最后一個(gè)字節(jié)不應(yīng)答

              else

                  i2cAck();

              data++;

              len--;

          }

          i2cStop();

          return true;

      }


      上海意泓電子科技有限責(zé)任公司 版權(quán)所有 未經(jīng)授權(quán)禁止復(fù)制或鏡像

      CopyRight 2020-2025 www.hljhgw.com All rights reserved   滬ICP備2021005866號(hào)

      国产强伦姧在线观看,…中文天堂在线一区,亚洲欧洲精品污网站在线观看,在线视频综合站
      <tfoot id="ygvxt"><menuitem id="ygvxt"></menuitem></tfoot>
        • <kbd id="ygvxt"></kbd>
          <th id="ygvxt"><progress id="ygvxt"></progress></th>