OpenSTM32 Import von Source und Header files

OP #5960448
Lesenswert?

Hallo Freunde :-)

Ich bin ein Anfänger mit STM32. Ich benutze CubeMX und OpenSTM32 AC6 zum 
Programmieren. Mein erstes Projekt ist ein OLED-Display (ssd1306) auf 
dem Nucleon F411RE-Board. Ich möchte die Header und Source Files für das 
Oled Display in OpenSTM32 importieren. Kann aber keine Import-Funktion 
finden. Kann mir jemand sagen wie das geht.

Danke für die Hilfe. Rolf

PS: LD2 blinkt schon ;)
Angehängte Dateien:
Gast #5960460
Lesenswert?

Du musst die *.h und *.c Dateien einfach ins src Verzeichnis legen.

Wenn du magst, kannst du die *.h Dateien ins inc Verzeichnis legen. Ich 
mache das aber nicht so. Bei mir sind alle Quelltexte (außer HAL und 
CMSIS) im src Verzeichnis.

Welche konkrete Bibliothek willst du denn verwenden?
#5960569
Lesenswert?

Rolf D. schrieb:
> Der Compiler zeigt error in der main.c "conflicting typs in
> ssd1306_Fill(Black)"

Ich tippe mal du hast eine Funktion wie
void ssd1306_Fill(unsigned somecolor)
Wenn du jetzt dieser Funktion ein enum übergibst welches du per typedef 
zu einem Typ propagierst, dann meckert der Compiler zu recht, das die 
Typen nicht passen.

Du hast zwei Möglichkeiten:
Entweder du schreibst deine Funktion um, so dass sie den Typ 
"SSD1306_COLOR" akzeptiert, d.h. die Signatur wäre
void ssd1306_Fill(SSD1306_COLOR somecolor)
oder du führst einen Typecast durch wenn du die Funktion aufrufst, in 
etwa
ssd1306_Fill((SSD1306_COLOR)Black)
OP #5960584
Lesenswert?

Hab die Funktionen erst mal für eine normale int Var umgeschrieben. 
Jetzt meckert der Compiler aber bei einer Funktionen fürs Display, als 
ob das Header File nicht vorhanden wäre.

"Description  Resource  Path  Location  Type
undefined reference to `ssd1306_WriteCommand'  ssd1306.c  /Oled/Src 
line 70  C/C++ Problem"´


// Send a byte to the command register
void ssd1306_WriteCommand(uint8_t byte) {
  HAL_I2C_Mem_Write(&SSD1306_I2C_PORT, SSD1306_I2C_ADDR, 0x00, 1, &byte, 
1, HAL_MAX_DELAY);
}
Gast #5960601
Lesenswert?

>Jetzt meckert der Compiler aber bei einer Funktionen fürs Display, als
>ob das Header File nicht vorhanden wäre.
>
>"Description  Resource  Path  Location  Type
>undefined reference to `ssd1306_WriteCommand'  ssd1306.c  /Oled/Src

undefined reference bekommt man immer wenn die Funktion vom Linker
nicht gefunden wurde. Ist ssd1306_WriteCommand wirklich der 
Funktionsname?
Buchstabe für Buchstabe richtig?

Steht im Header ein Prototyp für
void ssd1306_WriteCommand(uint8_t byte);
?

Stimmt uint8_t für den Parameter?
byte als Parametername würde ich sofort ändern.
OP #5961588
Lesenswert?

Hab jetzt mal einen Test mit dem Anlegen eines neuen Header Files 
gemacht. Das merkwürdiger dabei ist, dass beim Anlegen eines neuen 
h.Files in AC6 das vorhandene Inc Verzeichnis nicht angezeigt wird und 
man keine Möglichkeit hat, ein neues Header File in diesem Verzeichnis 
anzulegen. Stattdessen habe ich das Source Verzeichnis benutzt und 
danach das Header File manuell in das Inc Verzeichnis verschoben.
Angehängte Dateien:
Gast #5961702
Lesenswert?

