Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.60/15: Рейтинг темы: голосов - 15, средняя оценка - 4.60
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1

Два Nucleo board'a по SPI

09.07.2018, 22:35. Показов 3579. Ответов 41
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
У меня есть два одинаковых Нуклео борда. Хочу их соединить по SPI. Но сначала непонятно как их прошить на одном ноуте так, чтобы один был мастер, другой слейв. Для каждого нужно сделать два отдельных проекта и запустить на каждом свой. Причем, что EWARM путается какой куда прожигать. Можете помочь ?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
09.07.2018, 22:35
Ответы с готовыми решениями:

SPI на одной плате Nucleo
Здравствуйте все ! Одним словом, мне не удалось связать две платы Нуклео с помощью SPI. Пробую теперь сделать это на одной плате, где...

Проблема с передачей по spi stm32 Nucleo-L053R8
Здравствуйте, что-то никак не получается у меня с первого раза завести интерфейсы арма. На этот раз взялся за spi. Плата stm32...

Два дисплея на ST7920 по SPI
Доброго времени суток! Подскажите, можно ли подключить два дисплея 128х64 по SPI звездой, то есть ,чтобы на них выводилась разная...

41
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1
21.07.2018, 12:40  [ТС]
Студворк — интернет-сервис помощи студентам
Эммм... Так наверное можно сделать, когда работаешь с одним бордом и, скажем, SPI1 - это мастер и SPI2 - это слейв. Тогда да, все внутри одного проекта и так можно сделать.

Но у меня два борда, один Nucleo-L152RE и другой Nucleo-f411re. И я хочу связать их по SPI. Получается, что у меня два разных проекта, сначала я запускаю один проект, скажем для слейва, потом другой проект - для мастера. И у меня по любому получается задержка больше 3 секунд.

Или я чего то не понял...

Добавлено через 10 минут
Да ! Получилось ! Огромное спасибо !
0
87 / 86 / 4
Регистрация: 20.11.2016
Сообщений: 271
21.07.2018, 13:03
max_sk,
неужто все?
имелось в виду что платы выполняют уже готовую и отлаженную программу и работают без среды отладки, и питание подается на обе платы одновременно.

Логический анализатор не мешало бы иметь в будущем. Пригодится еще если будешь заниматься дальше программированием
1
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1
21.07.2018, 14:12  [ТС]
Нет, не получилось... Может частоты шин обеих бордов должны совпадать ? В качестве предположения ? А то в Кубе у меня разные частоты могут быть...

Добавлено через 3 минуты
Слейв действительно выдает иногда правильные значения, но потом снова сьезжает на мусор...

Добавлено через 45 минут
max_sk,*
неужто все?
И главное, что получится же.

Но через месяц или несколько. А на работе нужно за пару дней...
0
87 / 86 / 4
Регистрация: 20.11.2016
Сообщений: 271
21.07.2018, 17:18
max_sk, ну без кода очень сложно гадать где искать ошибку((
плюс еще разные процы...
1
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1
21.07.2018, 18:42  [ТС]
Процы я могу взять одинаковые. У меня этих Nucleo бордов уже три штуки. )))

На днях выложу код, хотя он очень примитивный...
0
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1
29.07.2018, 20:20  [ТС]
После того, как отремонтировал вторую Nucleo-L152RE плату и теперь она выводит инфу на PuTTY, возвращаюсь к этой теме. Выкладываю код. В принципе, мне надо решить, как синхронизировать обе платы, мастер на передачу и слейв на прием, так чтобы слейв принимал без мусора. У слейва периодически проскакивают правильные значения, но потом он сьезжает на мусор.

Вот код:

Это мастер:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void prvSPITask ( void *pvParameters )
{
uint8_t SendBuf[]="SPI 123456";
uint8_t ReceiveBuf[11];
int count;
 
    //hspi1.Instance->CR1 |= SPI_CR1_MSTR; // Master selection
 
    while(1){
      
        HAL_Delay(250);
 
        HAL_UART_Transmit( &huart2, "Send SPI 123456\r\n", 17, 100);
        
        HAL_SPI_Transmit( &hspi1, SendBuf, 11, 100);
             
        HAL_UART_Transmit( &huart2, "Received : ", 11, 100);
        HAL_UART_Transmit( &huart2, ReceiveBuf, 11, 100);
        HAL_UART_Transmit( &huart2, "\r\n", 2, 100);
        
    }
  
}
Это слейв:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
int main(void)
{
  /* USER CODE BEGIN 1 */
uint8_t SendBuf[]="Slave Send";
uint8_t ReceiveBuf[11];
  /* USER CODE END 1 */
 
  /* MCU Configuration----------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USORT2_UART_Init();
  MX_SPI1_Init();
  /* USER CODE BEGIN 2 */
  
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
 
  /* USER CODE END WHILE */
 
  /* USER CODE BEGIN 3 */
    HAL_UART_Transmit( &huart2, "Reseiving from Master\r\n", 22, 100);
    
    HAL_SPI_Receive( &hspi1, ReceiveBuf, 11, 100);
    
    HAL_UART_Transmit( &huart2, "Received : ", 11, 100);
    HAL_UART_Transmit( &huart2, ReceiveBuf, 11, 100);
    HAL_UART_Transmit( &huart2, "\r\n", 2, 100);
    
  }
  /* USER CODE END 3 */
 
}
0
87 / 86 / 4
Регистрация: 20.11.2016
Сообщений: 271
30.07.2018, 22:47
недавно изучал режим DMA и набросал аналогичный код без функций HAL под STM32F407.
Код в работе не проверял, т.к. у меня пока одна плата)
Писал в среде IAR. Для вывода на экран используется функция printf

