/* ----------------------------- */ /* I2C Low Level Routinen */ /* ----------------------------- */ /* -------------------- Standard Include Files --------------------- */ #include #include /* -------------------- Zusätzliche Include Files ------------------ */ #include "i2c_basic.h" // --------------------------------------------------------------- // Initialisiere den I2C Bus // --------------------------------------------------------------- void I2C1_Init() { GPIO_InitTypeDef GPIO_InitStruct; // Port Init Struct I2C_InitTypeDef I2C_InitStruct; // I2C Init Struct // Peripherie Takt einschalten I2C3: PB6 (I2C1 SCL) und PB7 (I2C1_SDA) RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // Port mit SCL/SCA einrichten GPIO_InitStruct.GPIO_Pin = I2C_SCL_PIN | I2C_SDA_PIN; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD; // Pins als Alternate Function einstellen GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // IO Speed, nicht Baudrate, 2 Mhz reicht GPIO_Init(I2C_SCL_PORT, &GPIO_InitStruct); // Struktur Parameter fuer I2C setzen I2C_StructInit(&I2C_InitStruct); // Rücksetzen auf Default I2C_InitStruct.I2C_ClockSpeed = I2C_SPEED; // 100 khz Busfrequenz I2C_InitStruct.I2C_Mode = I2C_Mode_I2C; // Normaler I2C Mode I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2; // 50:50 Duty Cycle I2C_InitStruct.I2C_OwnAddress1 = 0x00; // Dummy Adresse I2C_InitStruct.I2C_Ack = I2C_Ack_Enable; // ACK senden I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; // 7 Bit Adressierung // I2C3 mit den obigen Parametern konfigurieren I2C_Init(I2Cx, &I2C_InitStruct); // I2C einschalten I2C_Cmd(I2Cx, ENABLE); } void I2C1_Disable() { I2C_Cmd(I2Cx, DISABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, DISABLE); } /* ----- Erzeuge Start Bedingung ------ */ ErrorStatus i2c_start() { int timeout = I2C_TIMEOUT; I2C_GenerateSTART(I2Cx, ENABLE); /* Warte auf I2C EV5. Bus frei, Start akzeptiert */ while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)) { if (!(--timeout)) { return ERROR; } } return SUCCESS; } /* --------- Erzeuge Stop Bedingung ------- */ void i2c_stop() { I2C_GenerateSTOP(I2Cx, ENABLE); // while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY)); } /* ---------- Adressiere den Slave -------- Write: I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED Read: I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED */ ErrorStatus i2c_address_direction(uint8_t address, uint8_t direction) { unsigned int timeout = I2C_TIMEOUT; /* Adressiere den Slave mit Datenrichtung */ I2C_Send7bitAddress(I2Cx, address, direction); /* Warte auf I2C EV6, Slave hat seine Adressierung akzeptiert */ if (direction == I2C_Direction_Transmitter) { while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) { if (!(--timeout)) { return ERROR; } } } if (direction == I2C_Direction_Receiver) { while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) { if (!(--timeout)) { return ERROR; } } } return SUCCESS; } /* ------- Uebertrage 1 Byte an Slave ----- */ ErrorStatus i2c_write(uint8_t byte) { unsigned int timeout = I2C_TIMEOUT; I2C_SendData(I2Cx, byte); /* Warte auf Ev8_2, Datum wurde heraus geschoben */ while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) { if (!(--timeout)) return ERROR; } return SUCCESS; } /* Ein Byte vom Slave lesen und mit ACK bestätigen, dass noch ein weiteres Byte angefordert wird */ uint8_t i2c_receive_ack() { I2C_AcknowledgeConfig(I2Cx, ENABLE); /* Warte fuer I2C EV7, d.h. Daten sind im Register empfangen worden. */ while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)); return(I2C_ReceiveData(I2Cx)); } /* Ein Byte vom Slave lesen und mit NACK bestätigen, dass KEIN weiteres Byte angefordert wird. */ uint8_t i2c_receive_nack() { I2C_AcknowledgeConfig(I2Cx, DISABLE); // Warte fuer EV7 = Daten sind empfangen worden while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)); I2C_GenerateSTOP(I2Cx, ENABLE); while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)); // Read and return data byte from I2C data register return (I2C_ReceiveData(I2Cx)); }