OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4639|回复: 13

求助原子哥--STM32L071RZ硬件I2C2问题

[复制链接]

2

主题

6

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2017-6-8
在线时间
5 小时
发表于 2017-6-8 18:24:03 | 显示全部楼层 |阅读模式
1金钱
原子哥您好。我买了一块F系列的mini板,示例上是用的软件模拟I2C,调通了。但公司所用芯片是STM32L071RZ,硬件I2C2,非I2C1、I2C3。SCL用的是PB10,SDA用的是PB11.

我刚接触固件编程,不熟悉。求教一个STM32L0xx系列硬件I2C2范例代码。

非常感谢!

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

main.C

[mw_shl_code=c,true]#include "main.h"

/** @addtogroup STM32L0xx_HAL_Examples
  * @{
  */

/** @addtogroup I2C_TwoBoards_AdvComIT
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Uncomment this line to use the board as master, if not it is used as slave */
#define MASTER_BOARD
#define I2C_ADDRESS        0xA0
#define MASTER_REQ_READ    0xA0
#define MASTER_REQ_WRITE   0xA0

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

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* I2C handler declaration */
I2C_HandleTypeDef I2cHandle;


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

/* Buffer used for reception */
uint8_t aRxBuffer[RXBUFFERSIZE];
__IO uint16_t hTxNumData = 0;
__IO uint16_t hRxNumData = 0;
uint8_t bTransferRequest = 0;

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static uint16_t Buffercmp(uint8_t *pBuffer1, uint8_t *pBuffer2, uint16_t BufferLength);
static void Flush_Buffer(uint8_t* pBuffer, uint16_t BufferLength);
static void Error_Handler(void);

/* Private functions ---------------------------------------------------------*/

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

  /* Configure LED2 */
  //BSP_LED_Init(LED2);

  /*##-1- Configure the I2C peripheral ######################################*/
  I2cHandle.Instance             = I2Cx;
  I2cHandle.Init.Timing          = I2C_TIMING;
  I2cHandle.Init.OwnAddress1     = I2C_ADDRESS;
  I2cHandle.Init.AddressingMode  = I2C_ADDRESSINGMODE_7BIT;
  I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  I2cHandle.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  I2cHandle.Init.OwnAddress2     = 0xFF;
  I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  I2cHandle.Init.NoStretchMode   = I2C_NOSTRETCH_DISABLE;  

  if(HAL_I2C_Init(&I2cHandle) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }

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

#ifdef MASTER_BOARD

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

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

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

  while(1)
  {
    /* Initialize number of data variables */
    hTxNumData = TXBUFFERSIZE;
    hRxNumData = RXBUFFERSIZE;

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

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

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

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

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

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

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

    /* Check correctness of received buffer ##################################*/
    if(Buffercmp((uint8_t*)aTxBuffer,(uint8_t*)aRxBuffer,hRxNumData))
    {
      /* Processing Error */
      Error_Handler();
    }

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

    /* Toggle LED2 */
    //BSP_LED_Toggle(LED2);

    /* This delay permits to see LED2 toggling */
    HAL_Delay(25);
  }
#else
  while(1)
  {   
  }
#endif /* MASTER_BOARD */
}

/**
  * @brief  System Clock Configuration
  *         The system Clock is configured as follow :
  *            System Clock source            = PLL (HSI)
  *            SYSCLK(Hz)                     = 32000000
  *            HCLK(Hz)                       = 32000000
  *            AHB Prescaler                  = 1
  *            APB1 Prescaler                 = 1
  *            APB2 Prescaler                 = 1
  *            Flash Latency(WS)              = 1
  *            Main regulator output voltage  = Scale1 mode
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_ClkInitTypeDef RCC_ClkInitStruct ={0};
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  
  /* Enable Power Control clock */
  __HAL_RCC_PWR_CLK_ENABLE();
  
  /* The voltage scaling allows optimizing the power consumption when the device is
     clocked below the maximum system frequency, to update the voltage scaling value
     regarding system frequency refer to product datasheet.  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  
  /* Disable Power Control clock */
  __HAL_RCC_PWR_CLK_DISABLE();
  
  /* Enable HSE Oscillator */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLSource   = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLState    = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLMUL      = RCC_PLL_MUL4;
  RCC_OscInitStruct.PLL.PLLDIV      = RCC_PLL_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct)!= HAL_OK)
  {
    /* Initialization Error */
    while(1);
  }
  
  /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
     clocks dividers */
  RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;  
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;  
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1)!= HAL_OK)
  {
    /* Initialization Error */
    while(1);
  }
}

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

