Forum: Mikrocontroller und Digitale Elektronik STM32F103C8 - init I2C


von Matthias (Gast)


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).

von trag einfügen: Rec (Gast)


Lesenswert?

STM32 Cube HAL Beispiele
STM32 Cube MX

Alternativ: libopencm3

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Matthias schrieb:
> Ich finde leider nur Beispiele die auf STM32F3xx zugeschnitten zu sein
> scheinen.

Hier ein Beispiel, welches auf STM32F4xx und STM32F10x läuft - also auch 
auf STM32F103C8:

   https://www.mikrocontroller.net/svnbrowser/wordclock24h/src/i2c/

Allerdings ist der STM32 hier Master, ich weiß nicht, ob Du das willst.

von Matthias (Gast)


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

von Matthias (Gast)


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?

von Matthias (Gast)


Lesenswert?

wieder waren es die einfachsten Sachen ....

Raspberry hat ein seperates Netzteil, der STM32F1xx wurde über USB vom 
PC versorgt. Vorsorgung des STM32 auf Raspberry-USB gelegt und schon 
geht alles ;)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.