Forum: Mikrocontroller und Digitale Elektronik STM32: interne Pull-Ups für SPI


von Traubensaft .. (increasingcurrant)


Lesenswert?

Hi,

ich möchte das SPI mit Hardware NSS am STM32F405RG nutzen. Die 
Konfiguration führe ich mit CubeMX durch.

Dort ist SPI1 aktiv und in der GPIO-Registerkarte wurden für alle 
SPI-Leitungen Pull-Ups aktiviert. Auf dem Scope sind diese jedoch im 
Ruhezustand immer auf LOW!

Hier der Code:
1
/* SPI1 init function */
2
static void MX_SPI1_Init(void)
3
{
4
5
  hspi1.Instance = SPI1;
6
  hspi1.Init.Mode = SPI_MODE_MASTER;
7
  hspi1.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
8
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
9
  hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
10
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
11
  hspi1.Init.NSS = SPI_NSS_HARD_OUTPUT;
12
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
13
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
14
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
15
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
16
  hspi1.Init.CRCPolynomial = 10;
17
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
18
  {
19
    Error_Handler();
20
  }
21
22
}
23
24
/** Configure pins as 
25
        * Analog 
26
        * Input 
27
        * Output
28
        * EVENT_OUT
29
        * EXTI
30
*/
31
static void MX_GPIO_Init(void)
32
{
33
34
  /* GPIO Ports Clock Enable */
35
  __HAL_RCC_GPIOA_CLK_ENABLE();
36
37
}


Im generierten Code konnte ich auch keinen Hinweis auf die SPI-Pull-Ups 
finden. Ich habe extra ein neues, leeres Projekt angelegt um 
Überschneidungen auszuschließen.

vielen Dank und vG
increasingcurrant

von Arduinoquäler (Gast)


Lesenswert?

Traubensaft .. schrieb:
> Auf dem Scope sind diese jedoch im
> Ruhezustand immer auf LOW!

Wenn du die Ausgänge meinst (MOSI, CLK, NSS) dann ist das ok.
Denn die werden - als Ausgänge konfiguriert - immer getrieben.
Hängt aber vom eingestellten Mode ab.

Der MISO Pin sollte dagegen HIGH sein wenn Pullup konfiguriert ist.

von grundschüler (Gast)


Lesenswert?

beim f103 gibt es für miso die mglk GPIO_AF_OPD und GPIO_AF_PP. 
letzteres dürfte der Pullup sein.

Bei clk richtet sich der Ruhezustand nach dem eingestellten Modus. 
SPI_POLARITY_HIGH müsste dann eigentlich high sein.

Die Pullups müsste man separat auch über SPIx->ODR setzen können.

von 5clowne (Gast)


Lesenswert?

Hi

wenn du mit CubeMX Projekte generierst, sollte der Code in etwa so 
aussehen:

1
void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
2
{
3
4
  GPIO_InitTypeDef GPIO_InitStruct;
5
  if(spiHandle->Instance==SPI1)
6
  {
7
  /* USER CODE BEGIN SPI1_MspInit 0 */
8
9
  /* USER CODE END SPI1_MspInit 0 */
10
    /* Peripheral clock enable */
11
    __HAL_RCC_SPI1_CLK_ENABLE();
12
  
13
    /**SPI1 GPIO Configuration    
14
    PA5     ------> SPI1_SCK
15
    PA6     ------> SPI1_MISO
16
    PA7     ------> SPI1_MOSI 
17
    */
18
    GPIO_InitStruct.Pin = SPI_SCK_LoRa_Pin|SPI_MISO_LoRa_Pin|SPI_MOSI_LoRa_Pin;
19
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
20
    GPIO_InitStruct.Pull = GPIO_PULLDOWN;
21
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
22
    GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;
23
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
24
25
    /* Peripheral interrupt init */
26
    HAL_NVIC_SetPriority(SPI1_IRQn, 0, 0);
27
    HAL_NVIC_EnableIRQ(SPI1_IRQn);
28
  /* USER CODE BEGIN SPI1_MspInit 1 */
29
30
  /* USER CODE END SPI1_MspInit 1 */
31
  }
32
  else if(spiHandle->Instance==SPI2)
33
  {
34
  /* USER CODE BEGIN SPI2_MspInit 0 */
35
36
  /* USER CODE END SPI2_MspInit 0 */
37
    /* Peripheral clock enable */
38
    __HAL_RCC_SPI2_CLK_ENABLE();
39
  
40
    /**SPI2 GPIO Configuration    
41
    PC2     ------> SPI2_MISO
42
    PC3     ------> SPI2_MOSI
43
    PB13     ------> SPI2_SCK 
44
    */
45
    GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
46
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
47
    GPIO_InitStruct.Pull = GPIO_NOPULL;
48
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
49
    GPIO_InitStruct.Alternate = GPIO_AF2_SPI2;
50
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
51
52
    GPIO_InitStruct.Pin = GPIO_PIN_13;
53
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
54
    GPIO_InitStruct.Pull = GPIO_NOPULL;
55
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
56
    GPIO_InitStruct.Alternate = GPIO_AF0_SPI2;
57
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
58
59
  /* USER CODE BEGIN SPI2_MspInit 1 */
60
61
  /* USER CODE END SPI2_MspInit 1 */
62
  }
63
}

Ansonsten einfach in der Init hinzufügen.

Je nach Mikrocontroller weicht die HAL etwas ab.

Grüße

von Traubensaft .. (increasingcurrant)


Angehängte Dateien:

Lesenswert?

