Skocz do zawartości

C011 rejestry - konfiguracja I2C


Pomocna odpowiedź

Mam problem z zainicjowaniem I2C1. Msalmon na youtube ociąga się z kolejnymi poradnikami, a do tego zakładam, że po wstępie do UARTa będzie być może ADC, którego już rozpracowałem samodzielnie na podstawie reference manuala przeszedłem do próby sterowania ekspanderem PCF8574 z I2C. Ale o ile ADC był w miarę prosty i sensowny, tak zaczynam się gubić przy I2C. Mam taki fragment kodu który napisałem samodzielnie, i nie potrafię dobrać wartości rejestrów TIMINGR. Skopiowałem wartość z dawcy w HALu, próbowałem samodzielnie wyliczyć a także skorzystałem z tabeli 94 w RF dla stm32 C011 i dalej nie mogę uzyskać żadnego przebiegu na linii scl, którą podglądam oscyloskopem. Zegar to 12MHz, tyle samo wchodzi na APB, więc przy obliczeniach nie będzie się to dobrze pokrywać z tabelą 94 bo tam jest dla 8MHz, ale nawet przy złych ustawieniach powinienem otrzymać po prostu inne parametry jak większa albo mniejsza częstotliwość. Co muszę w kodzie jeszcze dodać? Czy samo ustawienie czasów nie wystarczy?

void I2C1_Config(void) {
	//PB6 AF6 SCL
	RCC->IOPENR |= RCC_IOPENR_GPIOBEN; // Enable GPIOB clock

	RCC->APBENR1 |= RCC_APBENR1_I2C1EN; // Enable I2C1 clock

	GPIOB->MODER &= ~(GPIO_MODER_MODE6_0); // Set Pin 6 as Alternative Function
	GPIOB->MODER |= GPIO_MODER_MODE6_1;

	GPIOB->OTYPER |= GPIO_OTYPER_OT6; // Set as open-drain

	GPIOB->OSPEEDR |= GPIO_OSPEEDR_OSPEED6_0; // Set as high speed
	GPIOB->OSPEEDR |= GPIO_OSPEEDR_OSPEED6_1;

	GPIOB->PUPDR |= GPIO_PUPDR_PUPD6_0; // Set as pull-up
	GPIOB->PUPDR &= ~(GPIO_PUPDR_PUPD6_1);

	GPIOB->AFR[0] |= GPIO_AFRL_AFSEL6_0; // Set Pin 6 as Alternative function 6
	GPIOB->AFR[0] &= ~(GPIO_AFRL_AFSEL6_1);
	GPIOB->AFR[0] &= ~(GPIO_AFRL_AFSEL6_2);
	GPIOB->AFR[0] |= GPIO_AFRL_AFSEL6_3;

	//PB7 AF6 SDA

	GPIOB->MODER &= ~(GPIO_MODER_MODE7_0); // Set Pin 7 as Alternative Function
	GPIOB->MODER |= GPIO_MODER_MODE7_1;

	GPIOB->OTYPER |= GPIO_OTYPER_OT7; // Set as open-drain

	GPIOB->PUPDR |= GPIO_PUPDR_PUPD7_0; // Set as pull-up
	GPIOB->PUPDR &= ~(GPIO_PUPDR_PUPD7_1);

	GPIOB->OSPEEDR |= GPIO_OSPEEDR_OSPEED7_0; // Set as high speed
	GPIOB->OSPEEDR |= GPIO_OSPEEDR_OSPEED7_1;

	GPIOB->AFR[0] |= GPIO_AFRL_AFSEL7_0; // Set Pin 7 as Alternative function 6
	GPIOB->AFR[0] &= ~(GPIO_AFRL_AFSEL7_1);
	GPIOB->AFR[0] &= ~(GPIO_AFRL_AFSEL7_2);
	GPIOB->AFR[0] |= GPIO_AFRL_AFSEL7_3;

	I2C1->CR1 &= ~(I2C_CR1_PE); // Disable I2C1

	I2C1->TIMINGR = 0x3042C3C7;

	I2C1->CR1 |= I2C_CR1_PE; // Enable I2C1

}

 