/**
  * @brief  This function is executed in case of error occurrence.
  * @param  None
  * @retval None
  */
static void Error_Handler(void)
{
  /* Error if LED2 is slowly blinking (1 sec. period) */
  while(1)
  {
    //BSP_LED_Toggle(LED2);
    HAL_Delay(1000);
  }
}

/**
  * @brief  Compares two buffers.
  * @param  pBuffer1, pBuffer2: buffers to be compared.
  * @param  BufferLength: buffer's length
  * @retval 0  : pBuffer1 identical to pBuffer2
  *         >0 : pBuffer1 differs from pBuffer2
  */
static uint16_t Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength)
{
  while (BufferLength--)
  {
    if ((*pBuffer1) != *pBuffer2)
    {
      return BufferLength;
    }
    pBuffer1++;
    pBuffer2++;
  }

  return 0;
}

/**
  * @brief  Flushes the buffer
  * @param  pBuffer: buffers to be flushed.
  * @param  BufferLength: buffer's length
  * @retval None
  */
static void Flush_Buffer(uint8_t* pBuffer, uint16_t BufferLength)
{
  while (BufferLength--)
  {
    *pBuffer = 0;

    pBuffer++;
  }
}
#ifdef  USE_FULL_ASSERT

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

  /* Infinite loop */
  while (1)
  {
  }
}[/mw_shl_code]

main.h

[mw_shl_code=c,true]#ifndef __MAIN_H
#define __MAIN_H

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


/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* User can use this section to tailor I2Cx/I2Cx instance used and associated
   resources */
/* Definition for I2Cx clock resources */
#define I2Cx                            I2C2
#define RCC_PERIPHCLK_I2Cx              RCC_PERIPHCLK_I2C2
//#define RCC_I2CxCLKSOURCE_SYSCLK        RCC_I2C1CLKSOURCE_SYSCLK
#define I2Cx_CLK_ENABLE()               __HAL_RCC_I2C2_CLK_ENABLE()
#define I2Cx_SDA_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOB_CLK_ENABLE()
#define I2Cx_SCL_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOB_CLK_ENABLE()

#define I2Cx_FORCE_RESET()              __HAL_RCC_I2C2_FORCE_RESET()
#define I2Cx_RELEASE_RESET()            __HAL_RCC_I2C2_RELEASE_RESET()

/* Definition for I2Cx Pins */
#define I2Cx_SCL_PIN                    GPIO_PIN_10
#define I2Cx_SCL_GPIO_PORT              GPIOB
#define I2Cx_SDA_PIN                    GPIO_PIN_11
#define I2Cx_SDA_GPIO_PORT              GPIOB
#define I2Cx_SCL_SDA_AF                 GPIO_AF5_I2C2

/* Definition for I2Cx's NVIC */
#define I2Cx_IRQn                       I2C2_IRQn
#define I2Cx_IRQHandler                 I2C2_IRQHandler

/* Size of Transmission buffer */
#define TXBUFFERSIZE                    COUNTOF(aTxBuffer)
/* Size of Reception buffer */
#define RXBUFFERSIZE                    TXBUFFERSIZE

