你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

求一个STM32L0xx系列硬件I2C2范例代码

[复制链接]
ctang 提问时间:2017-6-8 16:36 /
所用芯片是STM32L071RZ,硬件I2C2,非I2C1、I2C3。SCL用的是PB10,SDA用的是PB11.

刚接触固件编程,不熟悉。求一个STM32L0xx系列硬件I2C2范例代码。可发至邮箱tclxspy@163.com.


非常感谢!


下面是主要代码,总感觉I2C时钟配置有问题。

main.c
  1. #include "main.h"

  2. /** @addtogroup STM32L0xx_HAL_Examples
  3.   * @{
  4.   */

  5. /** @addtogroup I2C_TwoBoards_AdvComIT
  6.   * @{
  7.   */

  8. /* Private typedef -----------------------------------------------------------*/
  9. /* Private define ------------------------------------------------------------*/
  10. /* Uncomment this line to use the board as master, if not it is used as slave */
  11. #define MASTER_BOARD
  12. #define I2C_ADDRESS        0xA0
  13. #define MASTER_REQ_READ    0xA0
  14. #define MASTER_REQ_WRITE   0xA0

  15. /* I2C TIMING Register define when I2C clock source is SYSCLK */
  16. /* I2C TIMING is calculated in case of the I2C Clock source is the SYSCLK = 32 MHz */
  17. //#define I2C_TIMING    0x10A13E56 /* 100 kHz with analog Filter ON, Rise Time 400ns, Fall Time 100ns */
  18. #define I2C_TIMING      0x00B1112E /* 400 kHz with analog Filter ON, Rise Time 250ns, Fall Time 100ns */     

  19. /* Private macro -------------------------------------------------------------*/
  20. /* Private variables ---------------------------------------------------------*/
  21. /* I2C handler declaration */
  22. I2C_HandleTypeDef I2cHandle;


  23. /* Buffer used for transmission */
  24. //uint8_t aTxBuffer[] = {0x33, 0x34};
  25. uint8_t aTxBuffer[] = {0x46, 0x54};//{"FT"}

  26. /* Buffer used for reception */
  27. uint8_t aRxBuffer[RXBUFFERSIZE];
  28. __IO uint16_t hTxNumData = 0;
  29. __IO uint16_t hRxNumData = 0;
  30. uint8_t bTransferRequest = 0;

  31. /* Private function prototypes -----------------------------------------------*/
  32. void SystemClock_Config(void);
  33. static uint16_t Buffercmp(uint8_t *pBuffer1, uint8_t *pBuffer2, uint16_t BufferLength);
  34. static void Flush_Buffer(uint8_t* pBuffer, uint16_t BufferLength);
  35. static void Error_Handler(void);

  36. /* Private functions ---------------------------------------------------------*/

  37. /**
  38.   * @brief  Main program
  39.   * @param  None
  40.   * @retval None
  41.   */
  42. int main(void)
  43. {
  44.   /* STM32L0xx HAL library initialization:
  45.        - Configure the Flash prefetch, Flash preread and Buffer caches
  46.        - Systick timer is configured by default as source of time base, but user
  47.              can eventually implement his proper time base source (a general purpose
  48.              timer for example or other time source), keeping in mind that Time base
  49.              duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
  50.              handled in milliseconds basis.
  51.        - Low Level Initialization
  52.      */
  53.   HAL_Init();
  54.   
  55.   /* Configure the system clock to 32 MHz */
  56.   SystemClock_Config();

  57.   /* Configure LED2 */
  58.   //BSP_LED_Init(LED2);

  59.   /*##-1- Configure the I2C peripheral ######################################*/
  60.   I2cHandle.Instance             = I2Cx;
  61.   I2cHandle.Init.Timing          = I2C_TIMING;
  62.   I2cHandle.Init.OwnAddress1     = I2C_ADDRESS;
  63.   I2cHandle.Init.AddressingMode  = I2C_ADDRESSINGMODE_7BIT;
  64.   I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  65.   I2cHandle.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  66.   I2cHandle.Init.OwnAddress2     = 0xFF;
  67.   I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  68.   I2cHandle.Init.NoStretchMode   = I2C_NOSTRETCH_DISABLE;  

  69.   if(HAL_I2C_Init(&I2cHandle) != HAL_OK)
  70.   {
  71.     /* Initialization Error */
  72.     Error_Handler();
  73.   }

  74.   /* Enable the Analog I2C Filter */
  75.   HAL_I2CEx_ConfigAnalogFilter(&I2cHandle,I2C_ANALOGFILTER_ENABLE);

  76. #ifdef MASTER_BOARD

  77.   /* Configure User push-button */
  78.   //BSP_PB_Init(BUTTON_KEY,BUTTON_MODE_GPIO);

  79.   /* Wait for User push-button press before starting the Communication */
  80. //  while (BSP_PB_GetState(BUTTON_KEY) != GPIO_PIN_RESET)
  81. //  {
  82. //  }

  83.   /* Wait for User push-button release before starting the Communication */
  84. //  while (BSP_PB_GetState(BUTTON_KEY) != GPIO_PIN_SET)
  85. //  {
  86. //  }

  87.   while(1)
  88.   {
  89.     /* Initialize number of data variables */
  90.     hTxNumData = TXBUFFERSIZE;
  91.     hRxNumData = RXBUFFERSIZE;

  92.     /* Update bTransferRequest to send buffer write request for Slave */
  93.     bTransferRequest = MASTER_REQ_WRITE;

  94.     /*##-2- Master sends write request for slave #############################*/
  95.      /*##-3- Master sends number of data to be written ########################*/
  96.     do
  97.     {
  98.       if(HAL_I2C_Mem_Write_IT(&I2cHandle, (uint16_t)I2C_ADDRESS, 0xA8, I2C_MEMADD_SIZE_8BIT, (uint8_t*)&aTxBuffer, TXBUFFERSIZE)!= HAL_OK)
  99.       {
  100.         /* Error_Handler() function is called when error occurs. */
  101.         Error_Handler();
  102.       }

  103.       /*  Before starting a new communication transfer, you need to check the current   
  104.           state of the peripheral; if it抯 busy you need to wait for the end of current
  105.           transfer before starting a new one.
  106.           For simplicity reasons, this example is just waiting till the end of the
  107.           transfer, but application may perform other tasks while transfer operation
  108.           is ongoing. */  
  109.       while (HAL_I2C_GetState(&I2cHandle) != HAL_I2C_STATE_READY)
  110.       {
  111.       }

  112.       /* When Acknowledge failure occurs (Slave don't acknowledge it's address)
  113.          Master restarts communication */
  114.     }
  115.     while(HAL_I2C_GetError(&I2cHandle) == HAL_I2C_ERROR_AF);

  116.     HAL_Delay(100);
  117.    
  118.     /*##-7- Master receives aRxBuffer from slave #############################*/
  119.     do
  120.     {
  121.       if(HAL_I2C_Mem_Read_IT(&I2cHandle, (uint16_t)I2C_ADDRESS, 0xA8, I2C_MEMADD_SIZE_8BIT, (uint8_t*)aRxBuffer, RXBUFFERSIZE)!= HAL_OK)
  122.       {
  123.         /* Error_Handler() function is called when error occurs. */
  124.         Error_Handler();
  125.       }

  126.       /*  Before starting a new communication transfer, you need to check the current   
  127.           state of the peripheral; if it抯 busy you need to wait for the end of current
  128.           transfer before starting a new one.
  129.           For simplicity reasons, this example is just waiting till the end of the
  130.           transfer, but application may perform other tasks while transfer operation
  131.           is ongoing. */  
  132.       while (HAL_I2C_GetState(&I2cHandle) != HAL_I2C_STATE_READY)
  133.       {
  134.       }

  135.       /* When Acknowledge failure occurs (Slave don't acknowledge it's address)
  136.          Master restarts communication */
  137.     }
  138.     while(HAL_I2C_GetError(&I2cHandle) == HAL_I2C_ERROR_AF);

  139.     /* Check correctness of received buffer ##################################*/
  140.     if(Buffercmp((uint8_t*)aTxBuffer,(uint8_t*)aRxBuffer,hRxNumData))
  141.     {
  142.       /* Processing Error */
  143.       Error_Handler();
  144.     }

  145.     /* Flush Rx buffers */
  146.     Flush_Buffer((uint8_t*)aRxBuffer,RXBUFFERSIZE);

  147.     /* Toggle LED2 */
  148.     //BSP_LED_Toggle(LED2);

  149.     /* This delay permits to see LED2 toggling */
  150.     HAL_Delay(25);
  151.   }
  152. #else
  153.   while(1)
  154.   {   
  155.   }
  156. #endif /* MASTER_BOARD */
  157. }

  158. /**
  159.   * @brief  System Clock Configuration
  160.   *         The system Clock is configured as follow :
  161.   *            System Clock source            = PLL (HSI)
  162.   *            SYSCLK(Hz)                     = 32000000
  163.   *            HCLK(Hz)                       = 32000000
  164.   *            AHB Prescaler                  = 1
  165.   *            APB1 Prescaler                 = 1
  166.   *            APB2 Prescaler                 = 1
  167.   *            Flash Latency(WS)              = 1
  168.   *            Main regulator output voltage  = Scale1 mode
  169.   * @retval None
  170.   */
  171. void SystemClock_Config(void)
  172. {
  173.   RCC_ClkInitTypeDef RCC_ClkInitStruct ={0};
  174.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  175.   
  176.   /* Enable Power Control clock */
  177.   __HAL_RCC_PWR_CLK_ENABLE();
  178.   
  179.   /* The voltage scaling allows optimizing the power consumption when the device is
  180.      clocked below the maximum system frequency, to update the voltage scaling value
  181.      regarding system frequency refer to product datasheet.  */
  182.   __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  183.   
  184.   /* Disable Power Control clock */
  185.   __HAL_RCC_PWR_CLK_DISABLE();
  186.   
  187.   /* Enable HSE Oscillator */
  188.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  189.   RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  190.   RCC_OscInitStruct.PLL.PLLSource   = RCC_PLLSOURCE_HSI;
  191.   RCC_OscInitStruct.PLL.PLLState    = RCC_PLL_ON;
  192.   RCC_OscInitStruct.PLL.PLLMUL      = RCC_PLL_MUL4;
  193.   RCC_OscInitStruct.PLL.PLLDIV      = RCC_PLL_DIV2;
  194.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct)!= HAL_OK)
  195.   {
  196.     /* Initialization Error */
  197.     while(1);
  198.   }
  199.   
  200.   /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
  201.      clocks dividers */
  202.   RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
  203.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  204.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  205.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;  
  206.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;  
  207.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1)!= HAL_OK)
  208.   {
  209.     /* Initialization Error */
  210.     while(1);
  211.   }
  212. }

  213. /**
  214.   * @brief  I2C error callbacks.
  215.   * @param  I2cHandle: I2C handle
  216.   * @note   This example shows a simple way to report transfer error, and you can
  217.   *         add your own implementation.
  218.   * @retval None
  219.   */
  220. void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *I2cHandle)
  221. {
  222.   /** Error_Handler() function is called when error occurs.
  223.     * 1- When Slave don't acknowledge it's address, Master restarts communication.
  224.     * 2- When Master don't acknowledge the last data transferred, Slave don't care in this example.
  225.     */
  226.   if (HAL_I2C_GetError(I2cHandle) != HAL_I2C_ERROR_AF)
  227.   {
  228.     Error_Handler();
  229.   }
  230. }

  231. /**
  232.   * @brief  This function is executed in case of error occurrence.
  233.   * @param  None
  234.   * @retval None
  235.   */
  236. static void Error_Handler(void)
  237. {
  238.   /* Error if LED2 is slowly blinking (1 sec. period) */
  239.   while(1)
  240.   {
  241.     //BSP_LED_Toggle(LED2);
  242.     HAL_Delay(1000);
  243.   }
  244. }

  245. /**
  246.   * @brief  Compares two buffers.
  247.   * @param  pBuffer1, pBuffer2: buffers to be compared.
  248.   * @param  BufferLength: buffer's length
  249.   * @retval 0  : pBuffer1 identical to pBuffer2
  250.   *         >0 : pBuffer1 differs from pBuffer2
  251.   */
  252. static uint16_t Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength)
  253. {
  254.   while (BufferLength--)
  255.   {
  256.     if ((*pBuffer1) != *pBuffer2)
  257.     {
  258.       return BufferLength;
  259.     }
  260.     pBuffer1++;
  261.     pBuffer2++;
  262.   }

  263.   return 0;
  264. }

  265. /**
  266.   * @brief  Flushes the buffer
  267.   * @param  pBuffer: buffers to be flushed.
  268.   * @param  BufferLength: buffer's length
  269.   * @retval None
  270.   */
  271. static void Flush_Buffer(uint8_t* pBuffer, uint16_t BufferLength)
  272. {
  273.   while (BufferLength--)
  274.   {
  275.     *pBuffer = 0;

  276.     pBuffer++;
  277.   }
  278. }
  279. #ifdef  USE_FULL_ASSERT

  280. /**
  281.   * @brief  Reports the name of the source file and the source line number
  282.   *         where the assert_param error has occurred.
  283.   * @param  file: pointer to the source file name
  284.   * @param  line: assert_param error line source number
  285.   * @retval None
  286.   */
  287. void assert_failed(uint8_t* file, uint32_t line)
  288. {
  289.   /* User can add his own implementation to report the file name and line number,
  290.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  291.   /* Infinite loop */
  292.   while (1)
  293.   {
  294.   }
  295. }
