2017-03-17 10 views
0

i2c를 통해 가속도계 데이터를 읽으려고합니다. 가속도계의 i2c 주소는 읽기의 경우 0x19이고 쓰기의 경우 0x18입니다. 가속도계와의 올바른 통신을 확인하기 위해 레지스터 0x00을 읽어야하고 결과로 0x12를 반환해야합니다. 그러나 나는 가속도계로부터 인정을받을 수 없다. HAL 라이브러리 및 CubeMX를 사용하여 생성 된 코드를 사용하고 있습니다. 코드는 다음과 같습니다.stm32 Nucleo-L011K4 i2c 승인 실패

#include "main.h" 
#include "stm32l0xx_hal.h" 

I2C_HandleTypeDef hi2c1; 

void SystemClock_Config(void); 
void Error_Handler(void); 
static void MX_GPIO_Init(void); 
static void MX_I2C1_Init(void); 


uint8_t data[2]; 
uint8_t result; 


int main(void) 
{ 
    HAL_Init(); 

    /* Configure the system clock */ 
    SystemClock_Config(); 

    /* Initialize all configured peripherals */ 
    MX_GPIO_Init(); 
    MX_I2C1_Init(); 

    while (1) 
    { 

      // HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) 
       HAL_I2C_Mem_Read_DMA(&hi2c1, 0x19, 0x00, 1, &result, 1); 
       HAL_Delay(100); 
    } 
} 

void SystemClock_Config(void) 
{ 

    RCC_OscInitTypeDef RCC_OscInitStruct; 
    RCC_ClkInitTypeDef RCC_ClkInitStruct; 
    RCC_PeriphCLKInitTypeDef PeriphClkInit; 

    /**Configure the main internal regulator output voltage */ 
    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); 

    /**Initializes the CPU, AHB and APB busses clocks */ 
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI; 
    RCC_OscInitStruct.MSIState = RCC_MSI_ON; 
    RCC_OscInitStruct.MSICalibrationValue = 0; 
    RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_5; 
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; 
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) 
    { 
    Error_Handler(); 
    } 

    /**Initializes the CPU, AHB and APB busses clocks */ 

    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK 
          |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; 
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI; 
    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_0) != HAL_OK) 
    { 
    Error_Handler(); 
    } 

    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2C1; 
    PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1; 
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) 
    { 
    Error_Handler(); 
    } 

    /**Configure the Systick interrupt time */ 
    HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000); 

    /**Configure the Systick */ 
    HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); 

    /* SysTick_IRQn interrupt configuration */ 
    HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); 
} 

/* I2C1 init function */ 
static void MX_I2C1_Init(void) 
{ 

    hi2c1.Instance = I2C1; 
    hi2c1.Init.Timing = 0x00000708; 
    hi2c1.Init.OwnAddress1 = 0x18; 
    hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; 
    hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; 
    hi2c1.Init.OwnAddress2 = 0; 
    hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK; 
    hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; 
    hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; 
    if (HAL_I2C_Init(&hi2c1) != HAL_OK) 
    { 
    Error_Handler(); 
    } 

    /**Configure Analogue filter */ 
    if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK) 
    { 
    Error_Handler(); 
    } 

} 

static void MX_GPIO_Init(void) 
{ 

    /* GPIO Ports Clock Enable */ 
    __HAL_RCC_GPIOC_CLK_ENABLE(); 
    __HAL_RCC_GPIOA_CLK_ENABLE(); 

} 

2 개의 외부 풀업 저항기가 사용됩니다 (4,7k 옴).

MC 핀 : 각각 SDA 및 SCL을 https://developer.mbed.org/platforms/ST-Nucleo-L011K4/

핀 D4와 D5. GND 및 3.3V는 가속도계 각각의 전원 연결부에 연결됩니다.

+0

주소 필드 끝에 R/W 비트를 수동으로 설정하지 않아도 HAL이 수동으로 처리합니다. 그래서 주소는'0x18 '이며, 왼쪽으로 1 씩 이동하고 상위 7 비트가 주소이기 때문에 첫 번째 비트 (비트 0)는 HAL 읽기 기능에 의해 1로 설정됩니다. 'HAL_I2C_Mem_Read_DMA (& hi2c1, ((0x18) << 1), 0x00, 1, & result, 1); –

+0

답장을 보내 주셔서 감사합니다. 장치 주소를 (0x18) << 1로 변경하려고했습니다. 나는 아직도 승인 오류 오류 코드를받습니다. – nayak

+0

'MX_I2C1_Init'에서 다음 라인이 잘못된 것 같습니다 :'hi2c1.Init.OwnAddress1 = 0x18;'. '0x18'은 슬레이브 주소이며, 가속도계의 주소는 MCU의 자체 주소를 설정하지 않습니다. 대신 '0'으로 설정할 수 있습니다. 아마 이것은 근본 원인이 아닙니다. –

답변

0

보드의 SDA 핀은 PB7이고 SCL 핀은 PB6입니다. 그러나 이러한 핀 클럭을 초기화하지 마십시오. MX_GPIO_Init 기능에서 포트 B 시계를 활성화해야합니다.

static void MX_GPIO_Init(void) 
{ 

    /* GPIO Ports Clock Enable */ 
    __HAL_RCC_GPIOC_CLK_ENABLE(); 
    __HAL_RCC_GPIOA_CLK_ENABLE(); 
    __HAL_RCC_GPIOB_CLK_ENABLE(); 

} 

MX_I2C1_Init 기능에서 OwnAddress1을 0으로 설정해야합니다.

hi2c1.Init.OwnAddress1 = 0; 

또한 어드레스 HAL_I2C_Mem_Read_DMA 또는 HAL_I2C_Mem_Read 함수 0x18이어야 읽었다. Timing이 정확한지 확신 할 수 없습니다. 대부분의 I2C 장치 클럭 속도는 100-400Khz입니다. I2C 디바이스 클럭 속도는 얼마입니까? 100 또는 400Khz에서 시도 할 수 있습니다.

hi2c1.Init.Timing = 400000; 
+0

st 마이크로 일렉트로닉스가 제공하는 I2C 예제 프로젝트를 수정하려고 시도했지만 이제는 i2c 통신이 작동하고 있습니다. – nayak

+0

I2C_ADDRESS (0x18 << 1)와 함께 HAL_I2C_Master_Receive_IT() 함수를 사용했습니다. I2C TIMING을 0x0020098E로 설정하여 100Khz 속도에 도달했습니다. 또한 클리너 파형을 얻으려면 저항 값을 2.2k로 줄였습니다. – nayak