2017-11-04 1 views
2

I2C와 2 개의 장치를 연결하고 싶습니다. 하지만 I2C는 작동하지 않습니다. 나는 많은 노력을했지만 많은 웹 사이트를 보았지만 성공하지 못했습니다. 내 회로를 오실로스코프에 연결 한 다음 보낼 곳을 확인했습니다.STM32L152의 I2C가 작동하지 않습니다.

모든 것을 잘 연결하고 풀업 저항을 추가했습니다.

#include <stddef.h> 
#include "stm32l1xx.h" 
#include "stm32l1xx_rcc.h" 
#include "stm32l1xx_i2c.h" 
#include "stm32l1xx_gpio.h" 
#include "core_cmFunc.h" 


#define Timed(x) Timeout = 0xFFFF; while (x) { if (Timeout-- == 0) goto errReturn;} 

void I2C_LowLevel_Init() { 
    GPIO_InitTypeDef GPIO_InitStructure; 
    I2C_InitTypeDef I2C_InitStructure; 

    RCC_APB2PeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); 
    GPIO_StructInit(&GPIO_InitStructure); // configure I#C clock and GPIO 

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); 

    //Configure pins: SCL and SDA ------------------ 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_400KHz; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; 
    GPIO_Init(GPIOB, &GPIO_InitStructure); 

// I2C1 reset 
    RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE); 
    RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE); 

    I2C_StructInit(&I2C_InitStructure); 
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; 
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; 
    I2C_InitStructure.I2C_OwnAddress1 = 1; 
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; 
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; 
    I2C_InitStructure.I2C_ClockSpeed = GPIO_Speed_400KHz; 

    I2C_Init(I2C1, &I2C_InitStructure); 
    I2C_Cmd(I2C1, ENABLE); 
} 


int I2C_Write(const uint8_t *buf, uint32_t nbyte, uint8_t SlaveAddress) { 
    uint32_t Timeout = 0; 
    if (nbyte) { 
     Timed(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); 
//  Intiate Start Sequence 
     I2C_GenerateSTART(I2C1, ENABLE); 
     Timed(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); 
//  Send Address EV5 
     I2C_Send7bitAddress(I2C1, SlaveAddress, I2C_Direction_Transmitter); 
     Timed(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); 
//  EV6 Write first byte EV8_1 
     I2C_SendData(I2C1, *buf++); 
     while (--nbyte) { 
//  wait on BTF 
      Timed(!I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF)); 
      I2C_SendData(I2C1, *buf++); 
     } 
     Timed(!I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF)); 
     I2C_GenerateSTOP(I2C1, ENABLE); 
     Timed(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF)); 
    } 
    return 1; 

    errReturn: 
    return -1; 
} 

int main(void) { 
    uint8_t buf[] = {0x01, 0x00, 0x13, 0xFF}; 
    I2C_LowLevel_Init(); 
    I2C_Write(&buf, 4, 0x20); 
} 
+0

은 HTTPS를 검토하십시오 : 당신이 오타가 // 유래 .com/help/mcve. 'I2C_Read' 함수는 관련이 없으므로 포함되어서는 안됩니다. – jwdonahue

+0

'I2C_Write'에서'errReturn' 라벨을 치지 않는다는 것을 어떻게 알 수 있습니까? – jwdonahue

+0

'#define Timed (x) Timeout = 0xFFFF; while (x) {if (Timeout-- == 0) goto errReturn;}'신뢰할 수있는 타이머가 아닙니다. 매우 빨리'x '에 의해 호출되는 함수를 통해 실행할 수 있습니다. – jwdonahue

답변

2

그냥 추측 : 여기

내 코드입니다

RCC_APB2PeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); 

변경 그것에 :

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); 
+0

아 감사합니다! 이제 나는 오실로스코프에서 어떤 일이 일어나고 있지만 여전히 유효한 I2C 신호는 아니라는 것을 알았습니다. – mbakker1996

+1

나는 범위에서 어떤 일이 일어나고 있는지 알아낼 필요가 있다고 생각한다. 일반적으로 디바이스 데이터 시트에는 I2C 신호 파형이 있습니다. –

관련 문제