68 lines
1.4 KiB
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;
|
|
}
|
|
|