Код Мастера
main.c

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include "main.h"
#include "stm32f4xx_hal.h"
 
/* USER CODE BEGIN Includes */
 
/* USER CODE END Includes */
 
/* Private variables ---------------------------------------------------------*/
SPI_HandleTypeDef hspi1;
DMA_HandleTypeDef hdma_spi1_rx;
DMA_HandleTypeDef hdma_spi1_tx;
 
UART_HandleTypeDef huart1;
 
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
#define DMA2_S0CR   (__IO uint32_t *)(0x40026400+0x0010)
#define DMA2_S0NDTR (__IO uint32_t *)(0x40026400+0x0014)
#define DMA2_S0PAR  (__IO uint32_t *)(0x40026400+0x0018)
#define DMA2_S0M0AR (__IO uint32_t *)(0x40026400+0x001C)
 
 
#define DMA2_S3CR   (__IO uint32_t *)(0x40026400+0x0058)
#define DMA2_S3NDTR (__IO uint32_t *)(0x40026400+0x005C)
#define DMA2_S3PAR  (__IO uint32_t *)(0x40026400+0x0060)
#define DMA2_S3M0AR (__IO uint32_t *)(0x40026400+0x0064)
 
 
 
uint8_t SendBuf[]="SPI 123456";
uint8_t ReceiveBuf[11];
 
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void Error_Handler(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_SPI1_Init(void);
static void MX_USART1_UART_Init(void);
 
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
 
// Stream of Receiver 
void DMA2_Stream0_init(void)
{
 
*DMA2_S0PAR=(uint32_t)&(SPI1->DR);  // write address of source
*DMA2_S0M0AR=(uint32_t)ReceiveBuf;
*DMA2_S0NDTR= 11;   // write number of data
 
 
// setting of SxCR
*DMA2_S0CR|= (DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_0 );  // canal 3
*DMA2_S0CR|= (DMA_SxCR_MINC);     // Memory increment mode
*DMA2_S0CR|= (DMA_SxCR_TCIE);     // enable interrupt of transfer completed
}
 
 
// Stream of Transmitter
void DMA2_Stream3_init(void)  
{
*DMA2_S3PAR=(uint32_t)&(SPI1->DR);  // write address of destination
*DMA2_S3M0AR=(uint32_t)SendBuf;
*DMA2_S3NDTR=  11;   // write number of data
 
 
// setting of SxCR
*DMA2_S3CR|= (DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_0);  // canal 3
*DMA2_S3CR|= (DMA_SxCR_DIR_0);     // memory-to-peripheral
*DMA2_S3CR|= (DMA_SxCR_MINC);     // Memory increment mode
*DMA2_S3CR|= (DMA_SxCR_TCIE);     // enable interrupt of transfer completed
}
 
 
/* USER CODE END PFP */
 
/* USER CODE BEGIN 0 */
 
/* USER CODE END 0 */
 
int main(void)
{
 
  /* USER CODE BEGIN 1 */
 
  /* USER CODE END 1 */
 
  /* MCU Configuration----------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_SPI1_Init();
  MX_USART1_UART_Init();
 
  /* USER CODE BEGIN 2 */
  
DMA2_Stream3_init();
DMA2_Stream0_init();
 
HAL_Delay(250);    // pause for Master
 
SPI1->CR2|= (SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);   // enable DMA mode
SPI1->CR1|= (SPI_CR1_SPE );     // enable SPI
 
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    
*DMA2_S3CR|= (DMA_SxCR_EN);       // start stream SPI_Tx
*DMA2_S0CR|= (DMA_SxCR_EN);       // start stream SPI_Rx
 
printf ("%s\n", ReceiveBuf);        // out received string
 
HAL_Delay(1000);
 
 
  /* USER CODE END WHILE */
 
  /* USER CODE BEGIN 3 */
 
  }
  /* USER CODE END 3 */
 
}
stm32f4xx_it

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
void DMA2_Stream0_IRQHandler(void)   // Stream of Receiver
{
  /* USER CODE BEGIN DMA2_Stream0_IRQn 0 */
  *DMA2_S0CR&= ~(DMA_SxCR_EN);     // stop of stream
  if (DMA2->LISR & LISR_TCIF0)     // if flag TCIF0  set
  DMA2->LIFCR|= DMA_LIFCR_CTCIF0;  // reset flag interrupt stream transfer complete
 
  /* USER CODE END DMA2_Stream0_IRQn 0 */
  
  /* USER CODE BEGIN DMA2_Stream0_IRQn 1 */
 
  /* USER CODE END DMA2_Stream0_IRQn 1 */
}
 
/**
* @brief This function handles DMA2 stream3 global interrupt.
*/
void DMA2_Stream3_IRQHandler(void)  // Stream of Transmitter
{
  /* USER CODE BEGIN DMA2_Stream3_IRQn 0 */
  *DMA2_S3CR&= ~(DMA_SxCR_EN);     // stop of stream
  if (DMA2->LISR & LISR_TCIF3)     // if flag TCIF3  set
  DMA2->LIFCR|= DMA_LIFCR_CTCIF3;  // reset flag interrupt stream transfer complete
  
 
  /* USER CODE END DMA2_Stream3_IRQn 0 */
  
  /* USER CODE BEGIN DMA2_Stream3_IRQn 1 */
 
  /* USER CODE END DMA2_Stream3_IRQn 1 */
}
Добавлено через 21 минуту
код для slave вроде пишется аналогично)
1
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1
31.07.2018, 16:34  [ТС]
Radikal_78, спасибо, буду разбираться...
0
87 / 86 / 4
Регистрация: 20.11.2016
Сообщений: 271
21.08.2018, 12:18
Дождался с али второй такой же платы EU STM32 M4 на процессоре STM32F407ZGT6 и довел свою программу до ума.
Обе платы работают в режиме DMA.
Каждая плата сравнивает свой приемный буфер с тестовым массивом, если массивы идентичны, то переключается LED1, в противном случае загорается LED2. Потом приемный буфер очищается перед принятием очередного пакета данных.