Arduinoquäler schrieb:
> Denn die werden - als Ausgänge konfiguriert - immer getrieben.

Da hast du sicher recht.

grundschüler schrieb:
> SPI_POLARITY_HIGH müsste dann eigentlich high sein.

Denke ich auch. Ich habe mal einen Scope-Screenshot angehängt, damit ihr 
euch das Problem ansehen könnt. Aufgenommen wurde das Bild mit dem 
Quelltext aus dem ersten Beitrag auf dem Controller. Mit
1
hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
passt das irgenwie nicht so recht zusammen, oder?


Ist das ein Bug? Mache ich etwas anderes grundlegend falsch?

Mit dem Code von 5clowne kann ich nicht so viel anfangen. Schließlich 
sehe ich bei mir keine richtige GPIO-Config.

von 5clowne (Gast)


Lesenswert?

Code für genau deinen µC:

spi.c
1
/**
2
  ******************************************************************************
3
  * File Name          : SPI.c
4
  * Description        : This file provides code for the configuration
5
  *                      of the SPI instances.
6
  ******************************************************************************
7
  *
8
  * COPYRIGHT(c) 2017 STMicroelectronics
9
  *
10
  * Redistribution and use in source and binary forms, with or without modification,
11
  * are permitted provided that the following conditions are met:
12
  *   1. Redistributions of source code must retain the above copyright notice,
13
  *      this list of conditions and the following disclaimer.
14
  *   2. Redistributions in binary form must reproduce the above copyright notice,
15
  *      this list of conditions and the following disclaimer in the documentation
16
  *      and/or other materials provided with the distribution.
17
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
18
  *      may be used to endorse or promote products derived from this software
19
  *      without specific prior written permission.
20
  *
21
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
  *
32
  ******************************************************************************
33
  */
34
35
/* Includes ------------------------------------------------------------------*/
36
#include "spi.h"
37
38
#include "gpio.h"
39
40
/* USER CODE BEGIN 0 */
41
42
/* USER CODE END 0 */
43
44
SPI_HandleTypeDef hspi1;
45
46
/* SPI1 init function */
47
void MX_SPI1_Init(void)
48
{
49
50
  hspi1.Instance = SPI1;
51
  hspi1.Init.Mode = SPI_MODE_MASTER;
52
  hspi1.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
53
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
54
  hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
55
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
56
  hspi1.Init.NSS = SPI_NSS_HARD_OUTPUT;
57
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
58
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
59
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
60
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
61
  hspi1.Init.CRCPolynomial = 10;
62
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
63
  {
64
    Error_Handler();
65
  }
66
67
}
68
69
void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
70
{
71
72
  GPIO_InitTypeDef GPIO_InitStruct;
73
  if(spiHandle->Instance==SPI1)
74
  {
75
  /* USER CODE BEGIN SPI1_MspInit 0 */
76
77
  /* USER CODE END SPI1_MspInit 0 */
78
    /* Peripheral clock enable */
79
    __HAL_RCC_SPI1_CLK_ENABLE();
80
  
81
    /**SPI1 GPIO Configuration    
82
    PA4     ------> SPI1_NSS
83
    PA5     ------> SPI1_SCK
84
    PA6     ------> SPI1_MISO 
85
    */
86
    GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6;
87
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
88
    GPIO_InitStruct.Pull = GPIO_NOPULL;
89
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
90
    GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
91
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
92
93
  /* USER CODE BEGIN SPI1_MspInit 1 */
94
95
  /* USER CODE END SPI1_MspInit 1 */
96
  }
97
}
98
99
void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle)
100
{
101
102
  if(spiHandle->Instance==SPI1)
103
  {
104
  /* USER CODE BEGIN SPI1_MspDeInit 0 */
105
106
  /* USER CODE END SPI1_MspDeInit 0 */
107
    /* Peripheral clock disable */
108
    __HAL_RCC_SPI1_CLK_DISABLE();
109
  
110
    /**SPI1 GPIO Configuration    
111
    PA4     ------> SPI1_NSS
112
    PA5     ------> SPI1_SCK
113
    PA6     ------> SPI1_MISO 
114
    */
115
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6);
116
117
  }
118
  /* USER CODE BEGIN SPI1_MspDeInit 1 */
119
120
  /* USER CODE END SPI1_MspDeInit 1 */
121
} 
122
123
/* USER CODE BEGIN 1 */
124
125
/* USER CODE END 1 */
126
127
/**
128
  * @}
129
  */
130
131
/**
132
  * @}
133
  */
134
135
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

Sollte dann eigentlich im idle high sein und wenn nicht dann halt noch 
die Pin Config statt _NOPULL in PULLUP ändern.

von 5clowne (Gast)


Angehängte Dateien:

Lesenswert?

Bei mir sieht der Clock (pink) dann so aus.

von Traubensaft .. (increasingcurrant)


Lesenswert?

Ich habe deine Version mal in mein Programm kopiert und getestet. Hat 
leider nichts gebracht.
Dazu musste ich allerdings die msp-Funktionen in meinem Projekt 
auskommentieren. Diese befinden sich bei mir in einer extra Datei 
"stm32f4xx_hal_msp.c".

Aus welchem Grund ligen die SPI-Konfig und die dazugehörige GPIO-Konfig 
bei dir in einer Datei? Hast du de gezeigte Konfiguration auch mit 
CubeMX erstellt?  Wenn ja mit welcher Version? Ich nuzte Version 4.16.1 
STM32Cube V1.0

von Robin S. (der_r)


Lesenswert?

