Передмова
Щоб спробувати роботу інтерфейсу SPI на простому прикладі я обрав мікросхему зсувного регістру SN74HC595, який приймає по послідовній шині байт і виставляє цей байт на виході вже у паралельному вигляді. Спектр застосування доволі широкий. Це і розширення GPIO, коли не вистачає ніжок на MCU для проекту, і робота з 7-ми сегментними дисплеями, і робота зі світлодіодними матрицями, тощо.
Мета
З метою ознайомлення з інтерфейсом SPI:
- підключимо зсувний регістр SN74HC595 до STM32;
- створимо проект в STM32CubeMX, налаштуємо периферію;
- напишемо невеличкий код для демонстрації.
Налаштування периферії в CubeMX
Створюємо новий проект в STM32CubeMX і налаштовуємо периферію як показано на малюнку:
![]() |
Налаштування периферії |
- Обираємо SPI і налаштовуємо як "Transmit only master", так як все одно будемо тільки передавати байти;
- Обираємо "Serial Wire" для програмування MCU за допомоги ST-Link (не обов'язково);
- Налаштовуємо одину шпильку на вихід GPIO_OUTPUT (яку вам зручно) і називаємо її "SN74HC595_CS" вибір кристалу.
Генеруємо проект, даємо назву, наприклад "STM32F103RB_SPI_SN74HC595N". З CubeMX це все. Переходимо до збірки схеми.
Схема підключення
Так як в SN74HC595N шпильки називаються по своєму, то ось відповідність SPI до виводів SN74HC595N:
- STM32: PB11 (CS) - 74HC595: 12 (RCLK) Storage rergistr
- STM32: PB15 (MOSI) - 74HC595: 14 (SER) Serial data input
- STM32: PB13 (SCK) - 74HC595: 11 ( SRCLK) Shift registr
Все інше схематично на макеті:
![]() |
Макетна схема |
Принципова схема:
![]() |
Принципова схема |
Все налаштовано і зібрано? Залишилось написати демо код.
Демонстраційна прогарма
Запускаємо свій засіб розробки і відкриваємо/експортуємо проект сформований програмою CubeMX. Відкриваємо файл "main.h". У визначених програмою CubeMX ділянках для користувача пишемо такий код:
/* USER CODE BEGIN Private defines */ #define CS_SET() HAL_GPIO_WritePin(SN74HC595_CS_GPIO_Port, SN74HC595_CS_Pin, GPIO_PIN_SET) #define CS_RESET() HAL_GPIO_WritePin(SN74HC595_CS_GPIO_Port, SN74HC595_CS_Pin, GPIO_PIN_RESET) #define CS_STROB() CS_SET(); CS_RESET() /* USER CODE END Private defines */
Тепер відкриваємо файл "main.c" і у визначених для користувача ділянках пишемо такий код:
/* USER CODE BEGIN WHILE */ while (1) { for(uint8_t i = 0; i < 256; i++) { HAL_SPI_Transmit(&hspi2, &i, 1, 1000); CS_STROB(); HAL_Delay(50); } /* USER CODE END WHILE */
Можете поекспериментувати з надсиланням байтів і зробити, наприклад, вогник що біжить зліва праворуч та повертається з право ліворуч. Шляхом зсуву бітів у циклі.