(хотел бы я знать, каким местом думал проектировщик такой платы ставя рядом два ОДИНАКОВЫХ ГОЛУБЫХ светодиода???
Приходится иногда нагибаться к плате, чтобы узнать точнее, какой именно светодиод горит)

Код "мастера" файл main.c
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f4xx_hal.h"
 
/* USER CODE BEGIN Includes */
 
/* USER CODE END Includes */
 
/* Private variables ---------------------------------------------------------*/
SPI_HandleTypeDef hspi1;
DMA_HandleTypeDef hdma_spi1_rx;
DMA_HandleTypeDef hdma_spi1_tx;
 
UART_HandleTypeDef huart1;
 
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
#define DMA2_S0CR   (__IO uint32_t *)(0x40026400+0x0010)
#define DMA2_S0NDTR (__IO uint32_t *)(0x40026400+0x0014)
#define DMA2_S0PAR  (__IO uint32_t *)(0x40026400+0x0018)
#define DMA2_S0M0AR (__IO uint32_t *)(0x40026400+0x001C)
 
 
#define DMA2_S3CR   (__IO uint32_t *)(0x40026400+0x0058)
#define DMA2_S3NDTR (__IO uint32_t *)(0x40026400+0x005C)
#define DMA2_S3PAR  (__IO uint32_t *)(0x40026400+0x0060)
#define DMA2_S3M0AR (__IO uint32_t *)(0x40026400+0x0064)
 
#define Bufer_Size 10
 
#define LED1    GPIO_PIN_0 //  PC0
#define LED2    GPIO_PIN_3 //  PD3
 
 
uint8_t SendBuf[]="SPI 123456";
uint8_t ReceiveBuf[Bufer_Size];
uint8_t Test[]="Slave Send";
 
uint8_t Flag1=0, Flag2=0;
uint32_t Temp;
 
 
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void Error_Handler(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_SPI1_Init(void);
static void MX_USART1_UART_Init(void);
 
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
 
// Stream of Receiver 
void DMA2_Stream0_init(void)
{
 
*DMA2_S0PAR=(uint32_t)&(SPI1->DR);  // write address of source
*DMA2_S0M0AR=(uint32_t)ReceiveBuf;
*DMA2_S0NDTR= Bufer_Size;   // write number of data
 
 
// setting of SxCR
*DMA2_S0CR|= (DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_0 );  // canal 3
*DMA2_S0CR|= (DMA_SxCR_MINC);     // Memory increment mode
*DMA2_S0CR|= (DMA_SxCR_TCIE);     // enable interrupt of transfer completed
}
 
 
// Stream of Transmitter
void DMA2_Stream3_init(void)  
{
*DMA2_S3PAR=(uint32_t)&(SPI1->DR);  // write address of destination
*DMA2_S3M0AR=(uint32_t)SendBuf;
*DMA2_S3NDTR=  Bufer_Size;   // write number of data
 
 
// setting of SxCR
*DMA2_S3CR|= (DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_0);  // canal 3
*DMA2_S3CR|= (DMA_SxCR_DIR_0);     // memory-to-peripheral
*DMA2_S3CR|= (DMA_SxCR_MINC);     // Memory increment mode
*DMA2_S3CR|= (DMA_SxCR_TCIE);     // enable interrupt of transfer completed
}
 
static int Buffercmp(uint8_t *pBuffer1, uint8_t *pBuffer2, uint16_t BufferLength)
 
{
  while (BufferLength--)
  {
    if (*pBuffer1 != *pBuffer2)
    {
      return 0;
    }
    pBuffer1++;
    pBuffer2++;
  }  
  return 1;
}
 
 
void BufferClear(void)
{
  for (int i=0; i<Bufer_Size; i++)
  { 
    ReceiveBuf[i]=0;
  }
}
 
 
/* USER CODE END PFP */
 
/* USER CODE BEGIN 0 */
 
/* USER CODE END 0 */
 
int main(void)
{
 
  /* USER CODE BEGIN 1 */
 
  /* USER CODE END 1 */
 
  /* MCU Configuration----------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_SPI1_Init();
  MX_USART1_UART_Init();
 
  /* USER CODE BEGIN 2 */
  
//DMA2_Stream3_init();
//DMA2_Stream0_init();
 
HAL_Delay(250);    // pause for Master
 
SPI1->CR2|= (SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);   // enable DMA mode
SPI1->CR1|= (SPI_CR1_SPE );     // enable SPI
 
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
DMA2_Stream3_init();
DMA2_Stream0_init();
 
 Flag1=0; Flag2=0;   
*DMA2_S3CR|= (DMA_SxCR_EN);       // start stream SPI_Tx
*DMA2_S0CR|= (DMA_SxCR_EN);       // start stream SPI_Rx
 
 
HAL_Delay(1350); //
//Temp=*DMA2_S3NDTR;
//printf ("DMA2_S3NDTR %X\n", Temp); 
//Temp=*DMA2_S0NDTR;
//printf ("DMA2_S0NDTR %X\n", Temp); 
 
while (!(Flag1 && Flag2)) {};
 
  /* USER CODE END WHILE */
 
  /* USER CODE BEGIN 3 */
 
if (Buffercmp( Test, ReceiveBuf, Bufer_Size))
{
   HAL_GPIO_TogglePin(GPIOC, LED1);
  }
 else 
 { 
  HAL_GPIO_WritePin(GPIOD, LED2, GPIO_PIN_RESET);
  }
//printf ("%s\n", ReceiveBuf);        // out received string
BufferClear();  // clear buffer
//HAL_Delay(1350); //
  
  }
 
  /* USER CODE END 3 */
 
}
 