Rolf D. schrieb:
> Das merkwürdiger dabei ist, dass beim Anlegen eines neuen
> h.Files in AC6 das vorhandene Inc Verzeichnis nicht angezeigt wird und
> man keine Möglichkeit hat, ein neues Header File in diesem Verzeichnis
> anzulegen.

Die gehören da auch nicht hin.

In ein include Verzeichnis gehören die Header von Libraries, die im 
Binärformat (ohne Quelltext) vorliegen. Das ist im µC Umfeld aber eine 
sehr seltene Ausnahme.

Pärchen aus C-Quelltext und C-Header gehören ins src Verzeichnis, wenn 
sie nicht Bestandteil einer umfangreicheren Bibliothek sind, die 
außerhalb des Projektes liegt.
Gast #5962327
Lesenswert?

>Ich vermute dass es daran liegt, wie ich die h-files anlege.

Nein. Mein Post von 14:46 sagt was fehlt. Also tauch in die Untiefen 
deiner
IDE und suche nach der Stelle wo man ein define für den Compiler 
hinzufügen kann.

Da gibst du dann ein SSD1306_USE_I2C ein.

Die folgende Fehlermeldung ignorierst du einfach und bastelst da an den 
völlig falschen Stellen rum:

#error "You should define SSD1306_USE_SPI or SSD1306_USE_I2C macro!"
Gast #5962385
Lesenswert?

Das Command-Line Pattern sollte normalerweise so aussehen:
> ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}

Definitionen setzt bei Preprocessor unter "Defined Symbols (-D)"
OP #5962432
Lesenswert?

Ok. Hab das Command-Line Pattern wieder hergestellt und den Eintrag 
"SSD1306_USE_I2C" im Preprocessor gemacht. Jetzt gibt es keine 
Fehlermeldungen mehr. Da soll ein "STM32 Beginner" drauf kommen ;) Aber 
man lernt ja nie aus.

Vielen dank für die tolle Unterstützung :)

Gruß Rolf aus Wuppertal
Gast #5962950
Lesenswert?

Hallöchen..

Ein kleines Problem gibt es noch. Nachdem ich das Projekt über Run 
gestartet habe tut sich auf dem ic2 Bus leider nichts. Pullups (1K) sind 
vorhanden. Oled ist richtig angeschlossen. Auf dem Scop ist wärend der 
Initialisierung und im Betrieb  auf SDA und SCL kein Signal zu sehen.
Gast #5963095
Lesenswert?

Ich fürchte mit Stichworten ist jetzt nichts mehr zu machen.
Jetzt muss man die Quellen Schritt für Schritt durchgehen.

Zur Not solltest Du das erst einmal mit einem funktionierenden I2C 
Beispiel vergleichen.

Ist vermutlich nur ein kleiner Fehler wie Clock Enable, Pin Namen ....
Gast #5963183
Lesenswert?

Rolf D. schrieb:
> Da soll ein "STM32 Beginner" drauf kommen ;) Aber
> man lernt ja nie aus.

Das sind Grundlagen der Programmiersprache. Deswegen empfehle ich immer, 
die Sprache und die Entwicklungstools erstmal auf einem PC ohne 
Mikrocontroller kennen zu lernen.

Selbst dieser Einstellungsdialog ist nicht für die IDE spezifisch. Jede 
andere IDE hat einen ganz ähnlichen Dialog, weil er letztendlich dazu 
dient, die Kommandozeilenparameter für den gcc zusammen zu basteln.
OP #5963258
Lesenswert?

Hallo Stefanus..

