STM32-Code geht nicht, Compilerproblem?

Gast #4243509
Hallo,

ich versuche nun schon eine ganze Weile eine I2C-Bibliothek für einen 
STM32F103C8 zum laufen zu bekommen.
Programmcode hab ich von hier:

http://diller-technologies.de/stm32.html#i2c

Und soweit zusammengekürzt, dass es eigentlich offensichtlich gehen 
müsste.
Hab den Fehler in Zeile 100 lokalisiert (Zeile mit if(1) ... ).
Wenn ich die Variable i2cDirectionWrite hier abfrage geht der Code 
nicht.
Schreibe ich eine "1" rein, gehts soweit (s.u.).
Ich versteh nur nicht warum, da i2cDirectionWrite permanent "1" ist.

Ich verwende CooCox Version 1.7.7 und  gcc-arm Version 4_8.
Code-Optimierung ist auf -O0 (None).

Es scheint wohl ein Compilerproblem zu sein. Weiß jemand Rat??

Schonmal Besten Dank!!
1
#include <stdint.h>
2
#include "stm32f10x_i2c.h"
3
#include "stm32f10x_rcc.h"
4
#include "stm32f10x_gpio.h"
5
#include "misc.h"
6
#include "i2c.h"
7

8

9
volatile uint8_t deviceAddress = 0;
10
volatile uint8_t dataByte1 = 0;
11
volatile uint8_t dataByte0 = 0;
12
volatile uint8_t receivedDataByte1 = 0;
13
volatile uint8_t receivedDataByte0 = 0;
14
volatile uint8_t i2cDirectionWrite = 1;
15
volatile uint8_t i2cByteCounter = 0;
16
volatile uint8_t i2cBusyFlag = 0;
17

18
volatile uint8_t test = 1;
19

20
volatile uint8_t temp = 1;
21

22

23
void i2c_init(void)
24
{
25
  GPIO_InitTypeDef GPIO_InitStructure;
26
  NVIC_InitTypeDef NVIC_InitStructure;
27
  I2C_InitTypeDef I2C_InitStructure;
28

29
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
30
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
31

32
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
33
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
34
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
35
  GPIO_Init(GPIOB, &GPIO_InitStructure);
36

37
  NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;
38
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
39
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
40
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
41
  NVIC_Init(&NVIC_InitStructure);
42

43
  NVIC_InitStructure.NVIC_IRQChannel = I2C1_ER_IRQn;
44
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
45
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
46
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
47
  NVIC_Init(&NVIC_InitStructure);
48

49
  I2C_DeInit(I2C1);
50

51
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
52
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
53
  I2C_InitStructure.I2C_ClockSpeed = 100000;
54
  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
55
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
56
  I2C_InitStructure.I2C_OwnAddress1 = 0;
57
  I2C_Init(I2C1, &I2C_InitStructure);
58

59
  I2C_ITConfig(I2C1, I2C_IT_EVT, ENABLE);
60
  I2C_ITConfig(I2C1, I2C_IT_BUF, ENABLE);
61
  I2C_ITConfig(I2C1, I2C_IT_ERR, ENABLE);
62

63
  I2C_Cmd(I2C1, ENABLE);
64

65
  i2cBusyFlag = 0;
66
}
67

68
void i2c_writeByte(uint8_t address, uint8_t byte){
69
  while(i2cBusyFlag){}
70
  while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY)){}
71
  deviceAddress = address;
72
  dataByte0 = byte;
73
  i2cDirectionWrite = 1;
74
  i2cBusyFlag = 1;
75
  i2cByteCounter = 1;
76
  I2C_GenerateSTART(I2C1, ENABLE);
77
}
78

79
// ISR
80
void I2C1_EV_IRQHandler(void)
81
{
82

83
  if(I2C_GetFlagStatus(I2C1, I2C_FLAG_SB) == SET)
84
  {
85
    if(i2cDirectionWrite)
86
    {
87
         // STM32 Transmitter
88
         I2C_Send7bitAddress(I2C1, deviceAddress, I2C_Direction_Transmitter);
89
    }
90
    else
91
    {
92
         // STM32 Receiver
93
         I2C_Send7bitAddress(I2C1, deviceAddress, I2C_Direction_Receiver);
94
    }
95
  }
96
  else if(I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR) == SET || I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF) == SET){
97
    I2C_ReadRegister(I2C1, I2C_Register_SR1);
98
    I2C_ReadRegister(I2C1, I2C_Register_SR2);
99

100
    if(1) // hier soll eigentlich if(i2cDirectionWrite) stehen, geht nur nicht
101
    {
102

103
      // STM32 Transmitter
104
      if(i2cByteCounter == 2)
105
      {
106
        I2C_SendData(I2C1, dataByte1);
107
        i2cByteCounter--;
108
      }
109
      else if(i2cByteCounter == 1)
110
      {
111
        I2C_SendData(I2C1, dataByte0);
112
        i2cByteCounter--;
113
      }
114
      else
115
      {
116
        I2C_GenerateSTOP(I2C1, ENABLE);
117
        i2cBusyFlag = 0;
118
      }
119
    }
120
  }
121
}
122

123
// ISR
124
void I2C1_ER_IRQHandler(void)
125
{
126
  I2C_GenerateSTOP(I2C1, ENABLE);
127
  i2cBusyFlag = 0;
128

129
  I2C_ClearFlag(I2C1, I2C_FLAG_AF);
130
  I2C_ClearFlag(I2C1, I2C_FLAG_ARLO);
131
  I2C_ClearFlag(I2C1, I2C_FLAG_BERR);
132
}
kann es sein das delay als Sekunde angesehen wird?
reduziere bitte mal die Zeit und teste nochmal bzw. entferne das delay 
und schau nach ob nach dem senden das Programm weiter läuft.

Wenn nicht, können die PullUps für I2C fehlerhaft sein
Gast
Hallo,

das delay() ist einfach eine Schleife die Zeit totschlägt (s.u.), 
1000000 ist hier ca. eine halbe Sekunde.
Hardware ist in Ordnung, hab nen Portexpander am I2C dranhängen.
Das erste mal senden funktioniert. Nur das zweite mal nicht mehr.
Das funktioniert aber, wenn ich if(1) statt if(i2cDirectionWrite) 
schreibe.

1
void delay(uint32_t i)
2
{
3
    volatile uint32_t iZ = i;
4
    while (iZ--);
5
}
I2C und STM32 haben sich nicht so gerne...

Ich hatte bis jetzt auch immer wieder Probleme damit. Man muss exakt die 
Schritte in den Qube-Beispielen einhalten, damit dies läuft. Und selbst 
dann kann es sein, dass es sporadische aussetzer gibt. Das ging soweit, 
dass ich mir für die STM32 eine eigene LIB geschrieben habe. Damit hatte 
ich dann nie Probleme.
Gast
Ich verwende einfach die Funktionen aus der Standard-Library von ST.
Gibts mit dieser da etwa bekannte Probleme mit I2C?
Du meinst sicherlich stm32cube oder?
Ehm ja, diese meinte ich.
Fehler in der Lib gibts nicht, dafür ein paar in der Hardware (musst mal 
die Erratas lesen). ST hat hier über alle Versionen immer wieder 
Probleme.
Das schlimmste Problem ist, dass sie bei einem M4 den DMA nicht sauber 
gemacht haben (stürzt immer wieder ab, wenn zu viele Daten transferiert 
werden sollen).

Für Schreib- und Leseoperationen muss einfach der Ablauf wie in den 
Beispielen eingehalten werden. Dann klapts vielleicht.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 11 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

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.