/* Exported macro ------------------------------------------------------------*/
#define COUNTOF(__BUFFER__)   (sizeof(__BUFFER__) / sizeof(*(__BUFFER__)))
/* Exported functions ------------------------------------------------------- */

#endif /* __MAIN_H */[/mw_shl_code]

stm32l0xx_hal_msp.c

[mw_shl_code=c,true]#include "main.h"

/** @addtogroup STM32L0xx_HAL_Examples
  * @{
  */

/** @defgroup HAL_MSP
  * @brief HAL MSP module.
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/** @defgroup HAL_MSP_Private_Functions
  * @{
  */

/**
  * @brief I2C MSP Initialization
  *        This function configures the hardware resources used in this example:
  *           - Peripheral's clock enable
  *           - Peripheral's GPIO Configuration  
  *           - DMA configuration for transmission request by peripheral
  *           - NVIC configuration for DMA interrupt request enable
  * @param hi2c: I2C handle pointer
  * @retval None
  */
void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c)
{
  GPIO_InitTypeDef  GPIO_InitStruct;
  RCC_PeriphCLKInitTypeDef  RCC_PeriphCLKInitStruct;
  
  /*##-1- Configure the I2C clock source. The clock is derived from the SYSCLK #*/
  RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2Cx;
  //RCC_PeriphCLKInitStruct.I2c1ClockSelection = RCC_I2CxCLKSOURCE_SYSCLK;
  HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct);

  /*##-2- Enable peripherals and GPIO Clocks #################################*/
  /* Enable GPIO TX/RX clock */
  I2Cx_SCL_GPIO_CLK_ENABLE();
  I2Cx_SDA_GPIO_CLK_ENABLE();
  /* Enable I2Cx clock */
  I2Cx_CLK_ENABLE();

  /*##-3- Configure peripheral GPIO ##########################################*/  
  /* I2C TX GPIO pin configuration  */
  GPIO_InitStruct.Pin       = I2Cx_SCL_PIN;
  GPIO_InitStruct.Mode      = GPIO_MODE_AF_OD;
  GPIO_InitStruct.Pull      = GPIO_PULLUP;
  GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = I2Cx_SCL_SDA_AF;
  HAL_GPIO_Init(I2Cx_SCL_GPIO_PORT, &GPIO_InitStruct);
   
  /* I2C RX GPIO pin configuration  */
  GPIO_InitStruct.Pin       = I2Cx_SDA_PIN;
  GPIO_InitStruct.Alternate = I2Cx_SCL_SDA_AF;
  HAL_GPIO_Init(I2Cx_SDA_GPIO_PORT, &GPIO_InitStruct);
   
  /*##-4- Configure the NVIC for I2C ########################################*/   
  /* NVIC for I2Cx */
  HAL_NVIC_SetPriority(I2Cx_IRQn, 0, 1);
  HAL_NVIC_EnableIRQ(I2Cx_IRQn);
}

/**
  * @brief I2C MSP De-Initialization
  *        This function frees the hardware resources used in this example:
  *          - Disable the Peripheral's clock
  *          - Revert GPIO, DMA and NVIC configuration to their default state
  * @param hi2c: I2C handle pointer
  * @retval None
  */
void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c)
{
  
  /*##-1- Reset peripherals ##################################################*/
  I2Cx_FORCE_RESET();
  I2Cx_RELEASE_RESET();

  /*##-2- Disable peripherals and GPIO Clocks #################################*/
  /* Configure I2C Tx as alternate function  */
  HAL_GPIO_DeInit(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_PIN);
  /* Configure I2C Rx as alternate function  */
  HAL_GPIO_DeInit(I2Cx_SDA_GPIO_PORT, I2Cx_SDA_PIN);
  
  /*##-3- Disable the NVIC for I2C ##########################################*/
  HAL_NVIC_DisableIRQ(I2Cx_IRQn);
}[/mw_shl_code]


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2017-6-8 20:46:48 | 显示全部楼层
回复

使用道具 举报

2