Kleine Info über mich. Ich komme aus der Atmel Ecke und habe jahrelang 
mit Atmel Studio in C im Bereich der Musikelektronik gearbeitet. Mein 
größtes Projekte war der Degenerator. (Link: 
http://cczwei-forum.de/cc2/thread.php?threadid=5878&threadview=0&hilight=&hilightuser=0&page=34). 
So fremd ist mir das Ganze also nicht. Ich will erst einmal die 
Entwicklungsumgebung und die ARM Prozessoren kennen lernen und mit 
kleinen Projekten beginnen.

Gruß Rolf
OP #5964764
Lesenswert?

Ich komme nicht weiter. Auf dem i2c Bus rührt sich immer noch nix. 
SCL(D15) und SDA(D14) sind auf dem Nucleo-Board mit Pullups von 1.2K auf 
+3.3V angeschlossen. Slave Adresse vom Display (0x78) ist defeniert.
Um Fehler auszuschließen, nutze ich die SSD1306 Lib vorerst nicht.

Hab noch einmal ein neues Projekt mit IC2 in CubeMX generiert. Fürs 
senden von Daten benutze ich den HAL_I2C_Master_Transmit.
1
/* USER CODE BEGIN Header */
2
/**
3
  ******************************************************************************
4
  * @file           : main.c
5
  * @brief          : Main program body
6
  ******************************************************************************
7
  * @attention
8
  *
9
  * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
10
  * All rights reserved.</center></h2>
11
  *
12
  * This software component is licensed by ST under BSD 3-Clause license,
13
  * the "License"; You may not use this file except in compliance with the
14
  * License. You may obtain a copy of the License at:
15
  *                        opensource.org/licenses/BSD-3-Clause
16
  *
17
  ******************************************************************************
18
  */
19
/* USER CODE END Header */
20

21
/* Includes ------------------------------------------------------------------*/
22
#include "main.h"
23
#include "i2c.h"
24
#include "usart.h"
25
#include "gpio.h"
26

27
/* Private includes ----------------------------------------------------------*/
28
/* USER CODE BEGIN Includes */
29
#include "string.h"
30

31
/* USER CODE END Includes */
32

33
/* Private typedef -----------------------------------------------------------*/
34
/* USER CODE BEGIN PTD */
35

36
//I2C_HandleTypeDef hi2c1;
37

38
/* USER CODE END PTD */
39

40
/* Private define ------------------------------------------------------------*/
41
/* USER CODE BEGIN PD */
42
#define SLAVE_ADD_7BIT 0x78
43
#define SLAVE_ADD_8BIT 0x78 << 1
44

45
/* USER CODE END PD */
46

47
/* Private macro -------------------------------------------------------------*/
48
/* USER CODE BEGIN PM */
49

50

51
/* USER CODE END PM */
52

53
/* Private variables ---------------------------------------------------------*/
54

55
/* USER CODE BEGIN PV */
56

57
/* USER CODE END PV */
58

59
/* Private function prototypes -----------------------------------------------*/
60
void SystemClock_Config(void);
61
/* USER CODE BEGIN PFP */
62

63
/* USER CODE END PFP */
64

65
/* Private user code ---------------------------------------------------------*/
66
/* USER CODE BEGIN 0 */
67

68
/* USER CODE END 0 */
69

70
/**
71
  * @brief  The application entry point.
72
  * @retval int
73
  */
74
int main(void)
75
{
76
  /* USER CODE BEGIN 1 */
77

78
  /* USER CODE END 1 */
79
  
80

81
  /* MCU Configuration--------------------------------------------------------*/
82

83
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
84
  HAL_Init();
85

86
  /* USER CODE BEGIN Init */
87

88
  /* USER CODE END Init */
89

90
  /* Configure the system clock */
91

92
  SystemClock_Config();
93

94

95
  /* USER CODE BEGIN SysInit */
96

97
  /* USER CODE END SysInit */
98

99
  /* Initialize all configured peripherals */
100

101
  MX_GPIO_Init();
102
  MX_I2C1_Init();
103
  MX_USART2_UART_Init();
104

105
  /* USER CODE BEGIN 2 */
106

107
  /* USER CODE END 2 */
108

109
  /* Infinite loop */
110
  /* USER CODE BEGIN WHILE */
111
  while (1)
112
  {
113
    /* USER CODE END WHILE */
114

115
    /* USER CODE BEGIN 3 */
116

117
    HAL_Delay(150);
118
    HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
119

120
    char buffer[16];
121
    strcpy((char*) buffer,  (const char*) "Test 1");
122
    
123
    HAL_I2C_Master_Transmit(&hi2c1, SLAVE_ADD_8BIT, (uint8_t *) buffer,  7, 1000);
124
   
125
    HAL_Delay(150);
126
    HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
127
  }
128
  /* USER CODE END 3 */
129
}
130

131
/**
132
  * @brief System Clock Configuration
133
  * @retval None
134
  */
135
void SystemClock_Config(void)
136
{
137
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
138
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
139

140
  /** Initializes the CPU, AHB and APB busses clocks 
141
  */
142
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
143
  RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
144
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
145
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
146
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
147
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
148
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
149
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
150
  {
151
    Error_Handler();
152
  }
153
  /** Initializes the CPU, AHB and APB busses clocks 
154
  */
155
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
156
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
157
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
158
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
159
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
160
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
161

162
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
163
  {
164
    Error_Handler();
165
  }
166
}
167

168
/* USER CODE BEGIN 4 */
169

170
/* USER CODE END 4 */
171

172
/**
173
  * @brief  This function is executed in case of error occurrence.
174
  * @retval None
175
  */
176
void Error_Handler(void)
177
{
178
  /* USER CODE BEGIN Error_Handler_Debug */
179
  /* User can add his own implementation to report the HAL error return state */
180

181
  /* USER CODE END Error_Handler_Debug */
182
}
183

184
#ifdef  USE_FULL_ASSERT
185
/**
186
  * @brief  Reports the name of the source file and the source line number
187
  *         where the assert_param error has occurred.
188
  * @param  file: pointer to the source file name
189
  * @param  line: assert_param error line source number
190
  * @retval None
191
  */
192
void assert_failed(uint8_t *file, uint32_t line)
193
{ 
194
  /* USER CODE BEGIN 6 */
195
  /* User can add his own implementation to report the file name and line number,
196
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
197
  /* USER CODE END 6 */
198
}
199
#endif /* USE_FULL_ASSERT */
200

201
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Gast #5964775
Lesenswert?

Rolf D. schrieb:
> Ich komme nicht weiter. Auf dem i2c Bus rührt sich immer noch nix.

Wie äussert sich das?

Wenn du keinen I2C Slave der passenden Adresse angeschlossen
hast ist nach dem ersten Byte das der Master sendet Funkstille.
Ganz normal, denn der Master wartet nach der Adresse auf ein
Ack vom Slave.

Poste mal dein ganzes Projekt, ich versuche es dann mal auf
einem Discovery-Board von mir anzuschauen.
#5964803
Lesenswert?

Wenn ich vor dem Problem stehe daß ich aus der Doku einer 
Hersteller-Library (z.B. HAL) nicht schlau werde und auch nicht die 
Nerven habe die Doku des eigentlichen Controllers Bit für Bit wieder 
rückwärts nach HAL zu übersetzen  (ein nervenaufreibender Vorgang) dann 
versuch ich als nächstes einfach mal einen *funktionierenden 
Beispielcode* irgendwo aufzutreiben der die fragliche Peripherie in 
Betrieb nimmt und den dann zu verstehen und nachzuvollziehen.
Gast #5964805
Lesenswert?

Rolf D. schrieb:
> Aber auf den IC2 Leitungen müsste sich doch prinzipiell was tun. Auch
> wenn die Adresse nicht stimmt !?

STM Unterstützer schrieb:
> Wenn du keinen I2C Slave der passenden Adresse angeschlossen
> hast ist nach dem ersten Byte das der Master sendet Funkstille.

Heisst also dass du pro HAL_I2C_Master_Transmit-Versuch genau
ein Byte sehen könntest, aber auch nicht mehr.
Gast #5964831
Lesenswert?

Rolf D. schrieb:
> Um es noch einmal klar zu stellen.

Um es einmal klar zu stellen:

Eine Spur von Bedauern deinerseits könnte nicht schaden.

Aber scheinbar hast du nichts falsch gemacht, nur wir haben
nicht pingelig genug deine Salami-Scheiben abgefragt. Der
Fehler liegt also nur bei uns ....
OP #5964839
Lesenswert?

Hier ist das von CubeMX erzeugte I2C.c
1
 * File Name          : I2C.c
2
  * Description        : This file provides code for the configuration
3
  *                      of the I2C instances.
4
  ******************************************************************************
5
  * @attention
6
  *
7
  * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
8
  * All rights reserved.</center></h2>
9
  *
10
  * This software component is licensed by ST under BSD 3-Clause license,
11
  * the "License"; You may not use this file except in compliance with the
12
  * License. You may obtain a copy of the License at:
13
  *                        opensource.org/licenses/BSD-3-Clause
14
  *
15
  ******************************************************************************
16
  */
17

18
/* Includes ------------------------------------------------------------------*/
19
#include "i2c.h"
20

21
/* USER CODE BEGIN 0 */
22

23
/* USER CODE END 0 */
24

25
I2C_HandleTypeDef hi2c1;
26

27
/* I2C1 init function */
28
void MX_I2C1_Init(void)
29
{
30

31
  hi2c1.Instance = I2C1;
32
  hi2c1.Init.ClockSpeed = 400000;
33
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
34
  hi2c1.Init.OwnAddress1 = 0;
35
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
36
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
37
  hi2c1.Init.OwnAddress2 = 0;
38
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
39
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
40
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
41
  {
42
    Error_Handler();
43
  }
44

45
}
46

47
void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
48
{
49

50
  GPIO_InitTypeDef GPIO_InitStruct = {0};
51
  if(i2cHandle->Instance==I2C1)
52
  {
53
  /* USER CODE BEGIN I2C1_MspInit 0 */
54

55
  /* USER CODE END I2C1_MspInit 0 */
56
  
57
    __HAL_RCC_GPIOB_CLK_ENABLE();
58
    /**I2C1 GPIO Configuration    
59
    PB6     ------> I2C1_SCL
60
    PB7     ------> I2C1_SDA 
61
    */
62
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
63
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
64
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
65
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
66

67
    /* I2C1 clock enable */
68
   __HAL_RCC_I2C1_CLK_ENABLE();
69
  /* USER CODE BEGIN I2C1_MspInit 1 */
70

71
  /* USER CODE END I2C1_MspInit 1 */
72
  }
73
}
74

75
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* i2cHandle)
76
{
77

78
  if(i2cHandle->Instance==I2C1)
79
  {
80
  /* USER CODE BEGIN I2C1_MspDeInit 0 */
81

82
  /* USER CODE END I2C1_MspDeInit 0 */
83
    /* Peripheral clock disable */
84
    __HAL_RCC_I2C1_CLK_DISABLE();
85
  
86
    /**I2C1 GPIO Configuration    
87
    PB6     ------> I2C1_SCL
88
    PB7     ------> I2C1_SDA 
89
    */
90
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);
91

92
  /* USER CODE BEGIN I2C1_MspDeInit 1 */
93

94
  /* USER CODE END I2C1_MspDeInit 1 */
95
  }
96
} 
97

98
/* USER CODE BEGIN 1 */
99

100
/* USER CODE END 1 */
101

102
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
#5964842
Lesenswert?

Ich hab mir deinen Code mal angeschaut.

Was soll sowas?
1
    char buffer[16];
2
    strcpy((char*) buffer,  (const char*) "Test 1");
3

4
    HAL_I2C_Master_Transmit(&hi2c1, SLAVE_ADD_8BIT, (uint8_t *) buffer,  7, 1000);

Erwartest du, daß du deinem Display Klartext schicken kannst?
Du kannst erstmal nur Pixel setzen/löschen.

Das ist auch völliger Unfug:
1
/* Private define ------------------------------------------------------------*/
2
/* USER CODE BEGIN PD */
3
#define SLAVE_ADD_7BIT 0x78
4
#define SLAVE_ADD_8BIT 0x78 << 1

0x78 ist bereits die 8bit-Version der Adresse.
Die 7bit-Adresse ist 0x3c

Wenn du unbedingt solche Defines bauen willst, dann bitte so:
1
/* USER CODE BEGIN PD */
2
#define SLAVE_ADD_7BIT 0x3c
3
#define SLAVE_ADD_8BIT (SLAVE_ADD_7BIT << 1)
#5964852
Lesenswert?

Und was hast Du getan um zu verifizieren daß sich an den Pins "nichts 
tut"?

Hast Du die Pullups angeschlossen? Hast Du ein Oszilloskop angeschlossen 
mit beiden Kanälen auf SCL und SDA und auf fallende Flanke getriggert?

Was hast Du gemessen? Bitte detailliert beschreiben oder Oszi-Screenshot 
beifügen!
OP #5964912
Lesenswert?

Ich habe den Fehler gefunden. Die automatische Zuweisung von Pin PB6 und 
PB7 für I2C1 ist in CubeMX nicht richtig. Es müssen PB8 und PB9 sein. 
Habe die Zuweisung in CubeMX manuell geändert und schon läufts 
problemlos.

@Bernd.K. Danke für deinen Hinweis.

Im Anhang aktuelle Hardware Konfiguration in CubeMx und Scope Signale

Vielen Dank an alle :)
Angehängte Dateien:
Gast #5964913
Lesenswert?

Vorab: Ich habe kaum Erfahrung mit Cube MX und HAL.

Ich habe dein Programm auf meinem Nucleo Board (nur mit Pull-Up 
Widerständen und Logic Analyzer) ausprobiert und kann bestätigen, dass 
sich an den I²C Pins nichts tut. Die Initialisierung der I²C 
Schnittstelle geht noch, aber die Kommunikation bricht mit einer 
Fehlermeldung ab, die ich im angehängten Screenshot sichtbar gemacht 
habe.

