STM32F4 Discovery I2C Sorunu

Başlatan mfurkan7, 11 Aralık 2023, 01:23:10

mfurkan7

Merhabalar,
I2C ile DS1307 sensöründen alınan data ile led yakmaya çalışıyorum. Ancak PB6'ya osiloskopu bağladığımda clock sinyali göremiyorum.

Kod çok karmaşık değil ancak nerede hata yaptığımı bulamadım. Bu denediğim 3.sensör. En basit olanı budur diye en son bu sensörü seçtim ancak bunda da iletişimi kuramadım. Yardımcı olabilirseniz sevinirim.
#include <stdio.h>
#include <stdint.h>
#include "stm32f407xx.h"

//SCL->PB6
//SDA->PB9
#define SLAVE_ADDRESS	0x68

void I2C_Init(void);
int I2C_ReadByte(char saddr, char maddr, char* data);
void delayMs(int n);

int main(){
	I2C_Init();
	RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;
	GPIOD->MODER |= GPIO_MODER_MODER12_0;
	char data;
	while(1){
		I2C_ReadByte(SLAVE_ADDRESS,0,&data);
		if(data & 1){
			GPIOD->ODR |= GPIO_ODR_OD12;
		}
		else{
			GPIOD->ODR &= ~GPIO_ODR_OD12;
		}
		delayMs(10);
	}
}

void I2C_Init(void){
	//Enable the port B clock
	RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;
	//Enable the I2C clock
	RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
	//Select the alternate function mode
	GPIOB->MODER |= GPIO_MODER_MODER6_1;
	GPIOB->MODER |= GPIO_MODER_MODER9_1;
	//Select the alternate function selection for SCL PB6
	GPIOB->AFR[0] |= GPIO_AFRH_AFSEL6_2;
	//Select the alternate function selection for SDA PB9
	GPIOB->AFR[1] |= GPIO_AFRH_AFSEL9_2;
	//Config PB6 and PB9 as Open Drain
	GPIOB->OTYPER |= GPIO_OTYPER_OT6;
	GPIOB->OTYPER |= GPIO_OTYPER_OT9;
	//Pull Up for PB6 and PB9
	GPIOB->PUPDR |= GPIO_PUPDR_PUPD6_0;
	GPIOB->PUPDR |= GPIO_PUPDR_PUPD9_0;

	//I2C Config
	//Software Reset
	I2C1->CR1 |= I2C_CR1_SWRST;
	I2C1->CR1 &= ~I2C_CR1_SWRST;
	//Set the frequency to 16MHz
	I2C1->CR2 |= (1U<<4);
	//100kHz Standard Mode calculation
	I2C1->CCR = 80;
	//Rise time setting
	I2C1->TRISE = 17;
	//Enable the I2C Peripheral
	I2C1->CR1 |= I2C_CR1_PE;

}

int I2C_ReadByte(char saddr, char maddr, char* data){
	volatile int tmp;
	while(I2C1->SR2 & I2C_SR2_BUSY){};
	I2C1->CR1 |= I2C_CR1_START;
	while(!(I2C1->SR1 & I2C_SR1_SB)){};
	I2C1->DR = saddr<<1;
	while(!(I2C1->SR1 & I2C_SR1_ADDR)){};
	tmp = I2C1->SR2;
	while(!(I2C1->SR1 & I2C_SR1_TXE)){};
	I2C1->DR = maddr;
	while(!(I2C1->SR1 & I2C_SR1_TXE)){};
	I2C1->CR1 |= I2C_CR1_START;
	while(!(I2C1->SR1 & I2C_SR1_SB)){};
	I2C1->DR = saddr<<1 | 1;
	while(!(I2C1->SR1 & I2C_SR1_ADDR)){};
	I2C1->CR1 &= ~I2C_CR1_ACK;
	tmp = I2C1->SR2;
	I2C1->CR1 |= I2C_CR1_STOP;
	while(!(I2C1->SR1 & I2C_SR1_RXNE)){};
	*data++ = I2C1->DR;
	return 0;
}

void delayMs(int n){
	for(;n>0;n--){
		for(int i=0;i<3195;i++);
	}
}