STM32F103C8 - init I2C

Gast #4302555
Lesenswert?

Hallo,

ich probiere gerade I2C zwischen Raspberry Pi B+ und dem "STM32F103C8T6 
Minimum System Development Board" zu implementieren.

Bei Zweiterem versuche ich gerade die Initialisierung zu realisieren. 
Bei folgendem Code bin ich gerade:
1
void I2CG_Init(void){
2
  #define   I2C_Port    GPIOB
3
  #define   SCL         GPIO_Pin_6
4
  #define   SDA         GPIO_Pin_7
5

6
  GPIO_InitTypeDef GPIO_InitStructure;
7
  I2C_InitTypeDef I2C_InitStructure;
8

9
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
10
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
11
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
12
      GPIO_InitStructure.GPIO_Pin = SCL | SDA;
13
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
14
    GPIO_Init(I2C_Port, &GPIO_InitStructure);
15

16
      I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
17
      I2C_InitStructure.I2C_OwnAddress1 = 0x55;
18
      I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
19
      I2C_InitStructure.I2C_Ack = I2C_Ack_Disable;
20
      I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
21
      I2C_InitStructure.I2C_ClockSpeed = 50000;
22
    I2C_Init(I2C1, &I2C_InitStructure);
23
  
24
  I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_BUF, DISABLE);
25
  I2C_Cmd(I2C1, ENABLE);
26
}

Ich finde leider nur Beispiele die auf STM32F3xx zugeschnitten zu sein 
scheinen.

Wo kann ich nachschauen, wie I2C auf diesem Board richtig initialisiert 
wird?
Wie wird die "alternate function" festgelegt?
Ich sage den Pins zwar, dass sie AF sein sollen, aber laut Reference 
Manual gibt es mehr als eine AF für diese Pins (PB6 und PB7).
Gast #4302659
Lesenswert?

Frank M. schrieb:
> Allerdings ist der STM32 hier Master, ich weiß nicht, ob Du das willst.

Nein, der Master soll Slave werden.
Zum einen weil ich die Daten auf dem Raspberry dann gezielt in eine 
Datenbank speichern will, zum anderen weil ich mal gelesen habe, dass 
Raspi nicht echtzeitfähig ist, insofern halte ich ein Gelingen für 
wahrscheinlicher wenn der Raspi den Takt angibt.

Frank M. schrieb:
> https://www.mikrocontroller.net/svnbrowser/wordclock24h/src/i2c/

Schau ich mir mal an, mal sehen ob es mich weiter bringt

trag einfügen: Rec schrieb:
> STM32 Cube MX

Schönes Ding! :D
Gast #4307744
Lesenswert?

Ich habe wieder etwas Zeit gefunden und das Projekt weiter verfolgt.

Meiner Meinung nach ist der I2C1 richtig initialisiert und der 
Event-Interrupt sollte auch korrekt eingestellt werden. Wenn ich aber 
über den Raspi ein I2C-Device-Detect sende reagiert der Handler nicht. 
Eigentlich müsste er aber reagieren sobald der Bus angesprochen wird?
(I2C-Device-Detect listet alle im Bus vorhandenen Devices auf, ich denke 
also das es alle Slaves auf Präsenz prüft, also auch anspricht)

Hier der Code:
I2C- und NVIC-Init:
1
  GPIO_InitTypeDef GPIO_InitStructure;
2
  I2C_InitTypeDef I2C_InitStructure;
3

4
  RCC_APB1PeriphClockCmd(RCC_APB1ENR_I2C1EN, ENABLE);
5
  RCC_APB2PeriphClockCmd(RCC_APB2ENR_IOPBEN, ENABLE);
6
  RCC_APB2PeriphClockCmd(RCC_APB2ENR_AFIOEN, ENABLE);
7

8
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
9
      GPIO_InitStructure.GPIO_Pin = SCL_Pin | SDA_Pin;
10
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
11
    GPIO_Init(I2C_Port, &GPIO_InitStructure);
12

13
  I2C_StructInit(&I2C_InitStructure);
14
      I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
15
      I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
16
      I2C_InitStructure.I2C_OwnAddress1 = I2C_Adress;
17
      I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
18
      I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
19
      I2C_InitStructure.I2C_ClockSpeed = 100000;
20
    I2C_Init(I2C1, &I2C_InitStructure);
21
  NVIC_InitTypeDef NVIC_InitStructure;
22

23
  /* Configure the I2C event priority */
24
    NVIC_InitStructure.NVIC_IRQChannel                   = I2C1_EV_IRQn;
25
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
26
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;
27
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
28
  NVIC_Init(&NVIC_InitStructure);
29
    NVIC_InitStructure.NVIC_IRQChannel                   = I2C1_ER_IRQn;
30
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
31
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;
32
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
33
  NVIC_Init(&NVIC_InitStructure);
34

35
  I2C_ITConfig(I2C1, I2C_IT_BUF | I2C_IT_EVT | I2C_IT_ERR, ENABLE);
36
  I2C_Cmd(I2C1, ENABLE);

Die Interrupts habe ich einfach mit einem Delay versehen und einen 
Breakpoint gesetzt um zu sehen, ob sie überhaupt greifen. Wie gesagt tun 
sie das nicht.
1
void I2C1_ER_IRQHandler(void){
2
  Delay_Ms(1000);
3
}
4

5
void I2C1_EV_IRQHandler(void){
6
  Delay_Ms(1000);
7
}

Ist meine Annahme korrekt, dass die Breakpoints der Interrupt-Handler 
anschlagen müssten? Habe ich in der Initialisierung doch einen Fehler 
drin den ich nur nicht sehe?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren