Forum: Mikrocontroller und Digitale Elektronik STM32-Code geht nicht, Compilerproblem?


von mh (Gast)


Lesenswert?

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
}

von mh (Gast)


Lesenswert?

Getestet wird in main.c nur folgendes:
1
i2c_writeByte(0x40, 0x11);
2
delay(1000000);
3
i2c_writeByte(0x40, 0x55);

von mh (Gast)


Lesenswert?

Das erste wird gesendet, das zweite nicht mehr.

von Alex W. (a20q90)


Lesenswert?

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

von mh (Gast)


Lesenswert?

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
}

von mh (Gast)


Lesenswert?

Keiner eine Idee?
Ich bin für jeden Hinweis dankbar!

von R. F. (rfr)


Lesenswert?

teste mal deine delayroutine.
Gruss
RFr

von mh (Gast)


Lesenswert?

Hab nun CooCox 1.7.8 installiert und arm-gcc 4.9 ...
Jetzt gehts...

von Patrick B. (p51d)


Lesenswert?

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.

von mh (Gast)


Lesenswert?

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?

von Patrick B. (p51d)


Lesenswert?

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.

von Bülent C. (mirki)


Lesenswert?

Die Lösung wird in Zeile 42 zu finden sein.

von Walter T. (nicolas)


Lesenswert?

[gelöscht wegen Irrtums]

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.