Gyrosensor/I2C.c

68 lines
1.4 KiB
C

#include "stm32f10x.h"
#include "I2C.h"
#include <armv30_std.h>
#include <stm32f10x.h>
#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;
}