/** System Clock Configuration
*/
void SystemClock_Config(void)
{
 
  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
 
    /**Configure the main internal regulator output voltage 
    */
  __HAL_RCC_PWR_CLK_ENABLE();
 
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
 
    /**Initializes the CPU, AHB and APB busses clocks 
    */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = 16;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
 
    /**Initializes the CPU, AHB and APB busses clocks 
    */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
 
    /**Configure the Systick interrupt time 
    */
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
 
    /**Configure the Systick 
    */
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
 
  /* SysTick_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
 
/* SPI1 init function */
static void MX_SPI1_Init(void)
{
 
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }
 
}
 
/* USART1 init function */
static void MX_USART1_UART_Init(void)
{
 
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
 
}
 
/** 
  * Enable DMA controller clock
  */
static void MX_DMA_Init(void) 
{
  /* DMA controller clock enable */
  __HAL_RCC_DMA2_CLK_ENABLE();
 
  /* DMA interrupt init */
  /* DMA2_Stream0_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
  /* DMA2_Stream3_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
 
}
 
/** Configure pins as 
        * Analog 
        * Input 
        * Output
        * EVENT_OUT
        * EXTI
*/
static void MX_GPIO_Init(void)
{
 
   GPIO_InitTypeDef GPIO_InitStruct;
 
  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_SET);
 
  /*Configure GPIO pin : LED1_Pin */
  GPIO_InitStruct.Pin = LED1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LED1_GPIO_Port, &GPIO_InitStruct);
 
  /*Configure GPIO pin : LED2_Pin */
  GPIO_InitStruct.Pin = LED2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LED2_GPIO_Port, &GPIO_InitStruct);
 
}
 
 
/* USER CODE BEGIN 4 */
 
/* USER CODE END 4 */
 
/**
  * @brief  This function is executed in case of error occurrence.
  * @param  None
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler */
  /* User can add his own implementation to report the HAL error return state */
  while(1) 
  {
  }
  /* USER CODE END Error_Handler */ 
}
 
#ifdef USE_FULL_ASSERT
 
/**
   * @brief Reports the name of the source file and the source line number
   * where the assert_param error has occurred.
   * @param file: pointer to the source file name
   * @param line: assert_param error line source number
   * @retval None
   */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
    ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
 
}
код "мастера" файл stm32f4xx_it.c

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"
#include "stm32f4xx.h"
#include "stm32f4xx_it.h"
 
/* USER CODE BEGIN 0 */
#define LISR_TCIF0 0x00000020
#define LISR_TCIF3 0x08000000
 
#define DMA2_S0CR   (__IO uint32_t *)(0x40026400+0x0010)
#define DMA2_S3CR   (__IO uint32_t *)(0x40026400+0x0058)
 
extern uint8_t Flag1, Flag2;
 
 
/* USER CODE END 0 */
 
/* External variables --------------------------------------------------------*/
extern DMA_HandleTypeDef hdma_spi1_rx;
extern DMA_HandleTypeDef hdma_spi1_tx;
 
/******************************************************************************/
/*            Cortex-M4 Processor Interruption and Exception Handlers         */ 
/******************************************************************************/
 
/**
* @brief This function handles Non maskable interrupt.
*/
void NMI_Handler(void)
{
  /* USER CODE BEGIN NonMaskableInt_IRQn 0 */
 
  /* USER CODE END NonMaskableInt_IRQn 0 */
  /* USER CODE BEGIN NonMaskableInt_IRQn 1 */
 
  /* USER CODE END NonMaskableInt_IRQn 1 */
}
 
/**
* @brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
  /* USER CODE BEGIN HardFault_IRQn 0 */
 
  /* USER CODE END HardFault_IRQn 0 */
  while (1)
  {
  }
  /* USER CODE BEGIN HardFault_IRQn 1 */
 
  /* USER CODE END HardFault_IRQn 1 */
}
 
/**
* @brief This function handles Memory management fault.
*/
void MemManage_Handler(void)
{
  /* USER CODE BEGIN MemoryManagement_IRQn 0 */
 
  /* USER CODE END MemoryManagement_IRQn 0 */
  while (1)
  {
  }
  /* USER CODE BEGIN MemoryManagement_IRQn 1 */
 
  /* USER CODE END MemoryManagement_IRQn 1 */
}
 
/**
* @brief This function handles Pre-fetch fault, memory access fault.
*/
void BusFault_Handler(void)
{
  /* USER CODE BEGIN BusFault_IRQn 0 */
 
  /* USER CODE END BusFault_IRQn 0 */
  while (1)
  {
  }
  /* USER CODE BEGIN BusFault_IRQn 1 */
 
  /* USER CODE END BusFault_IRQn 1 */
}
 
/**
* @brief This function handles Undefined instruction or illegal state.
*/
void UsageFault_Handler(void)
{
  /* USER CODE BEGIN UsageFault_IRQn 0 */
 
  /* USER CODE END UsageFault_IRQn 0 */
  while (1)
  {
  }
  /* USER CODE BEGIN UsageFault_IRQn 1 */
 
  /* USER CODE END UsageFault_IRQn 1 */
}
 