Es scheint sich um einen Kommunikationsfehler zu handeln.

> SCL(D15) und SDA(D14)

Das sind die Arduino Bezeichnungen. Die "richtigen" STM32 Port Nummern 
findest du auf der Papp-Karte, die in der Verpackung des Nucleo Boardes 
lag (und natürlich auch in der PDF Bedienungsanleitung).

Jedenfalls sind das aus Sicht des Mikrocontrollers die Pins PB8 und PB9, 
die als alternative Funktion "I2C1 remap" haben. In deinem *.ioc File 
sehe ich allerdings nichts für diese Pins.

Insofern bin ich ziemlich sicher, dass du die falschen Pins benutzt.

Ich denke, du solltest dein Display an die Pins PB6 und PB7 anschließen. 
Das würde mit dem *.ioc File überein stimmen:
1
PB6.Mode=I2C
2
PB6.Signal=I2C1_SCL
3
PB7.Mode=I2C
4
PB7.Signal=I2C1_SDA

Dein nächstes Problem ist, dass die Funktion HAL_I2C_Master_Transmit() 
fehlschlägt, weil im Register I2C1.SR2 das busy Flag High ist. Im 
Referenzhandbuch steht dazu "Set by hardware on detection of SDA or SCL 
low".

Jetzt habe ich mir mal die komplette Konfiguration in den Registern 
angesehen:

CR1 = 1
Peripheral enabled

CR2 = 100100
Peripheral Clock Frequency is 36 Mhz

OAR1 = 100000000000000
"Should always be kept at 1 by software."

OAR2 = 0
Ok

DR = 0
Ok

SR1 = 0
Keine Störung

SR2 = 10
Communication ongoing on the bus
Set by hardware on detection of SDA or SCL low, cleared by hardware on 
detection of a Stop condition.

CCR = 1000000000011110
Fast mode, die unteren Bits habe ich nicht geprüft

TRISE = 1011
habe ich nicht geprüft

Bis hierhin habe ich noch keinen Fehler erkannt, bis auf dieses Busy 
Flag. Deswegen habe ich zur Probe mal die folgenden Befehle direkt vor 
die while Schleife eingefügt:
1
  SET_BIT(I2C1->CR1,I2C_CR1_SWRST);
2
  CLEAR_BIT(I2C1->CR1,I2C_CR1_SWRST);
3
  MX_I2C1_Init();

Und siehe da: Es läuft (der angehängte Screenshot von PulseView beweist 
es).

Ich vermute, dass beim Initialisieren ein Timing-Problem besteht oder 
die Hardware in der falschen Reihenfolge initialisiert wird. Denn wenn 
ich die while Schleife mal leer mache, so dass nur die Peripherie 
initialisiert wird, sehe ich die beiden Pins flackern. Das sollte schon 
nicht der Fall sein. Siehe angehängter Screenshot. Ich denke, diese 
Pulse bringen den Bus zum Blockieren.

Dazu habe ich bei meinen eigenen bare-metal Programmierversuchen vor 
einigen Monaten Programmierversuchen etwas herausgefunden: Und zwar muss 
man zuerst den I²C initialisieren und erst dann die I/O Pins. Nur dann 
startet er sauber ohne falsche Impulse.

Wenn ich in deinem Code die beiden Zeilen tausche, klappt es aber 
trotzdem nicht:
1
  MX_I2C1_Init();
2
  MX_GPIO_Init();

Ich denke, dass der eigentliche Fehler (mal wieder) in der HAl steckt, 
und zwar in der Funktion HAL_I2C_Init(). Diese ruft nämlich zuerst
1
/* Init the low level hardware : GPIO, CLOCK, NVIC */
2
HAL_I2C_MspInit(hi2c);
auf, und initialisiert danach den I²C Controller. Das ist genau die 
falsche Reihenfolge - jedenfalls beim STM32F103. Beim STM32F303 wäre 
diese Reihenfolge Ok, nur mal so nebenbei bemerkt.

Damit habe ich dein Problem noch nicht gelöst, aber zumindest eine 
Richtung zur weiteren Analyse gegeben. Ich hoffe es bringt Dich weiter.

Nachtrag: Falls sich meine Antworten mit vorherigen überlappen, bitte 
ich um Entschuldigung. Ich habe eine ganze Weile gebraucht, um das 
Problem zu analysieren.
Gast #5964923
Lesenswert?

Du hast ja jetzt erfolgreich andere Pins verwendet als ich. Ich würde 
trotzdem nochmal prüfen, ob die Initialisierung (mit leerer 
while-Schleife) korrekt abläuft. Auf den beiden Pins dürfen dann keine 
Impulse sichtbar sein.

Falls doch, wirst du früher oder später wieder Probleme bekommen. Ich 
erinnere mich, dass dies hier öfters diskutiert wird. Irgendein 
Busteilnehmer blockiert bei Reset (oder Einschalten der Stromversorgung) 
sporadisch, dann sucht man sich einen Wolf.

Ich bin ziemlich sicher, dass die Initialisierungsreihenfolge der HAL 
hier fehlerhaft ist.
Gast #5964972
Lesenswert?

Ich wüsste auch gerne mal, warum die Platine mit den möchtegern Arduino 
kompatiblen Funktionen beschriftet ist, anstatt mit den "richtigen" 
Pinbezeichnungen des STM32.

Oder: Warum gibt es keinen USB Anschluss für das Target?

Für den niedrigen Preis sind das ja ganz nette Boards, aber ein paar 
kleine Details finde ich einfach nur gaga.

Ich würde vorschlagen, das nächste Problem in einem neuen Thread zu 
diskutieren. Von der ursprünglichen Frage sind wir ja inzwischen schon 
weit entfernt.
OP #5965534
Lesenswert?

Hallöchen..

Spaßeshalber hab ich mal die I2C Datenübertragung vom Nucleo-F103RB Bord 
(Master) zum Oled-Display (Slave) mit dem Scope überprüft. Die 
Übertragungsgeschwindigkeit ist im Test auf den Standartmode (100KHz) 
eingestellt. Maximal sind im Fastmode aber 400KHz möglich.

Zur Info: Das SDA-Signal ist gelb und das SCL-Signal violett.