An der Stelle noch der Hinweis: Manche (alle? Nicht sicher...) STM32 
haben im Master Mode keine sinnvolle Funktion des NSS Pins als Hardware. 
Der ist einfach immer low, solange die SPI aktiviert ist (damit meine 
ich nicht während einer Übertragung!).


Mit DMA bleibt der NSS beispielsweise einfach dauerhaft low, bis man SPI 
komplett deaktiviert. Totaler Schwachsinn. Da hilft nur, NSS in Software 
steuern...

von grundschüler (Gast)


Lesenswert?

probier mal die register direkt zu schreiben und verfolge das im 
debugger:

//spi_enable
RCC->APB2ENR |= RCC_APB2Periph_SPI1;
SPI1->CR1 = SPI_CR1_SSM|SPI_CR1_SSI|SPI_CR1_MSTR|SPI_CR1_SPE;

von 5clowne (Gast)


Lesenswert?

Hi

ich nutze die Version 4.18.0 hab aber in Project -> Settings -> Code 
Generator einen Haken bei "Generate peripheral initialization as a pair 
of .c/.h/ files per peripheral" gesetzt.

Mich würde noch interessieren was für ein SPI Device du ansprechen 
willst und warum du RXONLY benutzt?

Den NSS Pin könntest du auch mal softwareseitig auf GND ziehen.

Grüße

von Traubensaft .. (increasingcurrant)


Lesenswert?

Hallo, vielen Dank für all eure Bemühungen.
Durch einiges Rumprobieren musste ich leider feststellen, dass die 
Platine einen Fehler aufwies. Die NSS-Leitung war relativ hochohmig mit 
der Massefläche verbunden.


Nun stehe ich vor einem neuen Problem: Ich versuche insgesamt 16 bit als 
Sequenzen von 2x 8 bit von meinem Sensor zu lesen. Manchmal bekomme ich 
jedoch 8 und manchmal 24 clock-Flanken. Weiß jemand darüber bescheid? 
Das Problem scheint spontan und ohne erkennbares System aufzutreten. Die 
erhaltenen Werte sind dann natürlich Murks.

von Mitlesa (Gast)


Lesenswert?

Traubensaft .. schrieb:
> Ich versuche insgesamt 16 bit als
> Sequenzen von 2x 8 bit von meinem Sensor zu lesen. Manchmal bekomme ich
> jedoch 8 und manchmal 24 clock-Flanken.

Welcher Sensor?

Ein Sensor sendet üblicherweise keine Clocks, daher "bekommst"
du auch keine Clock-Flanken sondern du erzeugst sie in deinem
Programm selbst.

Zeige dein Programm oder analysiere es selbst nach diesen
Gegebenheiten.

von Traubensaft .. (increasingcurrant)


Lesenswert?

Ein AS5311. Der spricht kein "echtes" SPI (der Hersteller nennt es SSI).

Die Clock-Flanken kommen natürlich vom µC. Nur eben manchmal 8 und 
manchmal 24 statt der gewünschten 16.

von Mitlesa (Gast)


Lesenswert?

Traubensaft .. schrieb:
> Die Clock-Flanken kommen natürlich vom µC.

Warum schreibst du dann dass du welche bekommst? Du bist
bei deiner Programmierung dafür verantorlich was passiert,
das gilt ganz besonders für das SPI. Da kommt clock-mässig
nichts von aussen.

Clocks werden nur dann erzeugt wenn du schreibend auf das
SPI-Datenregister zugreifst oder einen Schreibvorgang
per DMA darauf auslöst.

von Traubensaft .. (increasingcurrant)


Angehängte Dateien:

Lesenswert?

Ich habe ein neues, leeres Projekt angelegt um die Funktionalität 
isoliert zu testen. Mit der Funktion HAL_SPI_Receive(...) funktioniert 
alles soweit.

Mit der Funktion HAL_SPI_Receive_IT(...) wird NSS nicht bedient. Der 
Sensor gibt so keine Daten aus. Was mache ich hier falsch?

von Traubensaft .. (increasingcurrant)


Angehängte Dateien:

Lesenswert?

Ich habe es momentan mit verschiedenen Problemen zu tun. Hier noch mal 
ein paar Bilder von meinem Hauptprogramm. Gezeigt wird das Problem wenn 
nur 8 oder 24 Clock-Flanken auftreten.

Der Code dazu:
1
 /* USER CODE BEGIN WHILE */
2
3
 while (1)
4
  {
5
    
6
    
7
    HAL_Delay(10);
8
    HAL_SPI_Receive(&hspi1, dummyspi, 2, HAL_MAX_DELAY);
9
    
10
    
11
  /* USER CODE END WHILE */
12
13
  }

Die SPI-Schnittstelle wird nur an dieser Stelle im Code angesprochen. 
Wenn ich die Zeile auskommentiere, bleiben die Leitungen ruhig.

: Bearbeitet durch User
von grundschüler (Gast)


Lesenswert?

HAL_Delay(10);
    HAL_SPI_Receive(&hspi1, dummyspi, 2, HAL_MAX_DELAY);

Das sieht so aus als würde die wait-bsy/rxne/txe funktion nicht richtig 
funktionieren.

Probier mal rxne, wenn das mit den hal-Funktionen überhaupt geht. Wie 
kann man sich solche Funktionen, die einem die Übersicht über die 
Register nehmen, freiwillig antun?

von Traubensaft .. (increasingcurrant)


Lesenswert?

grundschüler schrieb:
> Wie kann man sich solche Funktionen, die einem die Übersicht über die
> Register nehmen, freiwillig antun?

Das ist in erster Linie eine Zeitfrage. Es geht hier um ein Projekt im 
Rahmen meines Studiums, in dem in Gruppen von vier bis fünf Studenten 
ein Stereolithographie-Drucker entwicklt werden muss.
Das Projekt behinhaltet Schaltungsentwicklung, Platinenlayout, 
mechanische Konstruktion, alle Auslegungsrechnungen, Platinenfertigung 
im Labor der Hochschule, Fertigung mechanischer Komponenten incl. Aufbau 
des Prototypen und eben die Programmentwicklung auf einer 
Mikrocontrollerplattform, mit der kein Gruppenmitglied vor Beginn des 
Semsters je zu tun hatte. Ich möchte nicht rumjammern, aber das ist 
objektiv betrachtet ein großes Arbeitspensum. Und da finde ich es nur 
nachvollziehbar für die Bedienung einer SPI-Schnittstelle eine 
vorhandene Bibliothek nutzen zu wollen.



Mitlesa schrieb im Beitrag #4897333:
> Aha, so so, das ist das Hauptprogramm, mehr nicht?

Ich hätte nicht damit gerechnet überhaupt noch eine Antwort zu erhalten, 
wenn ich 760 Zeilen Code hier hinklatsche. Zu verheimlichen habe ich 
natürlich nichts.
1
/**
2
  ******************************************************************************
3
  * File Name          : main.c
4
  * Description        : Main program body
5
  ******************************************************************************
6
  *
7
  * COPYRIGHT(c) 2017 STMicroelectronics
8
  *
9
  * Redistribution and use in source and binary forms, with or without modification,
10
  * are permitted provided that the following conditions are met:
11
  *   1. Redistributions of source code must retain the above copyright notice,
12
  *      this list of conditions and the following disclaimer.
13
  *   2. Redistributions in binary form must reproduce the above copyright notice,
14
  *      this list of conditions and the following disclaimer in the documentation
15
  *      and/or other materials provided with the distribution.
16
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
17
  *      may be used to endorse or promote products derived from this software
18
  *      without specific prior written permission.
19
  *
20
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
  *
31
  ******************************************************************************
32
  */
33
/* Includes ------------------------------------------------------------------*/
34
#include "stm32f4xx_hal.h"
35
36
/* USER CODE BEGIN Includes */
37
#include "AS5311.h"
38
#include "actuator.h"
39
#include "pidController.h"
40
#include "sincos1024.h"
41
/* USER CODE END Includes */
42
43
/* Private variables ---------------------------------------------------------*/
44
ADC_HandleTypeDef hadc1;
45
ADC_HandleTypeDef hadc2;
46
DMA_HandleTypeDef hdma_adc1;
47
DMA_HandleTypeDef hdma_adc2;
48
49
SPI_HandleTypeDef hspi1;
50
SPI_HandleTypeDef hspi3;
51
52
TIM_HandleTypeDef htim1;
53
TIM_HandleTypeDef htim2;
54
TIM_HandleTypeDef htim3;
55
TIM_HandleTypeDef htim4;
56
TIM_HandleTypeDef htim10;
57
TIM_HandleTypeDef htim12;
58
59
UART_HandleTypeDef huart4;
60
61
/* USER CODE BEGIN PV */
62
/* Private variables ---------------------------------------------------------*/
63
64
/* USER CODE END PV */
65
66
/* Private function prototypes -----------------------------------------------*/
67
void SystemClock_Config(void);
68
void Error_Handler(void);
69
static void MX_GPIO_Init(void);
70
static void MX_DMA_Init(void);
71
static void MX_ADC1_Init(void);
72
static void MX_SPI3_Init(void);
73
static void MX_TIM1_Init(void);
74
static void MX_TIM2_Init(void);
75
static void MX_TIM3_Init(void);
76
static void MX_TIM4_Init(void);
77
static void MX_TIM12_Init(void);
78
static void MX_UART4_Init(void);
79
static void MX_TIM10_Init(void);
80
static void MX_ADC2_Init(void);
81
static void MX_SPI1_Init(void);
82
83
void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
84
                
85
86
/* USER CODE BEGIN PFP */
87
/* Private function prototypes -----------------------------------------------*/
88
89
/* USER CODE END PFP */
90
91
/* USER CODE BEGIN 0 */
92
93
AS5311 sens_x, sens_y;
94
ACTUATOR act_x, act_y;
95
96
uint16_t adcbuffer[16];
97
uint16_t adcbuffer2[16];
98
99
uint8_t dummyspi[2];
100
101
102
/* USER CODE END 0 */
103
104
int main(void)
105
{
106
107
  /* USER CODE BEGIN 1 */
108
109
  /* USER CODE END 1 */
110
111
  /* MCU Configuration----------------------------------------------------------*/
112
113
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
114
  HAL_Init();
115
116
  /* Configure the system clock */
117
  SystemClock_Config();
118
119
  /* Initialize all configured peripherals */
120
  MX_GPIO_Init();
121
  MX_DMA_Init();
122
  MX_ADC1_Init();
123
  MX_SPI3_Init();
124
  MX_TIM1_Init();
125
  MX_TIM2_Init();
126
  MX_TIM3_Init();
127
  MX_TIM4_Init();
128
  MX_TIM12_Init();
129
  MX_UART4_Init();
130
  MX_TIM10_Init();
131
  MX_ADC2_Init();
132
  MX_SPI1_Init();
133
134
  /* USER CODE BEGIN 2 */
135
  //Belegung der Timer gemäß Konfig in CubeMX
136
  act_x.pwmtmr_pos = &htim3;
137
  act_x.pwmchn_pos = TIM_CHANNEL_2;
138
  act_x.pwmtmr_neg = &htim2;
139
  act_x.pwmchn_neg = TIM_CHANNEL_4;
140
  act_x.prt_enable = GPIOB;
141
  act_x.pin_enable = GPIO_PIN_3;
142
  
143
  act_y.pwmtmr_pos = &htim2;
144
  act_y.pwmchn_pos = TIM_CHANNEL_3;
145
  act_y.pwmtmr_neg = &htim3;
146
  act_y.pwmchn_neg = TIM_CHANNEL_1;
147
  act_y.prt_enable = GPIOC;
148
  act_y.pin_enable = GPIO_PIN_8;
149
  
150
  //initActuator(&act_x);
151
  //initActuator(&act_y);
152
 
153
154
  //Haupttimer starten
155
  HAL_TIM_Base_Start_IT(&htim10);
156
157
158
  // ADC mit DMA für Strommessung starten
159
  HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adcbuffer, 16);
160
  HAL_ADC_Start_DMA(&hadc2, (uint32_t*)adcbuffer2, 16);
161
  /* USER CODE END 2 */
162
163
  /* Infinite loop */
164
  /* USER CODE BEGIN WHILE */
165
  
166
  while (1)
167
  {
168
        
169
    HAL_Delay(10);
170
    HAL_SPI_Receive(&hspi1, dummyspi, 2, HAL_MAX_DELAY);
171
        
172
  /* USER CODE END WHILE */
173
  /* USER CODE BEGIN 3 */
174
175
  }
176
  /* USER CODE END 3 */
177
178
}
179
180
/** System Clock Configuration
181
*/
182
void SystemClock_Config(void)
183
{
184
185
  RCC_OscInitTypeDef RCC_OscInitStruct;
186
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
187
188
  __HAL_RCC_PWR_CLK_ENABLE();
189
190
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
191
192
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
193
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
194
  RCC_OscInitStruct.HSICalibrationValue = 16;
195
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
196
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
197
  RCC_OscInitStruct.PLL.PLLM = 8;
198
  RCC_OscInitStruct.PLL.PLLN = 168;
199
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
200
  RCC_OscInitStruct.PLL.PLLQ = 4;
201
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
202
  {
203
    Error_Handler();
204
  }
205
206
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
207
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
208
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
209
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
210
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
211
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
212
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
213
  {
214
    Error_Handler();
215
  }
216
217
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
218
219
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
220
221
  /* SysTick_IRQn interrupt configuration */
222
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
223
}
224
225
/* ADC1 init function */
226
static void MX_ADC1_Init(void)
227
{
228
229
  ADC_ChannelConfTypeDef sConfig;
230
231
    /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) 
232
    */
233
  hadc1.Instance = ADC1;
234
  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
235
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
236
  hadc1.Init.ScanConvMode = DISABLE;
237
  hadc1.Init.ContinuousConvMode = ENABLE;
238
  hadc1.Init.DiscontinuousConvMode = DISABLE;
239
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
240
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
241
  hadc1.Init.NbrOfConversion = 1;
242
  hadc1.Init.DMAContinuousRequests = ENABLE;
243
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
244
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
245
  {
246
    Error_Handler();
247
  }
248
249
    /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. 
250
    */
251
  sConfig.Channel = ADC_CHANNEL_10;
252
  sConfig.Rank = 1;
253
  sConfig.SamplingTime = ADC_SAMPLETIME_56CYCLES;
254
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
255
  {
256
    Error_Handler();
257
  }
258
259
}
260
261
/* ADC2 init function */
262
static void MX_ADC2_Init(void)
263
{
264
265
  ADC_ChannelConfTypeDef sConfig;
266
267
    /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) 
268
    */
269
  hadc2.Instance = ADC2;
270
  hadc2.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
271
  hadc2.Init.Resolution = ADC_RESOLUTION_12B;
272
  hadc2.Init.ScanConvMode = DISABLE;
273
  hadc2.Init.ContinuousConvMode = ENABLE;
274
  hadc2.Init.DiscontinuousConvMode = DISABLE;
275
  hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
276
  hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
277
  hadc2.Init.NbrOfConversion = 1;
278
  hadc2.Init.DMAContinuousRequests = ENABLE;
279
  hadc2.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
280
  if (HAL_ADC_Init(&hadc2) != HAL_OK)
281
  {
282
    Error_Handler();
283
  }
284
285
    /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. 
286
    */
287
  sConfig.Channel = ADC_CHANNEL_11;
288
  sConfig.Rank = 1;
289
  sConfig.SamplingTime = ADC_SAMPLETIME_56CYCLES;
290
  if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
291
  {
292
    Error_Handler();
293
  }