/**
* @brief This function handles System service call via SWI instruction.
*/
void SVC_Handler(void)
{
  /* USER CODE BEGIN SVCall_IRQn 0 */
 
  /* USER CODE END SVCall_IRQn 0 */
  /* USER CODE BEGIN SVCall_IRQn 1 */
 
  /* USER CODE END SVCall_IRQn 1 */
}
 
/**
* @brief This function handles Debug monitor.
*/
void DebugMon_Handler(void)
{
  /* USER CODE BEGIN DebugMonitor_IRQn 0 */
 
  /* USER CODE END DebugMonitor_IRQn 0 */
  /* USER CODE BEGIN DebugMonitor_IRQn 1 */
 
  /* USER CODE END DebugMonitor_IRQn 1 */
}
 
/**
* @brief This function handles Pendable request for system service.
*/
void PendSV_Handler(void)
{
  /* USER CODE BEGIN PendSV_IRQn 0 */
 
  /* USER CODE END PendSV_IRQn 0 */
  /* USER CODE BEGIN PendSV_IRQn 1 */
 
  /* USER CODE END PendSV_IRQn 1 */
}
 
/**
* @brief This function handles System tick timer.
*/
void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */
 
  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  HAL_SYSTICK_IRQHandler();
  /* USER CODE BEGIN SysTick_IRQn 1 */
 
  /* USER CODE END SysTick_IRQn 1 */
}
 
/******************************************************************************/
/* STM32F4xx Peripheral Interrupt Handlers                                    */
/* Add here the Interrupt Handlers for the used peripherals.                  */
/* For the available peripheral interrupt handler names,                      */
/* please refer to the startup file (startup_stm32f4xx.s).                    */
/******************************************************************************/
 
/**
* @brief This function handles DMA2 stream0 global interrupt.
*/
void DMA2_Stream0_IRQHandler(void)   // Stream of Receiver
{
  /* USER CODE BEGIN DMA2_Stream0_IRQn 0 */
  *DMA2_S0CR&= ~(DMA_SxCR_EN);     // stop of stream
  if (DMA2->LISR & LISR_TCIF0)     // if flag TCIF0  set
  DMA2->LIFCR|= DMA_LIFCR_CTCIF0;  // reset flag interrupt stream transfer complete
  Flag1=1;
 
  /* USER CODE END DMA2_Stream0_IRQn 0 */
  
  /* USER CODE BEGIN DMA2_Stream0_IRQn 1 */
 
  /* USER CODE END DMA2_Stream0_IRQn 1 */
}
 
/**
* @brief This function handles DMA2 stream3 global interrupt.
*/
void DMA2_Stream3_IRQHandler(void)  // Stream of Transmitter
{
  /* USER CODE BEGIN DMA2_Stream3_IRQn 0 */
  *DMA2_S3CR&= ~(DMA_SxCR_EN);     // stop of stream
  if (DMA2->LISR & LISR_TCIF3)     // if flag TCIF3  set
  DMA2->LIFCR|= DMA_LIFCR_CTCIF3;  // reset flag interrupt stream transfer complete
  Flag2=1;
 
  /* USER CODE END DMA2_Stream3_IRQn 0 */
  
  /* USER CODE BEGIN DMA2_Stream3_IRQn 1 */
 
  /* USER CODE END DMA2_Stream3_IRQn 1 */
}
1
87 / 86 / 4
Регистрация: 20.11.2016
Сообщений: 271
21.08.2018, 12:18
код для Slave файл main.c

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f4xx_hal.h"
 
/* USER CODE BEGIN Includes */
 
/* USER CODE END Includes */
 
/* Private variables ---------------------------------------------------------*/
SPI_HandleTypeDef hspi1;
DMA_HandleTypeDef hdma_spi1_rx;
DMA_HandleTypeDef hdma_spi1_tx;
 
UART_HandleTypeDef huart1;
 
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
#define DMA2_S0CR   (__IO uint32_t *)(0x40026400+0x0010)
#define DMA2_S0NDTR (__IO uint32_t *)(0x40026400+0x0014)
#define DMA2_S0PAR  (__IO uint32_t *)(0x40026400+0x0018)
#define DMA2_S0M0AR (__IO uint32_t *)(0x40026400+0x001C)
 
 
#define DMA2_S3CR   (__IO uint32_t *)(0x40026400+0x0058)
#define DMA2_S3NDTR (__IO uint32_t *)(0x40026400+0x005C)
#define DMA2_S3PAR  (__IO uint32_t *)(0x40026400+0x0060)
#define DMA2_S3M0AR (__IO uint32_t *)(0x40026400+0x0064)
 
#define Bufer_Size 10
 
#define LED1    GPIO_PIN_0 //  PC0
#define LED2    GPIO_PIN_3 //  PD3
 
 
 
 
uint8_t SendBuf[]="Slave Send";
uint8_t ReceiveBuf[Bufer_Size];
uint8_t Test[]="SPI 123456";
 