复制代码



main.h
  1. #ifndef __MAIN_H
  2. #define __MAIN_H

  3. /* Includes ------------------------------------------------------------------*/
  4. #include "stm32l0xx_hal.h"


  5. /* Exported types ------------------------------------------------------------*/
  6. /* Exported constants --------------------------------------------------------*/
  7. /* User can use this section to tailor I2Cx/I2Cx instance used and associated
  8.    resources */
  9. /* Definition for I2Cx clock resources */
  10. #define I2Cx                            I2C2
  11. #define RCC_PERIPHCLK_I2Cx              RCC_PERIPHCLK_I2C2
  12. //#define RCC_I2CxCLKSOURCE_SYSCLK        RCC_I2C1CLKSOURCE_SYSCLK
  13. #define I2Cx_CLK_ENABLE()               __HAL_RCC_I2C2_CLK_ENABLE()
  14. #define I2Cx_SDA_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOB_CLK_ENABLE()
  15. #define I2Cx_SCL_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOB_CLK_ENABLE()

  16. #define I2Cx_FORCE_RESET()              __HAL_RCC_I2C2_FORCE_RESET()
  17. #define I2Cx_RELEASE_RESET()            __HAL_RCC_I2C2_RELEASE_RESET()

  18. /* Definition for I2Cx Pins */
  19. #define I2Cx_SCL_PIN                    GPIO_PIN_10
  20. #define I2Cx_SCL_GPIO_PORT              GPIOB
  21. #define I2Cx_SDA_PIN                    GPIO_PIN_11
  22. #define I2Cx_SDA_GPIO_PORT              GPIOB
  23. #define I2Cx_SCL_SDA_AF                 GPIO_AF5_I2C2

  24. /* Definition for I2Cx's NVIC */
  25. #define I2Cx_IRQn                       I2C2_IRQn
  26. #define I2Cx_IRQHandler                 I2C2_IRQHandler

  27. /* Size of Transmission buffer */
  28. #define TXBUFFERSIZE                    COUNTOF(aTxBuffer)
  29. /* Size of Reception buffer */
  30. #define RXBUFFERSIZE                    TXBUFFERSIZE

  31. /* Exported macro ------------------------------------------------------------*/
  32. #define COUNTOF(__BUFFER__)   (sizeof(__BUFFER__) / sizeof(*(__BUFFER__)))
  33. /* Exported functions ------------------------------------------------------- */

  34. #endif /* __MAIN_H */