Reference manual STM32 C011.pdf

Edytowano przez DeadGeneratio
Dodanie RF
Link do komentarza
Share on other sites

Poprawiłem nieco kod, dodałem niektóre oczywistości jak generic call oraz disable clock stretching i zamieniłem konfigurację wyjścia jako no pull-up oraz no pull-down. Wzorowałem się także na czasie z dawcy halowskiego, dodałem maskę jak było w kodzie i ciągle nic nie działa.

void I2C1_Config(void) {
	//PB6 AF6 SCL
	RCC->IOPENR |= RCC_IOPENR_GPIOBEN; // Enable GPIOB clock

	RCC->APBENR1 |= RCC_APBENR1_I2C1EN; // Enable I2C1 clock

	GPIOB->MODER &= ~(GPIO_MODER_MODE6_0); // Set Pin 6 as Alternative Function
	GPIOB->MODER |= GPIO_MODER_MODE6_1;

	GPIOB->OTYPER |= GPIO_OTYPER_OT6; // Set as open-drain

	GPIOB->OSPEEDR &= ~GPIO_OSPEEDR_OSPEED6_0; // Set as low speed
	GPIOB->OSPEEDR &= ~GPIO_OSPEEDR_OSPEED6_1;

	GPIOB->PUPDR &= ~GPIO_PUPDR_PUPD6_0; // Set no pull-up and no pull-down
	GPIOB->PUPDR &= ~(GPIO_PUPDR_PUPD6_1);

	GPIOB->AFR[0] |= GPIO_AFRL_AFSEL6_0; // Set Pin 6 as Alternative function 6
	GPIOB->AFR[0] &= ~(GPIO_AFRL_AFSEL6_1);
	GPIOB->AFR[0] &= ~(GPIO_AFRL_AFSEL6_2);
	GPIOB->AFR[0] |= GPIO_AFRL_AFSEL6_3;

	//PB7 AF6 SDA

	GPIOB->MODER &= ~(GPIO_MODER_MODE7_0); // Set Pin 7 as Alternative Function
	GPIOB->MODER |= GPIO_MODER_MODE7_1;

	GPIOB->OTYPER |= GPIO_OTYPER_OT7; // Set as open-drain

	GPIOB->PUPDR &= ~GPIO_PUPDR_PUPD7_0; // Set no pull-up and no pull-down
	GPIOB->PUPDR &= ~(GPIO_PUPDR_PUPD7_1);

	GPIOB->OSPEEDR &= ~GPIO_OSPEEDR_OSPEED7_0; // Set as low speed
	GPIOB->OSPEEDR &= ~GPIO_OSPEEDR_OSPEED7_1;

	GPIOB->AFR[0] |= GPIO_AFRL_AFSEL7_0; // Set Pin 7 as Alternative function 6
	GPIOB->AFR[0] &= ~(GPIO_AFRL_AFSEL7_1);
	GPIOB->AFR[0] &= ~(GPIO_AFRL_AFSEL7_2);
	GPIOB->AFR[0] |= GPIO_AFRL_AFSEL7_3;

	I2C1->CR1 &= ~(I2C_CR1_PE); // Disable I2C1

	I2C1->CR1 |= I2C_CR1_NOSTRETCH; // Disable clock stretching
	I2C1->CR1 |= I2C_CR1_GCEN; // Enable general call mode
	I2C1->CR2 &= ~(I2C_CR2_ADD10); // Set 7-bit addressing mode

	I2C1->TIMINGR = 0x40000A0B  & 0xF0FFFFFFU; // Set timing

	I2C1->CR1 |= I2C_CR1_PE; // Enable I2C1

}

 

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.