uint8_t Flag1=0, Flag2=0;
 
 
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void Error_Handler(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_SPI1_Init(void);
static void MX_USART1_UART_Init(void);
 
// Stream of Receiver 
void DMA2_Stream0_init(void)
{
*DMA2_S0PAR=(uint32_t)&(SPI1->DR);  // write address of source
*DMA2_S0M0AR=(uint32_t)ReceiveBuf;
*DMA2_S0NDTR= Bufer_Size;   // write number of data
 
 
// setting of SxCR
*DMA2_S0CR|= (DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_0 );  // canal 3
*DMA2_S0CR|= (DMA_SxCR_MINC);     // Memory increment mode
*DMA2_S0CR|= (DMA_SxCR_TCIE);     // enable interrupt of transfer completed
}
 
 
// Stream of Transmitter
void DMA2_Stream3_init(void)  
{
*DMA2_S3PAR=(uint32_t)&(SPI1->DR);  // write address of destination
*DMA2_S3M0AR=(uint32_t)SendBuf;
*DMA2_S3NDTR= Bufer_Size;   // write number of data
 
 
// setting of SxCR
*DMA2_S3CR|= (DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_0);  // canal 3
*DMA2_S3CR|= (DMA_SxCR_DIR_0);     // memory-to-peripheral
*DMA2_S3CR|= (DMA_SxCR_MINC);     // Memory increment mode
*DMA2_S3CR|= (DMA_SxCR_TCIE);     // enable interrupt of transfer completed
}
 
 
static int Buffercmp(uint8_t *pBuffer1, uint8_t *pBuffer2, uint16_t BufferLength)
 
{
  while (BufferLength--)
  {
    if (*pBuffer1 != *pBuffer2)
    {
      return 0;
    }
    pBuffer1++;
    pBuffer2++;
  }  
  return 1;
}
 
 
void BufferClear(void)
{
  for (int i=0; i<Bufer_Size; i++)
  { 
    ReceiveBuf[i]=0;
  }
}
    
 
 
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
 
/* USER CODE END PFP */
 
/* USER CODE BEGIN 0 */
 
/* USER CODE END 0 */
 
int main(void)
{
 
  /* USER CODE BEGIN 1 */
 
  /* USER CODE END 1 */
 
  /* MCU Configuration----------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_SPI1_Init();
  MX_USART1_UART_Init();
 
  /* USER CODE BEGIN 2 */
//DMA2_Stream3_init();
//DMA2_Stream0_init();
 
//HAL_Delay(250);    // pause 
 
SPI1->CR2|= (SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);   // enable DMA mode
SPI1->CR1|= (SPI_CR1_SPE );     // enable SPI
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
 Flag1=0; Flag2=0;
DMA2_Stream3_init();
DMA2_Stream0_init();
*DMA2_S3CR|= (DMA_SxCR_EN);       // start stream SPI_Tx
*DMA2_S0CR|= (DMA_SxCR_EN);       // start stream SPI_Rx
 
while (!(Flag1 && Flag2)) {};
 
  /* USER CODE END WHILE */
 
  /* USER CODE BEGIN 3 */
if (Buffercmp( Test, ReceiveBuf, Bufer_Size))
{
   HAL_GPIO_TogglePin(GPIOC, LED1);
  }
 else 
 { 
  HAL_GPIO_WritePin(GPIOD, LED2, GPIO_PIN_RESET);
  }
//printf ("%s\n", ReceiveBuf);        // out received string
BufferClear();  // clear buffer
 
  }
  /* USER CODE END 3 */
 
}
 
/** System Clock Configuration
*/
void SystemClock_Config(void)
{
 
  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
 
    /**Configure the main internal regulator output voltage 
    */
  __HAL_RCC_PWR_CLK_ENABLE();
 
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
 
    /**Initializes the CPU, AHB and APB busses clocks 
    */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = 16;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
 
    /**Initializes the CPU, AHB and APB busses clocks 
    */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
 
    /**Configure the Systick interrupt time 
    */
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
 
    /**Configure the Systick 
    */
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
 
  /* SysTick_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
 
/* SPI1 init function */
static void MX_SPI1_Init(void)
{
 
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_SLAVE;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }
 
}
 
/* USART1 init function */
static void MX_USART1_UART_Init(void)
{
 
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
 
}
 
/** 
  * Enable DMA controller clock
  */
static void MX_DMA_Init(void) 
{
  /* DMA controller clock enable */
  __HAL_RCC_DMA2_CLK_ENABLE();
 
  /* DMA interrupt init */
  /* DMA2_Stream0_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
  /* DMA2_Stream3_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
 
}
 
/** Configure pins as 
        * Analog 
        * Input 
        * Output
        * EVENT_OUT
        * EXTI
*/
static void MX_GPIO_Init(void)
{
 
  GPIO_InitTypeDef GPIO_InitStruct;
 
  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_SET);
 
  /*Configure GPIO pin : LED1_Pin */
  GPIO_InitStruct.Pin = LED1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LED1_GPIO_Port, &GPIO_InitStruct);
 
  /*Configure GPIO pin : LED2_Pin */
  GPIO_InitStruct.Pin = LED2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LED2_GPIO_Port, &GPIO_InitStruct);
 
}
 
/* USER CODE BEGIN 4 */
 
/* USER CODE END 4 */
 
/**
  * @brief  This function is executed in case of error occurrence.
  * @param  None
  * @retval None
  */
void Error_Handler(void)
{
  
  while(1) 
  {
  }
  /* USER CODE END Error_Handler */ 
}
 
 
void assert_failed(uint8_t* file, uint32_t line)
{
  
 
}
код для Slave файл stm32f4xx_it.c

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"
#include "stm32f4xx.h"
#include "stm32f4xx_it.h"
 
/* USER CODE BEGIN 0 */
#define LISR_TCIF0 0x00000020
#define LISR_TCIF3 0x08000000
 
#define DMA2_S0CR   (__IO uint32_t *)(0x40026400+0x0010)
#define DMA2_S3CR   (__IO uint32_t *)(0x40026400+0x0058)
 