主题

6

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2017-6-8
在线时间
5 小时
 楼主| 发表于 2017-6-9 13:13:50 | 显示全部楼层
正点原子 发表于 2017-6-8 20:46
建议别用硬件IIC了

硬件这样接了,不好改。能否帮忙看看上面代码缺少什么?

datasheet上说I2C1和I2C3用的是独立时钟,I2C2用的是PCLK。
关于这个PCLK该如何配置?
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2017-6-9 21:27:45 | 显示全部楼层
ctang 发表于 2017-6-9 13:13
硬件这样接了,不好改。能否帮忙看看上面代码缺少什么?

datasheet上说I2C1和I2C3用的是独立时钟,I2C ...

软件模拟IIC,任何两个IO都可以。
至于硬件IIC的问题,我也帮不到你
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

2

主题

6

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2017-6-8
在线时间
5 小时
 楼主| 发表于 2017-6-13 10:30:07 | 显示全部楼层
正点原子 发表于 2017-6-9 21:27
软件模拟IIC,任何两个IO都可以。
至于硬件IIC的问题,我也帮不到你

谢谢原子哥!硬件I2C2我调通了。

目前在学习usb转i2c,请教下原子哥传授下这个方面的代码或资料。谢谢!
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2017-6-14 21:15:09 | 显示全部楼层
ctang 发表于 2017-6-13 10:30
谢谢原子哥!硬件I2C2我调通了。

目前在学习usb转i2c,请教下原子哥传授下这个方面的代码或资料。谢谢 ...

我都是用模拟
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

1

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
78
金钱
78
注册时间
2016-8-30
在线时间
17 小时
发表于 2017-11-23 15:49:04 | 显示全部楼层
ctang 发表于 2017-6-13 10:30
谢谢原子哥!硬件I2C2我调通了。

目前在学习usb转i2c,请教下原子哥传授下这个方面的代码或资料。谢谢 ...

硬件I2C2怎么弄得,求指教
回复

使用道具 举报

1

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
154
金钱
154
注册时间
2017-12-14
在线时间
17 小时
发表于 2018-1-18 22:41:11 | 显示全部楼层

最近在学习硬件I2C 能指教一下吗?
回复

使用道具 举报

2

主题

685

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3448
金钱
3448
注册时间
2017-7-4
在线时间
869 小时
发表于 2018-1-19 08:41:55 | 显示全部楼层
回复

使用道具 举报

13

主题

76

帖子

0

精华

高级会员

Rank: 4

积分
539
金钱
539
注册时间
2016-4-19
在线时间
139 小时
发表于 2018-1-19 09:37:11 | 显示全部楼层
你可以把PB10,PB11配置成普通IO,然后就可以做IO口模拟I2C了
回复

使用道具 举报

15

主题