Im 1.Bild ist nach der Übermittlung der Slave-Adresse (7 Bit) und  dem 
ReadWrite-Bit (8.Bit) das Acknowledge-Bit (9.Bit) zu erkennen. Als 
Bestätigung für die richtige Adresse legt der Slave die Datenleitung auf 
low und signalisiert dem Master das er jetzt mit dem Senden eines 
Datenbyte beginnen kann.

Im 2.Bild übertrage ich eine andere Adresse an den Slave. Das 
Acknowledge-Bit bleibt high und der Master stoppt die Übertragung zum 
Slave.
Angehängte Dateien:
Gast #6002378
Lesenswert?

Hallo Rolf,

der Audio Scope sieht gut aus.

Im cc2 Forum fand ich den Artikel (STM32)über CubeMX sehr gut erklärt.

Aber beim "SW4STM32 System Workbench" hätte ich einige Fragen:


1.Welche einstellungen sind zu treffen damit mann über die SWD den code 
übertragen kann (habe nur Cpu STM32f103 und v-link) ?

2. Wie ist die Ordnerstruktur ?
<Wohin (ORDNER) SW4STM32 installieren >
<Wohin (ORDNER) Projekt >
<Wohin (ORDNER) SPL,HAL etc.>

3. Wie importiere ich ein fertiges Projekt zb. "OLEDScope" ?


MFG

Ali
Gast #6002469
Lesenswert?

ali schrieb:
> Welche einstellungen sind zu treffen damit mann über die SWD den code
> übertragen kann

Guck Dir das an:
http://stefanfrings.de/stm32/system_workbench.html
http://stefanfrings.de/stm32/stm32f1.html

> Wie ist die Ordnerstruktur ?

Ziemlich egal, weil du in der IDE in den Projekteinstellungen die ganzen 
Pfade konfigurieren kannst. Für Arbeiten mit HAL generiert Cube MX 
komplette Projekte mit passender Verzeichnisstruktur und Konfiguration. 
Für Projekte ohne HAL generiert die IDE selbst (File/New Project) die 
grundsätzliche Verzeichnisstruktur.

Ich hab hier 
http://stefanfrings.de/mikrocontroller_buch2/Einblick%20in%20die%20moderne%20Elektronik.pdf 
ab Kapitel 9 einiges zur Verzeichnis-Struktur und der Konfiguration 
geschrieben.

> Wie importiere ich ein fertiges Projekt zb. "OLEDScope" ?

Steht auch in dem PDF. Schau dich mal im File Menü um, da findest du 
ganz viele spannende Funktionen, die zu deinen Fragen passen.
Gast #6003455
Lesenswert?

Hallo Stefan,vielen Dank für die Links.

Habe Sie kurz überflogen,werde Sie aber noch genauer anschauen.
Ich finde die Tutorials sind sehr gut gelungen. {TOP 5 STERNE}

Frage zur :  9.1  Projektvorlage kopieren

Behandelt die IDE das kopierte Projekt „Test1“ danach als neues 
eigenständiges Projekt?



Frage zur : 9.2  Projekt-Struktur

Wenn ich meinem Freund den Projekt-Ordner „Test1“ übergebe,müsste Es bei 
Ihm genauso funktionieren.
{Denn da ist ja Alles drinn !!!}

Reicht Es wenn ER „Test1“ importiert ?

MFG

Ali
Gast #6003651
Lesenswert?

Ali schrieb:
> Behandelt die IDE das kopierte Projekt „Test1“ danach als neues
> eigenständiges Projekt?

Ja.

> Wenn ich meinem Freund den Projekt-Ordner „Test1“ übergebe,müsste
> Es bei Ihm genauso funktionieren. {Denn da ist ja Alles drinn !!!}

Ja. Ich habe ja schließlich auch nur diesen einen Ordner (im ZIP Format) 
bereit gestellt, damit man ein fertiges Projekt zum Anfangen hat.

> Reicht Es wenn ER „Test1“ importiert ?

Ja

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