I2C @ STM32L476RG

OP #7491818
Lesenswert?
• ▲
▼

Ich versuche auf einem STM32L476RG ein EEPROM via I2C anzusprechen. Leider scheitere ich aber offenbar bereits an der grundsätzlichen Konfig. der I2C-Schnittstelle:

1
void config_i2c(void) {
2
  //Initialize PB13 and PB14 as SCL and SDA respectively:
3
  {
4
    RCC->AHB2ENR |= RCC_AHB2ENR_GPIOBEN;
5

6
    //Configure PB13 as SCL:
7
    {
8
      GPIOB->AFR[1] &= ~(GPIO_AFRH_AFRH5);
9
      GPIOB->AFR[1] |= ((uint32_t)GPIO_AF4_I2C2) << GPIO_AFRH_AFSEL13_Pos;
10
      GPIOB->MODER |= GPIO_MODER_MODER13_1;
11
      GPIOB->OTYPER |= GPIO_OTYPER_OT13;
12
      GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR13;
13
    }
14

15
    //Configure PB14 as SDA:
16
    {
17
      GPIOB->AFR[1] &= ~(GPIO_AFRH_AFRH6);
18
      GPIOB->AFR[1] |= ((uint32_t)GPIO_AF4_I2C2) << GPIO_AFRH_AFSEL14_Pos;
19
      GPIOB->MODER |= GPIO_MODER_MODER14_1;
20
      GPIOB->OTYPER |= GPIO_OTYPER_OT14;
21
      GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR14;
22
    }
23
  }
24

25
  //Initialize the I2C interface for master mode:
26
  {
27
    //Make sure HSI16 clock is turned on.
28
    RCC->CR |= RCC_CR_HSION;
29
    while(!(RCC->CR & RCC_CR_HSIRDY));
30

31
    //Select HSI16 clock as I2C2 clock.
32
    RCC->CCIPR |= RCC_CCIPR_I2C2SEL_1;
33

34
    //Enable the clock for the I2C interface.
35
    RCC->APB1ENR1 |= RCC_APB1ENR1_I2C2EN;
36

37
    //Disable the I2C peripheral.
38
    I2C2->CR1 &= ~(I2C_CR1_PE);
39

40
    //Configure timing for "Fast-mode".
41
    //(See Table 236 of the Reference Manual "RM0351, Rev 9" for the values.)
42
    I2C2->TIMINGR =
43
      (0x1u << I2C_TIMINGR_PRESC_Pos) +
44
      (0x9u << I2C_TIMINGR_SCLL_Pos) +
45
      (0x3u << I2C_TIMINGR_SCLH_Pos) +
46
      (0x2u << I2C_TIMINGR_SDADEL_Pos) +
47
      (0x3u << I2C_TIMINGR_SCLDEL_Pos);
48

49
    //"Stop" and "Restart" will be generated by software.
50
    I2C2->CR2 &= ~(I2C_CR2_AUTOEND);
51

52
    //Configure 7-bit addressing and set slave address.
53
    I2C2->CR2 &= ~(I2C_CR2_ADD10);
54
    I2C2->CR2 &= ~(I2C_CR2_SADD);
55
    I2C2->CR2 |= (NV_RAM_DEVICE_ADDRESS << 1)&0xFEul;
56

57
    //Enable the I2C peripheral.
58
    I2C2->CR1 |= I2C_CR1_PE;
59
  }
60
}

Wenn ich dann versuche, erst einmal einfach eine "Start Condition" zu generieren, passiert genau gar nichts. Das heisst, ich sehe auf dem Oszi. rein gar nichts auf den zwei Leitungen.

1
void do_some_magic(void) {
2
  //Set transfer dir. "write".
3
  I2C2->CR2 &= ~(I2C_CR2_RD_WRN);
4

5
  //Configure number of bytes to be written.
6
  I2C2->CR2 |= 1 << I2C_CR2_NBYTES_Pos;
7

8
  //Generate "Start Condition".
9
  I2C2->CR2 |= I2C_CR2_START;
10
  while(I2C2->CR2&I2C_CR2_START); //<-- HIER DREHT ES "FOREVER"
11

12
  return;
13
}

Was muss ich noch "enablen", "clearen" etc. oder was sonst ist falsch?

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.