43

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
215
金钱
215
注册时间
2018-12-15
在线时间
40 小时
发表于 2019-8-10 10:29:47 | 显示全部楼层
您好,我在做毕设,用的是STM32L071RBT6, 现在在做STM32与AT24C128N的iic通讯,软件模拟我没有调通,已经几天了 我实在是没有看出哪个地方有问题。能麻烦你帮忙瞅一眼不?还有硬件iic配置代码可以发我一份么 万分感谢
这是我的软件模拟iic代码
  1. //iic.c


  2. #include "myiic.h"
  3. #include "delay.h"




  4. void IIC_Init(void)
  5. {
  6.     GPIO_InitTypeDef GPIO_Initure;
  7.        
  8.          __HAL_RCC_GPIOB_CLK_ENABLE();   
  9.    
  10.    
  11.     GPIO_Initure.Pin=GPIO_PIN_8|GPIO_PIN_9;
  12.     GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  
  13.     GPIO_Initure.Pull=GPIO_PULLUP;         
  14.     GPIO_Initure.Speed=GPIO_SPEED_FAST;   
  15.     HAL_GPIO_Init(GPIOB,&GPIO_Initure);
  16.    
  17.     IIC_SDA_1;
  18.     IIC_SCL_1;  
  19.                 printf("iic init\r\n");
  20.    
  21.         /*
  22.     __HAL_RCC_GPIOC_CLK_ENABLE();   //ʹÄÜGPIOCʱÖÓ
  23.    
  24.     //PC0,1³õʼ»¯ÉèÖÃ
  25.     GPIO_Initure.Pin=GPIO_PIN_0|GPIO_PIN_1;
  26.     GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  
  27.     GPIO_Initure.Pull=GPIO_PULLUP;         
  28.     GPIO_Initure.Speed=GPIO_SPEED_FAST;
  29.     HAL_GPIO_Init(GPIOC,&GPIO_Initure);
  30.    
  31.     IIC_SDA_1;
  32.     IIC_SCL_1;  
  33.         */
  34. }





  35. void IIC_Start(void)
  36. {
  37.         SDA_OUT();   
  38.         IIC_SDA_1;                    
  39.         IIC_SCL_1;
  40.         delay_us(4);
  41.         IIC_SDA_0;//START:when CLK is high,DATA change form high to low
  42.         delay_us(4);
  43.         IIC_SCL_0;
  44.         printf("start\r\n");
  45. }          

  46. void IIC_Stop(void)
  47. {
  48.         SDA_OUT();//sdaÏßÊä³ö
  49.         IIC_SCL_0;
  50.         IIC_SDA_0;//STOP:when CLK is high DATA change form low to high
  51.         delay_us(4);
  52.         IIC_SCL_1;
  53.         IIC_SDA_1;
  54.         delay_us(4);       
  55.         printf("stop\r\n");       
  56. }

  57. uint8_t IIC_Wait_Ack(void)
  58. {
  59.         uint16_t ucErrTime=0;
  60.         SDA_IN();     
  61.         IIC_SDA_1;delay_us(1);          
  62.         IIC_SCL_1;delay_us(1);       
  63.         while(READ_SDA)
  64.         {
  65.                 ucErrTime++;
  66.                 if(ucErrTime>500)
  67.                 {
  68.                         IIC_Stop();
  69.                         return 1;
  70.                 }
  71.         }
  72.         IIC_SCL_0;
  73.         printf("wait ack\r\n");       
  74.         return 0;  
  75.        
  76. }

  77. void IIC_Ack(void)
  78. {
  79.         IIC_SCL_0;
  80.         SDA_OUT();
  81.         IIC_SDA_0;
  82.         delay_us(2);
  83.         IIC_SCL_1;
  84.         delay_us(2);
  85.         IIC_SCL_0;
  86.         printf("ack\r\n");
  87. }
  88.             
  89. void IIC_NAck(void)
  90. {
  91.         IIC_SCL_0;
  92.         SDA_OUT();
  93.         IIC_SDA_1;
  94.         delay_us(2);
  95.         IIC_SCL_1;
  96.         delay_us(2);
  97.         IIC_SCL_0;
  98.         printf("nack\r\n");
  99. }                                                                              

  100.           
  101. void IIC_Send_Byte(uint8_t txd)
  102. {                        
  103.     uint8_t t;   
  104.           SDA_OUT();             
  105.     IIC_SCL_0;
  106.     for(t=0;t<8;t++)
  107.     {  
  108.                 //IIC_SDA=(txd&0x80)>>7;                       
  109.                         if((txd&0x80)>>7)
  110.                         {
  111.                                 IIC_SDA_1;
  112.                                 printf("1");
  113.                         }
  114.                   else
  115.                         {
  116.                                 IIC_SDA_0;
  117.                                 printf("0");                               
  118.                         }
  119.                                                        
  120.       
  121.     txd<<=1;           
  122.                 delay_us(2);
  123.                 IIC_SCL_1;
  124.                 delay_us(2);
  125.                 IIC_SCL_0;       
  126.                 delay_us(2);
  127.     }         
  128.                 printf("sendbyte\r\n");
  129. }             


  130. uint8_t IIC_Read_Byte(unsigned char ack)
  131. {
  132.         unsigned char i,receive=0;
  133.         SDA_IN();
  134.     for(i=0;i<8;i++ )
  135.         {
  136.         IIC_SCL_0;
  137.         delay_us(2);
  138.                                 IIC_SCL_1;
  139.         receive<<=1;
  140.         if(READ_SDA) receive++;                
  141.                 delay_us(1);
  142.     }                                         
  143.     if (!ack)
  144.         IIC_NAck();
  145.     else
  146.         IIC_Ack(); //·&#162;&#203;&#205;ACK
  147.                 printf("iicreadbyte receive:%d\r\n",receive);               
  148.     return receive;
  149. }





  150. //iic.h

  151. #ifndef _MYIIC_H
  152. #define _MYIIC_H
  153. #include "sys.h"



  154. #define SDA_IN()  {GPIOB->MODER&=~(3<<(9*2));GPIOH->MODER|=0<<(9*2);}       
  155. #define SDA_OUT() {GPIOB->MODER&=~(3<<(9*2));GPIOH->MODER|=1<<(9*2);}

  156. /*
  157. #define SDA_IN()  {GPIOC->MODER&=~(3<<(1*2));GPIOH->MODER|=0<<1*2;}       
  158. #define SDA_OUT() {GPIOC->MODER&=~(3<<(1*2));GPIOH->MODER|=1<<1*2;}
  159. */


  160. #define IIC_SCL_1    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET)
  161. #define IIC_SCL_0    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET)
  162. #define IIC_SDA_1    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET)
  163. #define IIC_SDA_0    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET)
  164. #define READ_SDA           HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_9)

  165. /*
  166. #define IIC_SCL_1    HAL_GPIO_WritePin(GPIOC,GPIO_PIN_0,GPIO_PIN_SET)
  167. #define IIC_SCL_0    HAL_GPIO_WritePin(GPIOC,GPIO_PIN_0,GPIO_PIN_RESET)
  168. #define IIC_SDA_1    HAL_GPIO_WritePin(GPIOC,GPIO_PIN_1,GPIO_PIN_SET)
  169. #define IIC_SDA_0    HAL_GPIO_WritePin(GPIOC,GPIO_PIN_1,GPIO_PIN_RESET)
  170. #define READ_SDA           HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_1)
  171. */

  172. //IIC&#203;ù&#211;&#208;&#178;&#217;×÷&#186;&#175;&#202;&#253;
  173. void IIC_Init(void);                //&#179;&#245;&#202;&#188;&#187;&#175;IIC&#181;&#196;IO&#191;&#218;                                 
  174. void IIC_Start(void);                                //·&#162;&#203;&#205;IIC&#191;&#170;&#202;&#188;&#208;&#197;&#186;&#197;
  175. void IIC_Stop(void);                                  //·&#162;&#203;&#205;IIC&#205;&#163;&#214;&#185;&#208;&#197;&#186;&#197;
  176. void IIC_Send_Byte(uint8_t txd);                        //IIC·&#162;&#203;&#205;&#210;&#187;&#184;&#246;×&#214;&#189;&#218;
  177. uint8_t IIC_Read_Byte(unsigned char ack);//IIC&#182;&#193;&#200;&#161;&#210;&#187;&#184;&#246;×&#214;&#189;&#218;
  178. uint8_t IIC_Wait_Ack(void);                                 //IIC&#181;&#200;&#180;&#253;ACK&#208;&#197;&#186;&#197;
  179. void IIC_Ack(void);                                        //IIC·&#162;&#203;&#205;ACK&#208;&#197;&#186;&#197;
  180. void IIC_NAck(void);                                //IIC&#178;&#187;·&#162;&#203;&#205;ACK&#208;&#197;&#186;&#197;

  181. void IIC_Write_One_Byte(uint8_t daddr,uint8_t addr,uint8_t data);
  182. uint8_t IIC_Read_One_Byte(uint8_t daddr,uint8_t addr);         
  183. #endif



  184. //24cxx.c

  185. #include "24cxx.h"
  186. #include "delay.h"
  187. #include "usart4.h"

  188. void AT24CXX_Init(void)
  189. {
  190.         IIC_Init();
  191. }


  192. u8 AT24CXX_ReadOneByte(u16 ReadAddr)
  193. {                                  
  194.         u8 temp=0;                                                                                                                                                               
  195.     IIC_Start();  
  196.         if(EE_TYPE>AT24C16)
  197.         {
  198.                 IIC_Send_Byte(0XA0);         
  199.                 IIC_Wait_Ack();
  200.                 IIC_Send_Byte(ReadAddr>>8);
  201.         }else IIC_Send_Byte(0XA0+((ReadAddr/256)<<1));
  202.         IIC_Wait_Ack();
  203.     IIC_Send_Byte(ReadAddr%256);  
  204.         IIC_Wait_Ack();            
  205.         IIC_Start();                     
  206.         IIC_Send_Byte(0XA1);                  
  207.         IIC_Wait_Ack();         
  208.     temp=IIC_Read_Byte(0);                  
  209.     IIC_Stop();
  210.         printf("readonebyteis:%d",temp);       
  211.         return temp;
  212. }


  213. void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
  214. {                                                                                                                                                                                          
  215.     IIC_Start();  
  216.         if(EE_TYPE>AT24C16)
  217.         {
  218.                 IIC_Send_Byte(0XA0);          
  219.                 IIC_Wait_Ack();
  220.                 IIC_Send_Byte(WriteAddr>>8);
  221.         }else IIC_Send_Byte(0XA0+((WriteAddr/256)<<1));   
  222.         IIC_Wait_Ack();          
  223.     IIC_Send_Byte(WriteAddr%256);   
  224.         IIC_Wait_Ack();                                                                                                              
  225.         IIC_Send_Byte(DataToWrite);                                              
  226.         IIC_Wait_Ack();                                
  227.     IIC_Stop();
  228.         delay_ms(1);         
  229. }


  230. void AT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len)
  231. {         
  232.         u8 t;
  233.         for(t=0;t<Len;t++)
  234.         {
  235.                 AT24CXX_WriteOneByte(WriteAddr+t,(DataToWrite>>(8*t))&0xff);
  236.         }                                                                                                    
  237. }



  238. u32 AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len)
  239. {         
  240.         u8 t;
  241.         u32 temp=0;
  242.         for(t=0;t<Len;t++)
  243.         {
  244.                 temp<<=8;
  245.                 temp+=AT24CXX_ReadOneByte(ReadAddr+Len-t-1);                                            
  246.         }
  247.         return temp;                                                                                                    
  248. }


  249. u8 AT24CXX_Check(void)
  250. {
  251.         u8 temp;
  252.         temp=AT24CXX_ReadOneByte(255);//±&#220;&#195;&#226;&#195;&#191;&#180;&#206;&#191;&#170;&#187;ú&#182;&#188;&#208;&#180;AT24CXX                          
  253.         if(temp==0X55)return 0;                  
  254.         else//&#197;&#197;&#179;&#253;&#181;&#218;&#210;&#187;&#180;&#206;&#179;&#245;&#202;&#188;&#187;&#175;&#181;&#196;&#199;é&#191;&#246;
  255.         {
  256.                 AT24CXX_WriteOneByte(255,0X55);
  257.             temp=AT24CXX_ReadOneByte(255);          
  258.                 if(temp==0X55)return 0;
  259.         }
  260.         return 1;                                                                                          
  261. }



  262. void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)
  263. {
  264.         while(NumToRead)
  265.         {
  266.                 *pBuffer++=AT24CXX_ReadOneByte(ReadAddr++);       
  267.                 NumToRead--;
  268.         }
  269. }  


  270. void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
  271. {
  272.         while(NumToWrite--)
  273.         {
  274.                 AT24CXX_WriteOneByte(WriteAddr,*pBuffer);
  275.                 WriteAddr++;
  276.                 pBuffer++;
  277.         }
  278. }


  279. //24cxx.h

  280. #ifndef _24CXX_H
  281. #define _24CXX_H
  282. #include "sys.h"
  283. #include "myiic.h"

  284. #define AT24C01                127
  285. #define AT24C02                255
  286. #define AT24C04                511
  287. #define AT24C08                1023
  288. #define AT24C16                2047
  289. #define AT24C32                4095
  290. #define AT24C64          8191
  291. #define AT24C128        16383
  292. #define AT24C256        32767  


  293. #define EE_TYPE AT24C128
  294.                                           
  295. u8 AT24CXX_ReadOneByte(u16 ReadAddr);                                                        //&#214;&#184;&#182;¨&#181;&#216;&#214;·&#182;&#193;&#200;&#161;&#210;&#187;&#184;&#246;×&#214;&#189;&#218;
  296. void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite);                //&#214;&#184;&#182;¨&#181;&#216;&#214;·&#208;&#180;&#200;&#235;&#210;&#187;&#184;&#246;×&#214;&#189;&#218;
  297. void AT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len);//&#214;&#184;&#182;¨&#181;&#216;&#214;·&#191;&#170;&#202;&#188;&#208;&#180;&#200;&#235;&#214;&#184;&#182;¨&#179;¤&#182;&#200;&#181;&#196;&#202;&#253;&#190;&#221;
  298. u32 AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len);                                        //&#214;&#184;&#182;¨&#181;&#216;&#214;·&#191;&#170;&#202;&#188;&#182;&#193;&#200;&#161;&#214;&#184;&#182;¨&#179;¤&#182;&#200;&#202;&#253;&#190;&#221;
  299. void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite);        //&#180;&#211;&#214;&#184;&#182;¨&#181;&#216;&#214;·&#191;&#170;&#202;&#188;&#208;&#180;&#200;&#235;&#214;&#184;&#182;¨&#179;¤&#182;&#200;&#181;&#196;&#202;&#253;&#190;&#221;
  300. void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead);           //&#180;&#211;&#214;&#184;&#182;¨&#181;&#216;&#214;·&#191;&#170;&#202;&#188;&#182;&#193;&#179;&#246;&#214;&#184;&#182;¨&#179;¤&#182;&#200;&#181;&#196;&#202;&#253;&#190;&#221;

  301. u8 AT24CXX_Check(void);  //&#188;ì&#178;é&#198;÷&#188;&#254;
  302. void AT24CXX_Init(void); //&#179;&#245;&#202;&#188;&#187;&#175;IIC
  303. #endif
复制代码
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2019-8-12 03:20:57 | 显示全部楼层
帮顶
回复

使用道具 举报

3

主题

4

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2021-1-7
在线时间
7 小时
发表于 2021-5-10 17:02:32 | 显示全部楼层
ctang 发表于 2017-6-13 10:30
谢谢原子哥!硬件I2C2我调通了。

目前在学习usb转i2c,请教下原子哥传授下这个方面的代码或资料。谢谢 ...

调通了能否给个结果,我也遇到iic1能用iic2不能用
回复

使用道具 举报

14

主题

72

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
268
金钱
268
注册时间
2021-10-7
在线时间
44 小时
发表于 2021-11-7 21:09:00 | 显示全部楼层
sibalaxi 发表于 2021-5-10 17:02
调通了能否给个结果,我也遇到iic1能用iic2不能用

我也是I2C2不能用,I2C1能用,不知道楼主怎么解决的。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-11 08:42

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表