extern uint8_t Flag1, Flag2;
 
/* USER CODE END 0 */
 
/* External variables --------------------------------------------------------*/
extern DMA_HandleTypeDef hdma_spi1_rx;
extern DMA_HandleTypeDef hdma_spi1_tx;
 
/******************************************************************************/
/*            Cortex-M4 Processor Interruption and Exception Handlers         */ 
/******************************************************************************/
 
/**
* @brief This function handles Non maskable interrupt.
*/
void NMI_Handler(void)
{
 
}
 
/**
* @brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
  /* USER CODE BEGIN HardFault_IRQn 0 */
 
  /* USER CODE END HardFault_IRQn 0 */
  while (1)
  {
  }
  /* USER CODE BEGIN HardFault_IRQn 1 */
 
  /* USER CODE END HardFault_IRQn 1 */
}
 
/**
* @brief This function handles Memory management fault.
*/
void MemManage_Handler(void)
{
  /* USER CODE BEGIN MemoryManagement_IRQn 0 */
 
  /* USER CODE END MemoryManagement_IRQn 0 */
  while (1)
  {
  }
  /* USER CODE BEGIN MemoryManagement_IRQn 1 */
 
  /* USER CODE END MemoryManagement_IRQn 1 */
}
 
/**
* @brief This function handles Pre-fetch fault, memory access fault.
*/
void BusFault_Handler(void)
{
  /* USER CODE BEGIN BusFault_IRQn 0 */
 
  /* USER CODE END BusFault_IRQn 0 */
  while (1)
  {
  }
  /* USER CODE BEGIN BusFault_IRQn 1 */
 
  /* USER CODE END BusFault_IRQn 1 */
}
 
 
void UsageFault_Handler(void)
{
  /* USER CODE BEGIN UsageFault_IRQn 0 */
 
  /* USER CODE END UsageFault_IRQn 0 */
  while (1)
  {
  }
  /* USER CODE BEGIN UsageFault_IRQn 1 */
 
  /* USER CODE END UsageFault_IRQn 1 */
}
 
/**
* @brief This function handles System service call via SWI instruction.
*/
void SVC_Handler(void)
{
 
}
 
/**
* @brief This function handles Debug monitor.
*/
void DebugMon_Handler(void)
{
 
}
 
/**
* @brief This function handles Pendable request for system service.
*/
void PendSV_Handler(void)
{
 
}
 
 
void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */
 
  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  HAL_SYSTICK_IRQHandler();
  /* USER CODE BEGIN SysTick_IRQn 1 */
 
  /* USER CODE END SysTick_IRQn 1 */
}
 
 
void DMA2_Stream0_IRQHandler(void)
{
  /* USER CODE BEGIN DMA2_Stream0_IRQn 0 */
  *DMA2_S0CR&= ~(DMA_SxCR_EN);     // stop of stream
  if (DMA2->LISR & LISR_TCIF0)     // if flag TCIF0  set
  DMA2->LIFCR|= DMA_LIFCR_CTCIF0;  // reset flag interrupt stream transfer complete
  Flag1=1;
  /* USER CODE END DMA2_Stream0_IRQn 0 */
  
  /* USER CODE BEGIN DMA2_Stream0_IRQn 1 */
 
  /* USER CODE END DMA2_Stream0_IRQn 1 */
}
 
/**
* @brief This function handles DMA2 stream3 global interrupt.
*/
void DMA2_Stream3_IRQHandler(void)
{
 /* USER CODE BEGIN DMA2_Stream3_IRQn 0 */
  *DMA2_S3CR&= ~(DMA_SxCR_EN);     // stop of stream
  if (DMA2->LISR & LISR_TCIF3)     // if flag TCIF3  set
  DMA2->LIFCR|= DMA_LIFCR_CTCIF3;  // reset flag interrupt stream transfer complete
  Flag2=1;
 
  /* USER CODE END DMA2_Stream3_IRQn 0 */
  
  /* USER CODE BEGIN DMA2_Stream3_IRQn 1 */
 
  /* USER CODE END DMA2_Stream3_IRQn 1 */
}
в конечной версии программ вывод на экран отключен. Выводом на экран увлекаться не стоит. Платы должны работать без компьютера.
Сейчас у меня обе платы перемигиваются светодиодами. Правда, при первоначальной подаче питания иногда на одной плате может загореться светодиод LED2 (ошибка)
Лично для себя тему я считаю закрытой.
Удачи вам автор!
1
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1
01.09.2018, 13:48  [ТС]
Radikal_78, вы пишете :

Каждая плата сравнивает свой приемный буфер с тестовым массивом, если массивы идентичны, то переключается LED1, в противном случае загорается LED2

То есть у вас тоже иногда принимает мусор ? А вообще с какой целью создавался SPI ? По нему можно передавать большие обьемы данных без мусора ?
0
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1
01.09.2018, 13:48  [ТС]
Radikal_78, вы пишете :

Каждая плата сравнивает свой приемный буфер с тестовым массивом, если массивы идентичны, то переключается LED1, в противном случае загорается LED2

То есть у вас тоже иногда принимает мусор ? А вообще с какой целью создавался SPI ? По нему можно передавать большие обьемы данных без мусора ?
0
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1
01.09.2018, 13:52  [ТС]
Radikal_78, вы пишете :

Каждая плата сравнивает свой приемный буфер с тестовым массивом, если массивы идентичны, то переключается LED1, в противном случае загорается LED2