294
295
}
296
297
/* SPI1 init function */
298
static void MX_SPI1_Init(void)
299
{
300
301
  hspi1.Instance = SPI1;
302
  hspi1.Init.Mode = SPI_MODE_MASTER;
303
  hspi1.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
304
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
305
  hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
306
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
307
  hspi1.Init.NSS = SPI_NSS_HARD_OUTPUT;
308
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128;
309
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
310
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
311
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
312
  hspi1.Init.CRCPolynomial = 10;
313
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
314
  {
315
    Error_Handler();
316
  }
317
318
}
319
320
/* SPI3 init function */
321
static void MX_SPI3_Init(void)
322
{
323
324
  hspi3.Instance = SPI3;
325
  hspi3.Init.Mode = SPI_MODE_MASTER;
326
  hspi3.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
327
  hspi3.Init.DataSize = SPI_DATASIZE_8BIT;
328
  hspi3.Init.CLKPolarity = SPI_POLARITY_HIGH;
329
  hspi3.Init.CLKPhase = SPI_PHASE_1EDGE;
330
  hspi3.Init.NSS = SPI_NSS_HARD_OUTPUT;
331
  hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
332
  hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB;
333
  hspi3.Init.TIMode = SPI_TIMODE_DISABLE;
334
  hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
335
  hspi3.Init.CRCPolynomial = 10;
336
  if (HAL_SPI_Init(&hspi3) != HAL_OK)
337
  {
338
    Error_Handler();
339
  }
340
341
}
342
343
/* TIM1 init function */
344
static void MX_TIM1_Init(void)
345
{
346
347
  TIM_Encoder_InitTypeDef sConfig;
348
  TIM_MasterConfigTypeDef sMasterConfig;
349
350
  htim1.Instance = TIM1;
351
  htim1.Init.Prescaler = 0;
352
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
353
  htim1.Init.Period = 0;
354
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
355
  htim1.Init.RepetitionCounter = 0;
356
  sConfig.EncoderMode = TIM_ENCODERMODE_TI1;
357
  sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
358
  sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
359
  sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
360
  sConfig.IC1Filter = 0;
361
  sConfig.IC2Polarity = TIM_ICPOLARITY_RISING;
362
  sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
363
  sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
364
  sConfig.IC2Filter = 0;
365
  if (HAL_TIM_Encoder_Init(&htim1, &sConfig) != HAL_OK)
366
  {
367
    Error_Handler();
368
  }
369
370
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
371
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
372
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
373
  {
374
    Error_Handler();
375
  }
376
377
}
378
379
/* TIM2 init function */
380
static void MX_TIM2_Init(void)
381
{
382
383
  TIM_MasterConfigTypeDef sMasterConfig;
384
  TIM_OC_InitTypeDef sConfigOC;
385
386
  htim2.Instance = TIM2;
387
  htim2.Init.Prescaler = 0;
388
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
389
  htim2.Init.Period = 3583;
390
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
391
  if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
392
  {
393
    Error_Handler();
394
  }
395
396
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
397
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
398
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
399
  {
400
    Error_Handler();
401
  }
402
403
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
404
  sConfigOC.Pulse = 0;
405
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
406
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
407
  if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
408
  {
409
    Error_Handler();
410
  }
411
412
  if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
413
  {
414
    Error_Handler();
415
  }
416
417
  HAL_TIM_MspPostInit(&htim2);
418
419
}
420
421
/* TIM3 init function */
422
static void MX_TIM3_Init(void)
423
{
424
425
  TIM_MasterConfigTypeDef sMasterConfig;
426
  TIM_OC_InitTypeDef sConfigOC;
427
428
  htim3.Instance = TIM3;
429
  htim3.Init.Prescaler = 0;
430
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
431
  htim3.Init.Period = 3583;
432
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
433
  if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
434
  {
435
    Error_Handler();
436
  }
437
438
  if (HAL_TIM_OC_Init(&htim3) != HAL_OK)
439
  {
440
    Error_Handler();
441
  }
442
443
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
444
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
445
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
446
  {
447
    Error_Handler();
448
  }
449
450
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
451
  sConfigOC.Pulse = 0;
452
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
453
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
454
  if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
455
  {
456
    Error_Handler();
457
  }
458
459
  if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
460
  {
461
    Error_Handler();
462
  }
463
464
  if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
465
  {
466
    Error_Handler();
467
  }
468
469
  sConfigOC.OCMode = TIM_OCMODE_TIMING;
470
  if (HAL_TIM_OC_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
471
  {
472
    Error_Handler();
473
  }
474
475
  HAL_TIM_MspPostInit(&htim3);
476
477
}
478
479
/* TIM4 init function */
480
static void MX_TIM4_Init(void)
481
{
482
483
  TIM_Encoder_InitTypeDef sConfig;
484
  TIM_MasterConfigTypeDef sMasterConfig;
485
486
  htim4.Instance = TIM4;
487
  htim4.Init.Prescaler = 0;
488
  htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
489
  htim4.Init.Period = 0;
490
  htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
491
  sConfig.EncoderMode = TIM_ENCODERMODE_TI1;
492
  sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
493
  sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
494
  sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
495
  sConfig.IC1Filter = 0;
496
  sConfig.IC2Polarity = TIM_ICPOLARITY_RISING;
497
  sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
498
  sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
499
  sConfig.IC2Filter = 0;
500
  if (HAL_TIM_Encoder_Init(&htim4, &sConfig) != HAL_OK)
501
  {
502
    Error_Handler();
503
  }
504
505
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
506
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
507
  if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
508
  {
509
    Error_Handler();
510
  }
511
512
}
513
514
/* TIM10 init function */
515
static void MX_TIM10_Init(void)
516
{
517
518
  TIM_OC_InitTypeDef sConfigOC;
519
520
  htim10.Instance = TIM10;
521
  htim10.Init.Prescaler = 0;
522
  htim10.Init.CounterMode = TIM_COUNTERMODE_UP;
523
  htim10.Init.Period = 2399;
524
  htim10.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
525
  if (HAL_TIM_Base_Init(&htim10) != HAL_OK)
526
  {
527
    Error_Handler();
528
  }
529
530
  if (HAL_TIM_OC_Init(&htim10) != HAL_OK)
531
  {
532
    Error_Handler();
533
  }
534
535
  sConfigOC.OCMode = TIM_OCMODE_TIMING;
536
  sConfigOC.Pulse = 0;
537
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
538
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
539
  if (HAL_TIM_OC_ConfigChannel(&htim10, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
540
  {
541
    Error_Handler();
542
  }
543
544
}
545
546
/* TIM12 init function */
547
static void MX_TIM12_Init(void)
548
{
549
550
  TIM_OC_InitTypeDef sConfigOC;
551
552
  htim12.Instance = TIM12;
553
  htim12.Init.Prescaler = 0;
554
  htim12.Init.CounterMode = TIM_COUNTERMODE_UP;
555
  htim12.Init.Period = 0;
556
  htim12.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
557
  if (HAL_TIM_PWM_Init(&htim12) != HAL_OK)
558
  {
559
    Error_Handler();
560
  }
561
562
  if (HAL_TIM_OnePulse_Init(&htim12, TIM_OPMODE_SINGLE) != HAL_OK)
563
  {
564
    Error_Handler();
565
  }
566
567
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
568
  sConfigOC.Pulse = 0;
569
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
570
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
571
  if (HAL_TIM_PWM_ConfigChannel(&htim12, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
572
  {
573
    Error_Handler();
574
  }
575
576
  HAL_TIM_MspPostInit(&htim12);
577
578
}
579
580
/* UART4 init function */
581
static void MX_UART4_Init(void)
582
{
583
584
  huart4.Instance = UART4;
585
  huart4.Init.BaudRate = 115200;
586
  huart4.Init.WordLength = UART_WORDLENGTH_8B;
587
  huart4.Init.StopBits = UART_STOPBITS_1;
588
  huart4.Init.Parity = UART_PARITY_NONE;
589
  huart4.Init.Mode = UART_MODE_TX_RX;
590
  huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
591
  huart4.Init.OverSampling = UART_OVERSAMPLING_16;
592
  if (HAL_UART_Init(&huart4) != HAL_OK)
593
  {
594
    Error_Handler();
595
  }
596
597
}
598
599
/** 
600
  * Enable DMA controller clock
601
  */
602
static void MX_DMA_Init(void) 
603
{
604
  /* DMA controller clock enable */
605
  __HAL_RCC_DMA2_CLK_ENABLE();
606
607
  /* DMA interrupt init */
608
  /* DMA2_Stream0_IRQn interrupt configuration */
609
  HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
610
  HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
611
  /* DMA2_Stream2_IRQn interrupt configuration */
612
  HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
613
  HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
614
615
}
616
617
/** Configure pins as 
618
        * Analog 
619
        * Input 
620
        * Output
621
        * EVENT_OUT
622
        * EXTI
623
*/
624
static void MX_GPIO_Init(void)
625
{
626
627
  GPIO_InitTypeDef GPIO_InitStruct;
628
629
  /* GPIO Ports Clock Enable */
630
  __HAL_RCC_GPIOC_CLK_ENABLE();
631
  __HAL_RCC_GPIOH_CLK_ENABLE();
632
  __HAL_RCC_GPIOA_CLK_ENABLE();
633
  __HAL_RCC_GPIOB_CLK_ENABLE();
634
  __HAL_RCC_GPIOD_CLK_ENABLE();
635
636
  /*Configure GPIO pin Output Level */
637
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_2 
638
                          |GPIO_PIN_8|GPIO_PIN_9, GPIO_PIN_RESET);
639
640
  /*Configure GPIO pin Output Level */
641
  HAL_GPIO_WritePin(GPIOH, GPIO_PIN_0|GPIO_PIN_1, GPIO_PIN_RESET);
642
643
  /*Configure GPIO pin Output Level */
644
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2|GPIO_PIN_3|GPIO_Out_DEBUG_2_Punkt_Pin|GPIO_Out_DEBUG_1_Pin, GPIO_PIN_RESET);
645
646
  /*Configure GPIO pins : PC13 PC14 PC15 PC2 
647
                           PC8 PC9 */
648
  GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_2 
649
                          |GPIO_PIN_8|GPIO_PIN_9;
650
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
651
  GPIO_InitStruct.Pull = GPIO_NOPULL;
652
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
653
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
654
655
  /*Configure GPIO pins : PH0 PH1 */
656
  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
657
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
658
  GPIO_InitStruct.Pull = GPIO_NOPULL;
659
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
660
  HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
661
662
  /*Configure GPIO pins : PC4 PC5 PC12 */
663
  GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_12;
664
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
665
  GPIO_InitStruct.Pull = GPIO_NOPULL;
666
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
667
668
  /*Configure GPIO pins : PB2 PB3 GPIO_Out_DEBUG_2_Punkt_Pin GPIO_Out_DEBUG_1_Pin */
669
  GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3|GPIO_Out_DEBUG_2_Punkt_Pin|GPIO_Out_DEBUG_1_Pin;
670
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
671
  GPIO_InitStruct.Pull = GPIO_NOPULL;
672
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
673
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
674
675
  /*Configure GPIO pins : PB10 PB11 PB12 PB13 
676
                           PB15 */
677
  GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13 
678
                          |GPIO_PIN_15;
679
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
680
  GPIO_InitStruct.Pull = GPIO_NOPULL;
681
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
682
683
  /*Configure GPIO pins : PA10 PA11 PA12 */
684
  GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12;
685
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
686
  GPIO_InitStruct.Pull = GPIO_NOPULL;
687
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
688
689
  /*Configure GPIO pin : PD2 */
690
  GPIO_InitStruct.Pin = GPIO_PIN_2;
691
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
692
  GPIO_InitStruct.Pull = GPIO_NOPULL;
693
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
694
695
}
696
697
/* USER CODE BEGIN 4 */
698
699
// HAUPTIMER
700
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *ht)
701
{
702
  if(ht == &htim10)
703
  {
704
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
705
    
706
    
707
    
708
    
709
710
    
711
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
712
  }
713
}  
714
715
716
717
718
719
/* USER CODE END 4 */
720
721
/**
722
  * @brief  This function is executed in case of error occurrence.
723
  * @param  None
724
  * @retval None
725
  */
726
void Error_Handler(void)
727
{
728
  /* USER CODE BEGIN Error_Handler */
729
  /* User can add his own implementation to report the HAL error return state */
730
  while(1) 
731
  {
732
  }
733
  /* USER CODE END Error_Handler */ 
734
}
735
736
#ifdef USE_FULL_ASSERT
737
738
/**
739
   * @brief Reports the name of the source file and the source line number
740
   * where the assert_param error has occurred.
741
   * @param file: pointer to the source file name
742
   * @param line: assert_param error line source number
743
   * @retval None
744
   */
745
void assert_failed(uint8_t* file, uint32_t line)
746
{
747
  /* USER CODE BEGIN 6 */
748
  /* User can add his own implementation to report the file name and line number,
749
    ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
750
  /* USER CODE END 6 */
751
752
}
753
754
#endif
755
756
/**
757
  * @}
758
  */ 
759
760
/**
761
  * @}
762
*/ 
763
764
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

von Traubensaft .. (increasingcurrant)


Lesenswert?

Mitlesa schrieb im Beitrag #4897205:
> Traubensaft .. schrieb:
>> HAL_SPI_Receive_IT(...) wird NSS nicht bedient.
>
> Schau in der Dokumentation nach warum das so ist, dort
> wird es schon beschrieben sein

Und das Argument "faule Studenten scheuen sich vor Eigenrecherche in 
technischen Unterlagen" zieht nicht. Das Dokument, das ich zu Rate 
gezogen habe ist die "Description of STM32F4xx HAL drivers". 
http://www.st.com/content/ccc/resource/technical/document/user_manual/2f/71/ba/b8/75/54/47/cf/DM00105879.pdf/files/DM00105879.pdf/jcr:content/translations/en.DM00105879.pdf


Dort finde ich zwar auf Seite 826 zwar die Funktionsdeklaration von 
HAL_SPI_Receive_IT, jedoch keinen Hinweis auf Hardware-NSS. Wenn du mir 
ein anderespassendes Dokument verlinken könntest, würde ich es gerne 
lesen.

von Mitlesa (Gast)


Lesenswert?

Traubensaft .. schrieb:
> wenn ich 760 Zeilen Code hier hinklatsche. Zu verheimlichen habe ich
> natürlich nichts.

>>Wichtige Regeln - erst lesen, dann posten!
>>
>> Groß- und Kleinschreibung verwenden
>> Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
---^^^^^^^^^^^^^^^^^^^^

So so, ein leeres Projekt mit 760 Zeilen Code. Wichtige Hinweise
die bei jedem Posting-Formular angegeben werden kannst du auch
nicht lesen ....

Traubensaft .. schrieb:
> Ich habe ein neues, leeres Projekt angelegt um die Funktionalität
> isoliert zu testen. Mit der Funktion HAL_SPI_Receive(...) funktioniert
> alles soweit.

Ich schaue mir deinen Wust an Initialisierungen nicht durch.

Wenn du es nicht schaffst dein Problem wirklich isoliert
darzustellen dann eben nicht.

von Traubensaft .. (increasingcurrant)


Angehängte Dateien:

Lesenswert?

Hi,

dann habe ich gute Neuigkeiten :) Ich konnte das Problem eingrenzen. 
Folgendes: Ich habe ein neues Projekt eingerichtet und 
Schritt-für-Schritt an meinen Stand angeglichen. Bei der 
Clock-Konfiguration funktionierte SPI dann nicht mehr korrekt:

Bei hohen Baudraten wird NSS durch das Hardware-SPI bedient. Sinkt die 
Baudrate unter 1 MHz geht es nicht mehr. Am Code ändere ich dabei 
garnichts. Nur den Pre-Scaler vom SPI im CubeMX.


Hast du eine Idee wie das kommen kann?

von Mitlesa (Gast)


Lesenswert?

Wo sind deine Interrupt-Handler?

Wenn man Interrupts konfiguriert bzw Interrupt-Funktionalität
aufruft muss man üblicherweise auch Interrupt-Handler
bereitstellen. Ich finde die nicht.

Ich kenne die HAL-Codegenerierung nicht. Macht das HAL alles
automatisch im Hintergrund, gibt es dafür einen "HAL Kernel"?
Das wäre ja ein wahrer WunderAutomat.

von Traubensaft .. (increasingcurrant)


Lesenswert?

Mitlesa schrieb:
> Wenn man Interrupts konfiguriert bzw Interrupt-Funktionalität
> aufruft muss man üblicherweise auch Interrupt-Handler
> bereitstellen.

Nicht zwangsläufig. CubeMX generiert einem leere Handler mit 
__weak-Symbol in der "stm32f4xx_hal_spi.c".

Es macht also keinen Unterschied ob diese in der "main.c" vorhanden sind 
oder nicht. Jedenfalls konnte ich keinen Unterschied feststellen. Unter 
1 MBaud funktioniert NSS nicht.

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.