#include "stm32f10x.h" #include "I2C.h" #include #include #define I2C_TIMEOUT 100000 static uint8_t I2C_WaitFlag(volatile uint16_t *reg, uint16_t flag) { uint32_t timeout = I2C_TIMEOUT; while(!(*reg & flag)) { if(--timeout == 0) return 0; } return 1; } void I2C1_Init(void) { /* 1. Clock aktivieren */ RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; // GPIOB RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; // I2C1 /* 2. GPIO konfigurieren: PB6=SCL, PB7=SDA */ GPIOB->CRL &= ~((0xF << 24) | (0xF << 28)); GPIOB->CRL |= ((0xB << 24) | (0xB << 28)); // 0xB = Alternate Open Drain, 50MHz /* 3. I2C Reset */ I2C1->CR1 |= I2C_CR1_SWRST; I2C1->CR1 &= ~I2C_CR1_SWRST; /* 4. Peripherietakt einstellen */ I2C1->CR2 = 36; // APB1 = 36 MHz I2C1->CCR = 180; // 100kHz I2C1->TRISE = 37; // laut Datenblatt /* 5. Enable */ I2C1->CR1 |= I2C_CR1_PE; } void startSeq(void) { I2C1->CR1 |= I2C_CR1_START; // START setzen while(!(I2C1->SR1 & I2C_SR1_SB)); // Warten bis START gesendet } void stopSeq(void) { I2C1->CR1 |= I2C_CR1_STOP; } uint8_t I2C_SendAddress_Write(uint8_t addr) { I2C1->DR = addr << 1; // R/W = 0 if(!I2C_WaitFlag(&I2C1->SR1, I2C_SR1_ADDR)) return 0; (void)I2C1->SR1; // ADDR löschen (void)I2C1->SR2; return 1; }