Summary of i2c usage of stm32f3

Publisher:BeaLaity0170Latest update time:2019-04-02 Source: eefocusKeywords:stm32f3  i2c Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

I got the stm32f3discovery these days. The first thing I did was to test the hardware i2c, using stm32cube to generate the library, and the test objects were AD5934 and ADG715. After two days of debugging, it was perfectly tuned. I also encountered some problems in the middle.


1. I2C1 was used at the beginning, and the system would freeze during simulation.

        Since I2C1 and swd interfaces overlap, the system crashes after calling the HAL_I2C_Init() function. The problem is solved after changing to I2C2.

2. Unable to access the device at the specified address

        The entry address in the library function is not a 7-bit address, but an 8-bit address. My device address was 13, but I could not access the device. I changed it to 26 and it solved the problem.

3. Data of a single address can be read and written, but multi-byte reading and writing is not possible.

       (1) For multi-byte writes, the library function

        HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)

       MemAddSize indicates the number of bits in the address, 0 indicates a 7-bit address, and 1 indicates a 10-bit address. I mistakenly thought this was the number of bytes to be written, so it caused an error when writing multiple bytes.

       (2) For multi-byte read, there is a discrepancy between the read operation of AD5934 and the read operation of the library function, which results in a constant read error. In the library function, the read operation starts after the memory address is written, while in AD5934, after the block read is completed, a number bytes read is written before the read operation starts. Therefore, the library function needs to be modified and a new function needs to be added to suit the block read of AD5934.



        The i2c of stm32f3 has three modes: Reload, AutoEnd and SoftEnd mode.


        Each time i2c sends a byte, it will generate a TXIS flag. When the last byte is sent:


        For the Reload mode, when the bytes are greater than 255 bytes, this mode must be used. In this mode, a tcr flag will be generated after the transmission is completed.


        For AutoEnd mode, a STOP is automatically generated after the last byte is sent.


        For SoftEnd mode, a tc flag is generated when the last byte is sent. This mode is used when a restart is required during the sending process.


        For the read operation of AD5934, you can work in SoftEnd mode in advance, send block read and number bytes read, and then switch to AutoEnd mode for Restart. After reading the specified bytes, STOP is automatically generated. The operation process is as follows:


HAL_StatusTypeDef HAL_I2C_Mem_Read_AD5934_Block(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)

{

  uint32_t Sizetmp = 0;


  /* Check the parameters  http://tiyubisai.com/video_news/news_135585.html */

  assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));

  

  if(hi2c->State == HAL_I2C_STATE_READY)

  {    

    if((pData == NULL) || (Size == 0)) 

    {

      return  HAL_ERROR;                                    

    }


    if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)

    {

      return HAL_BUSY;

    }


    /* Process Locked */

    __HAL_LOCK(hi2c);

    

    hi2c->State = HAL_I2C_STATE_MEM_BUSY_RX;

    hi2c->ErrorCode = HAL_I2C_ERROR_NONE;

    /*

    //Send Slave Address and Memory Address 

    if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, Timeout) != HAL_OK)

    {

      if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)

      {

        // Process Unlocked 

        __HAL_UNLOCK(hi2c);

        return HAL_ERROR;

      }

      else

      {

        // Process Unlocked 

        __HAL_UNLOCK(hi2c);

        return HAL_TIMEOUT;

      }

    }*/

    

    I2C_TransferConfig(hi2c,DevAddress,MemAddSize+1, I2C_SOFTEND_MODE, I2C_GENERATE_START_WRITE);

      

    /* Wait until TXIS flag is set */

    if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout) != HAL_OK)

    {

      if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)

      {

        return HAL_ERROR;

      }

      else

      {

        return HAL_TIMEOUT;

      }

    }

    

    /* If Memory address size is 8Bit */

    if(MemAddSize == I2C_MEMADD_SIZE_8BIT)

    {

      /* Send Memory Address */

      hi2c->Instance->TXDR = __HAL_I2C_MEM_ADD_LSB(MemAddress);    

    }      

    /* If Mememory address size is 16Bit */

    else

    {

      /* Send MSB of Memory Address */

      hi2c->Instance->TXDR = __HAL_I2C_MEM_ADD_MSB(MemAddress); 

      

      /* Wait until TXIS flag is set */

      if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout) != HAL_OK)

      {

        if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)

        {

          return HAL_ERROR;

        }

        else

        {

          return HAL_TIMEOUT;

        }

      }

      

      /* Send LSB of Memory Address */

      hi2c->Instance->TXDR = __HAL_I2C_MEM_ADD_LSB(MemAddress);  

    }

   

    /* Wait until TXIS flag is set */

    if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout) != HAL_OK)

    {

      if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)

      {

        return HAL_ERROR;

      }

      else

      {

        return HAL_TIMEOUT;

      }

    }

    

    hi2c->Instance->TXDR = Size; 

    

    /* Wait until TC flag is set */

    if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TC, RESET, Timeout) != HAL_OK)      

    {

      return HAL_TIMEOUT;

    }    

    

    /* Send Slave Address */

    /* Set NBYTES to write and reload if size > 255 and generate RESTART */

    /* Size > 255, need to set RELOAD bit */

    if(Size > 255)

    {

      I2C_TransferConfig(hi2c,DevAddress,255, I2C_RELOAD_MODE, I2C_GENERATE_START_READ);

      Sizetmp = 255;

    }

    else

    {

      I2C_TransferConfig(hi2c,DevAddress,Size, I2C_AUTOEND_MODE, I2C_GENERATE_START_READ);

      Sizetmp = Size;

    }

    

    do

    {  

      /* Wait until RXNE flag is set */

      if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_RXNE, RESET, Timeout) != HAL_OK)      

      {

        return HAL_TIMEOUT;

      }

          

      /* Read data from RXDR */

      (*pData++) = hi2c->Instance->RXDR;


      /* Decrement the Size counter */

      Sizetmp--;

      Size--;   


      if((Sizetmp == 0)&&(Size!=0))

      {

        /* Wait until TCR flag is set */

        if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout) != HAL_OK)      

        {

          return HAL_TIMEOUT;

        }

        

        if(Size > 255)

        {

          I2C_TransferConfig(hi2c,DevAddress,255, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);

          Sizetmp = 255;

        }

        else

        {

          I2C_TransferConfig(hi2c,DevAddress,Size, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);

          Sizetmp = Size;

        }

      }


    }while(Size > 0);


    /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */

    /* Wait until STOPF flag is reset */ 

    if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, I2C_TIMEOUT_STOPF) != HAL_OK)

    {

      if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)

      {

        return HAL_ERROR;

      }

      else

      {

        return HAL_TIMEOUT;

      }

    }


    /* Clear STOP Flag */

    __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);

    

    /* Clear Configuration Register 2 */

    __HAL_I2C_RESET_CR2(hi2c);

    

    hi2c->State = HAL_I2C_STATE_READY;

    

    /* Process Unlocked */

    __HAL_UNLOCK(hi2c);

    

    return HAL_OK;

  }

  else

  {

    return HAL_BUSY;

  }

}