复制代码
stm32l0xx_hal_msp.c
  1. #include "main.h"

  2. /** @addtogroup STM32L0xx_HAL_Examples
  3.   * @{
  4.   */

  5. /** @defgroup HAL_MSP
  6.   * @brief HAL MSP module.
  7.   * @{
  8.   */

  9. /* Private typedef -----------------------------------------------------------*/
  10. /* Private define ------------------------------------------------------------*/
  11. /* Private macro -------------------------------------------------------------*/
  12. /* Private variables ---------------------------------------------------------*/
  13. /* Private function prototypes -----------------------------------------------*/
  14. /* Private functions ---------------------------------------------------------*/

  15. /** @defgroup HAL_MSP_Private_Functions
  16.   * @{
  17.   */

  18. /**
  19.   * @brief I2C MSP Initialization
  20.   *        This function configures the hardware resources used in this example:
  21.   *           - Peripheral's clock enable
  22.   *           - Peripheral's GPIO Configuration  
  23.   *           - DMA configuration for transmission request by peripheral
  24.   *           - NVIC configuration for DMA interrupt request enable
  25.   * @param hi2c: I2C handle pointer
  26.   * @retval None
  27.   */
  28. void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c)
  29. {
  30.   GPIO_InitTypeDef  GPIO_InitStruct;
  31.   RCC_PeriphCLKInitTypeDef  RCC_PeriphCLKInitStruct;
  32.   
  33.   /*##-1- Configure the I2C clock source. The clock is derived from the SYSCLK #*/
  34.   RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2Cx;
  35.   //RCC_PeriphCLKInitStruct.I2c1ClockSelection = RCC_I2CxCLKSOURCE_SYSCLK;
  36.   HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct);

  37.   /*##-2- Enable peripherals and GPIO Clocks #################################*/
  38.   /* Enable GPIO TX/RX clock */
  39.   I2Cx_SCL_GPIO_CLK_ENABLE();
  40.   I2Cx_SDA_GPIO_CLK_ENABLE();
  41.   /* Enable I2Cx clock */
  42.   I2Cx_CLK_ENABLE();

  43.   /*##-3- Configure peripheral GPIO ##########################################*/  
  44.   /* I2C TX GPIO pin configuration  */
  45.   GPIO_InitStruct.Pin       = I2Cx_SCL_PIN;
  46.   GPIO_InitStruct.Mode      = GPIO_MODE_AF_OD;
  47.   GPIO_InitStruct.Pull      = GPIO_PULLUP;
  48.   GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
  49.   GPIO_InitStruct.Alternate = I2Cx_SCL_SDA_AF;
  50.   HAL_GPIO_Init(I2Cx_SCL_GPIO_PORT, &GPIO_InitStruct);
  51.    
  52.   /* I2C RX GPIO pin configuration  */
  53.   GPIO_InitStruct.Pin       = I2Cx_SDA_PIN;
  54.   GPIO_InitStruct.Alternate = I2Cx_SCL_SDA_AF;
  55.   HAL_GPIO_Init(I2Cx_SDA_GPIO_PORT, &GPIO_InitStruct);
  56.    
  57.   /*##-4- Configure the NVIC for I2C ########################################*/   
  58.   /* NVIC for I2Cx */
  59.   HAL_NVIC_SetPriority(I2Cx_IRQn, 0, 1);
  60.   HAL_NVIC_EnableIRQ(I2Cx_IRQn);
  61. }

  62. /**
  63.   * @brief I2C MSP De-Initialization
  64.   *        This function frees the hardware resources used in this example:
  65.   *          - Disable the Peripheral's clock
  66.   *          - Revert GPIO, DMA and NVIC configuration to their default state
  67.   * @param hi2c: I2C handle pointer
  68.   * @retval None
  69.   */
  70. void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c)
  71. {
  72.   
  73.   /*##-1- Reset peripherals ##################################################*/
  74.   I2Cx_FORCE_RESET();
  75.   I2Cx_RELEASE_RESET();

  76.   /*##-2- Disable peripherals and GPIO Clocks #################################*/
  77.   /* Configure I2C Tx as alternate function  */
  78.   HAL_GPIO_DeInit(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_PIN);
  79.   /* Configure I2C Rx as alternate function  */
  80.   HAL_GPIO_DeInit(I2Cx_SDA_GPIO_PORT, I2Cx_SDA_PIN);
  81.   
  82.   /*##-3- Disable the NVIC for I2C ##########################################*/
  83.   HAL_NVIC_DisableIRQ(I2Cx_IRQn);
  84. }
复制代码


收藏 评论6 发布时间:2017-6-8 16:36

举报

6个回答
队长shiwo 回答时间:2017-6-27 14:44:35
IIC就使用口线模拟就好了,为啥一定要硬件的呢,模拟的也很好用了
ataudio 回答时间:2017-6-27 16:50:35
据说模拟更不容易出问题。
epochal 回答时间:2017-6-27 18:32:52
模拟IIC简单可靠!
samhong 回答时间:2017-8-3 16:17:12
模拟简单可靠,更灵活使用,用后你就爱用模拟!
废鱼 回答时间:2017-8-3 16:19:32
直接用HAL库。
ctang 回答时间:2017-8-11 10:22:41
解决了。是这行有问题:#define I2Cx_SCL_SDA_AF                 GPIO_AF5_I2C2
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版