четвер, 1 лютого 2018 р.

STM32: керуємо зсувним регістром SN74HC595 по SPI

Передмова

Щоб спробувати роботу інтерфейсу SPI на простому прикладі я обрав мікросхему зсувного регістру SN74HC595, який приймає по послідовній шині байт і виставляє цей байт на виході вже у паралельному вигляді. Спектр застосування доволі широкий. Це і розширення GPIO, коли не вистачає ніжок на MCU для проекту, і робота з 7-ми сегментними дисплеями, і робота зі світлодіодними матрицями, тощо.

Мета

З метою ознайомлення з інтерфейсом SPI:
  • підключимо зсувний регістр SN74HC595 до STM32;
  • створимо проект в STM32CubeMX, налаштуємо периферію;
  • напишемо невеличкий код для демонстрації.

Налаштування периферії в CubeMX

Створюємо новий проект в STM32CubeMX і налаштовуємо периферію як показано на малюнку:
Налаштування периферії
  1. Обираємо SPI і налаштовуємо як "Transmit only master", так як все одно будемо тільки передавати байти;
  2. Обираємо "Serial Wire" для програмування MCU за допомоги ST-Link (не обов'язково);
  3. Налаштовуємо одину шпильку на вихід 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 */
Це ми визначили директивами "#define" для зручності виклик функції з потрібними нам параметрами.

Тепер відкриваємо файл "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 */
Це простий цикл від 0 до 255, або від 0x00h до 0xFFh у шістнадцятковому виді. В цьому циклі ми по SPI з MCU шлемо один байт ітерації циклу до зсувного регістру кожні 50 мілісекунд. Простими словами, байт посланий  по послідовній шині, зсувний регістр прийме і виставить на паралельну шину вже у двійковому форматі. І будемо спостерігати як перебираються цифри від 0 до 255 у двійковому форматі.
Можете поекспериментувати з надсиланням байтів і зробити, наприклад, вогник що біжить зліва праворуч та повертається з право ліворуч. Шляхом зсуву бітів у циклі.