Keywords:stm32f3  i2c Reference address:Summary of i2c usage of stm32f3

Previous article:STM32 drives temperature and humidity sensor HTU21D
Next article:STM32 I2C deadlock issue

Recommended ReadingLatest update time:2024-11-16 13:30

I2C bus timing simulation (I) - Deepen understanding of bus protocol
  view plain   copy     print ? #include reg52.h    #define uchar unsigned char   sbit sda=P2^0;   sbit scl=P2^1; //Use the two I/O ports of the microcontroller to simulate the I2C interface   uchar a;   *************************************************** *************************   void dela
[Microcontroller]
Design of I2C communication between ARM/DSP and other machines based on Linux operating system
introduction In many embedded control systems, the system must complete a large amount of information collection and complex algorithms, and also realize precise control functions. The ARM9 microcontroller running the embedded Linux operating system is used to complete signal collection and implement the upper-level
[Microcontroller]
Design of I2C communication between ARM/DSP and other machines based on Linux operating system
STM32 simulated I2C program
The hardware I2C of STM32 is not very easy to use, and many people are troubled by it, including me. So I just go all out and use simulated I2C. Although the speed is not as fast as hardware I2C, it is still good in general applications. I post the code and protocol analysis diagram to benefit the friends who are trou
[Microcontroller]
Application of serial I2C bus E2PROM AT24CXXX1
This article introduces the use of I2C memory. It mainly introduces the AT24CXX series devices, which are divided into two categories, mainly based on the storage capacity address. One category is AT24C02-AT24C16, and its storage capacity ranges from 256 bytes to 2048 bytes. The other category is AT24C32-AT24C1024, wit
[Microcontroller]
Application of serial I2C bus E2PROM AT24CXXX1
Records on debugging SPI, I2C, and UART
The MCU model I used recently is ASM9260. I encountered some troubles when writing related drivers. I made a note below to keep in mind. 1. On SPI, use DMA to read and write FLASH data. The phenomenon that occurs is: after erasing FLASH, the read value is 0xFF. After writing some data, the read value is inconsistent
[Microcontroller]
The microcontroller based on I2C protocol records the number of microcontroller startups
  I have talked about the I2C protocol before and also gave a simple example. This time, using the I2C protocol, we can do a small experiment to let the microcontroller record the number of times the microcontroller is turned on, that is, the number of times the machine is used.   // Content: Each time the machine is
[Microcontroller]
stm8 debugging hardware I2C experience
This time, debugging the hardware of stm8 was really hard. I didn't expect it to be so annoying! It took me 5 days to do it. I referred to many examples on the Internet and Fengchi's stm8 explanation! And my own practice, I finally figured it out! I would like to share some of my experiences in the debugging process w
[Microcontroller]
Using digital oscilloscope to debug embedded I2C bus
This article explains the I2C communication problems encountered in actual development and how to use an oscilloscope to analyze and solve the problems. The latest DS6104 oscilloscope launched by RIGOL was used in the analysis process. Its specific features include: up to 1GHz bandwidth, which is suff
[Test Measurement]
Using digital oscilloscope to debug embedded I2C bus
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号