То есть, у вас тоже время от времени принимает мусор ? А вообще, с какой целью создавался SPI ? По нему можно передавать большие объемы данных без мусора ?
0
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1
01.09.2018, 13:52  [ТС]
Radikal_78, вы пишете :

Каждая плата сравнивает свой приемный буфер с тестовым массивом, если массивы идентичны, то переключается LED1, в противном случае загорается LED2

То есть, у вас тоже время от времени принимает мусор ? А вообще, с какой целью создавался SPI ? По нему можно передавать большие объемы данных без мусора ?
0
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1
01.09.2018, 13:53  [ТС]
Radikal_78, вы пишете :

Каждая плата сравнивает свой приемный буфер с тестовым массивом, если массивы идентичны, то переключается LED1, в противном случае загорается LED2

То есть, у вас тоже время от времени принимает мусор ? А вообще, с какой целью создавался SPI ? По нему можно передавать большие объемы данных без мусора ?
0
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1
01.09.2018, 13:54  [ТС]
Radikal_78, вы пишете :

Каждая плата сравнивает свой приемный буфер с тестовым массивом, если массивы идентичны, то переключается LED1, в противном случае загорается LED2

То есть, у вас тоже время от времени принимает мусор ? А вообще, с какой целью создавался SPI ? По нему можно передавать большие объемы данных без мусора ?
0
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1
01.09.2018, 13:55  [ТС]
Radikal_78, вы пишете :

Каждая плата сравнивает свой приемный буфер с тестовым массивом, если массивы идентичны, то переключается LED1, в противном случае загорается LED2

То есть, у вас тоже время от времени принимает мусор ? А вообще, с какой целью создавался SPI ? По нему можно передавать большие объемы данных без мусора ?
0
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1
01.09.2018, 14:06  [ТС]
Radikal_78, вы пишете :

Каждая плата сравнивает свой приемный буфер с тестовым массивом, если массивы идентичны, то переключается LED1, в противном случае загорается LED2

То есть, у вас тоже время от времени принимает мусор ? А вообще, с какой целью создавался SPI ? По нему можно передавать большие объемы данных без мусора ?
0
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1
01.09.2018, 14:06  [ТС]
Radikal_78, вы пишете :

Каждая плата сравнивает свой приемный буфер с тестовым массивом, если массивы идентичны, то переключается LED1, в противном случае загорается LED2

То есть, у вас тоже время от времени принимает мусор ? А вообще, с какой целью создавался SPI ? По нему можно передавать большие объемы данных без мусора ?
0
92 / 19 / 4
Регистрация: 11.04.2015
Сообщений: 1,019
Записей в блоге: 1
10.09.2018, 20:18  [ТС]
Решил разбираться своими силами ( перебарывая лень ). В итоге мне удалось добиться устойчивой передачи от мастера к слейву.

Вот отрывок кода мастера :

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* USER CODE BEGIN 2 */
  
  HAL_Delay(5000);
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1){
  /* USER CODE END WHILE */
 
  /* USER CODE BEGIN 3 */
       __HAL_SPI_ENABLE( &hspi1 );
       HAL_SPI_Transmit( &hspi1, TransmitBuf, 10, 100);
       __HAL_SPI_DISABLE( &hspi1 );
      
  }
  /* USER CODE END 3 */
Вот отрывок кода слейва :

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* USER CODE BEGIN WHILE */
  while (1){
 
  /* USER CODE END WHILE */
 
  /* USER CODE BEGIN 3 */
      HAL_SPI_Receive( &hspi1, ReceiveBuf, 10, 100);
      
      if( (strcmp((char *)ReceiveBuf,"SPI 123456"))==0 ){
          HAL_UART_Transmit( &huart2, "Received : SPI 123456\r\n", 23, 100);
          memset( ReceiveBuf, '\0', sizeof(ReceiveBuf) );
      }
      
  }
  /* USER CODE END 3 */
Теперь бьюсь над взаимной приемо-передачей. Если есть желающие помочь осуществить это, без крутых наворотов, типа DMA, то буду рад вашей помощи. Потому что простая замена команд HAL_SPI_Receive() и HAL_SPI_Transmit() на HAL_SPI_TransmitReceive() тупо не работает.

Добавлено через 3 часа 47 минут
Оказывается, что вдобавок ко всему у меня еще контакт в проводах пропадает. Изза этого тоже приходит мусор... :-(
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
10.09.2018, 20:18

Две платы Нуклео по SPI. Дубль два
Доброго времени суток всем ! Я скачал образцы от производителя ( библиотека STM32CubeL1 ) и попробовал запустить пример для SPI ( режимы...

Как, используя CPLD, можно состыковать два мастер-устройства SPI
Здравствуйте! Условие задачи: Есть 2 устройства, которые работают только в режиме мастер SPI. Нужно организовать обмен данными между...

ILI9341 SPI DMA, SPI, UART библиотеки
Доброго времени, форумчане... Посоветуйте библиотек плиз... 0) Либа для работы с контроллером по типу HAL (чисто ваше мнение какая вам...

SPI Flash 25q128 как SD в SPI mode ?
ну задача использовать spi флешки вместо sd карт. Как это зделать? Будет ли работать если spi флеху просто припаять и вставить в...

ILI9341 SPI DMA, SPI, UART библиотеки
Доброго времени, форумчане... Посоветуйте библиотек плиз... 0) Либа для работы с контроллером по типу HAL (чисто ваше мнение какая вам...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Nekobox - outbounds[0].transport: unknown transport type: raw
damix 01.10.2026
Фикс ошибки Правым кликом по серверу -> отладочная информация -> edit Заменить "net": "raw", на "net": "tcp", Нажать кнопку reload.
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru