STM Урок 23. HAL. SPI. Сдвиговый регистр 74HC595



Урок 23

HAL. SPI. Сдвиговый регистр 74HC595

 

Предыдущий урок Программирование МК STM32 Следующий урок

 

Сегодня мы начинаем цикл занятий по шине SPI (Serial peripheral interface).

Рассказывать про то, как данная шина работает, нет никакого смысла, так как на данном сайте вся информация об этом уже есть, достаточно посмотреть урок по данной шине для AVR.

Нам важно теперь узнать, как именно данную шину программировать в контроллерах STM32.

Мы продолжаем работать с той же платой — STM32F4-Discovery и подключим м к ней сдвиговый регистр 74HC595, хотя многие начинают изучение данной шины с акселерометра, который уже установлен на плате. Так конечно легче, но с акселерометрами мы будем работать немного позже, а пока мы слегка поломаем все стереотипы и подключим простейший сдвиговый регистр, тем более что мы его уже подключали в уроке по AVR и поэтому нам будет легче его программировать и не придётся о нем особо рассказывать.

Единственное напомню, что данный регистр в основном используется для преобразования последовательного кода, переданного по SPI в параллельный по 8-битной шине. Немного поподробнее я рассказал о шине и микросхеме в видеоверсии, ссылка на которую есть внизу на странице.

Вот схема подключения данной микросхемы к нашему контроллеру (нажмите на картинку для увеличения изображения)

 

Image00_500

 

Микросхема на схеме немного другая, но у нас будет именно заявленная в теме урока.

А вот так всё выглядит практически

 

Image05_0500

 

Вместо восьми светодиодов у нас светодиодная матрица, так удобнее и компаткнее.

Вход MISO мы на контроллере не исползуем, так как нам никакой информации от микросхемы не нужно.

Проект создаём из MYLCD80, называем его SPI595. Уберем из папок файлы lcd.c и lcd.h.

Запускаем Cube. Так как проект был создан в более ранней версии Cube, то в ответ на диалог с тремя кнопками жмём «Migrate», чтобы проект наш адаптировался к новой версии.

Включим SPI3. Почему SPI3, потому что лапки на плате на удобной стороне

 

Image01

 

 

Включим PD0 на выход, он также находится рядом с этими ножками и потребуется нам для Chip Select

 

Image01 Image02

 

Т.к. SPI3 находится на периферии APB1 (смотрим Reference Manual), то настроим её на максимальную частоту в Clock Configuration

 

Image03

 

Посмотрим SPI3 в Configuration

 

Image04

 

Судя по технической документации на микросхему, с данной частотой она должна справиться. У неё заявлено 100 МГц.

Больше ничего не трогаем. Генерируем проект и запускаем его. Настраиваем программатор на авторезет.

Удалим из main.h объявление lcd.h.

Также удалим весь код из main.c, ну конечно не весь, а который мы создавали самы, савтогенерированный убирать не надо.

Объявим в main.c некоторые дефайны для управления ножкой Chip Select

 

/* USER CODE BEGIN PV */

/* Private variables ———————————————————*/

#define cs_set() HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0, GPIO_PIN_RESET)

#define cs_reset() HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0, GPIO_PIN_SET)

#define cs_strob() cs_reset();cs_set()

/* USER CODE END PV */

 

 

Начнем писать код в функции main() – включим выбор микросхемы

 

  /* USER CODE BEGIN 2 */

        cs_set();

 

Создадим буфер для данных для передачи в SPI, так как этого требует функция передачи

 

/* Private variables ———————————————————*/

uint8_t aTxBuffer[1]={0};

#define cs_set() HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0, GPIO_PIN_RESET)

 

На странице 814 STM32F4_HAL_User Manual.pdf найдём функцию передачи данных в SPI. Напишем её код в проект

 

  /* USER CODE BEGIN 2 */

        cs_set();

        HAL_SPI_Transmit(&hspi3,(uint8_t*)aTxBuffer, 1, 5000);

 

Перед вызовом данной функции положим в буфер какое-нибудь число, например 1

 

        cs_set();

        aTxBuffer[0]=0x01;

        HAL_SPI_Transmit(&hspi3,(uint8_t*)aTxBuffer, 1, 5000);

 

Теперь нам необходим импульс на ножке cs (страница 5 даташита микросхемы)

 

        HAL_SPI_Transmit(&hspi3,(uint8_t*)aTxBuffer, 1, 5000);

        cs_strob();

 

Теперь давайте после небольшой задержки отправим другую цифру

 

        cs_strob();

        HAL_Delay(1000);

        aTxBuffer[0]=0xFF;

        HAL_SPI_Transmit(&hspi3,(uint8_t*)aTxBuffer, 1, 5000);

        HAL_Delay(1000);

        cs_strob();

  /* USER CODE END 2 */

 

Прошьём контроллер, посмотрим результат

 

Image06

 

Ну и давайте теперь организуем какой-нибудь счётчик для нашей матрицы.

Объявим переменную для счётчика

 

int main(void)

{

  /* USER CODE BEGIN 1 */

        uint8_t i=0;

  /* USER CODE END 1 */

 

Теперь давайте добавим в бесконечный сам счётчик

 

  while (1)

  {

                for(i=0;i<=255;i++)

                {

                        aTxBuffer[0]=i;

                        HAL_SPI_Transmit(&hspi3,(uint8_t*)aTxBuffer, 1, 5000);

                        cs_strob();

                        HAL_Delay(100);

                }

                /* USER CODE END WHILE */

 

Опять прошьём и посмотрим

 

Image07

 

На следующем уроке мы попробуем к такому же сдвиговому регистру подключить семисегментный светодиодный индикатор и поуправлять уже им.

 

 

Предыдущий урок Программирование МК STM32 Следующий урок

 

Исходный код

 

Техническая документация на микросхему 747HC595

 

Отладочную плату и сдвиговые регистры можно приобрести здесь:

STM32F4-DISCOVERY

Сдвиговые регистры 74HC595N 10 шт

 

 

Смотреть ВИДЕОУРОК

 

STM32 HAL. SPI. Сдвиговый регистр 74HC595

 

15 комментариев на “STM Урок 23. HAL. SPI. Сдвиговый регистр 74HC595
  1. Добрый день!
    у Вас указано CPOL=Low это правильно?
    у микросхемы (согласно даташита) 74HC595 сдвиг бита и запись в выходной регистр происходят при переходе от 0 к 1 т.е. по нарастающим фронтам.

    • Я сильно не заморачивался. Главное, что заработало.

      • дело не в заморачивании, а в стабильной работе хотя бы на 50МГц
        я поставил CPOL=High и пробовал 74HC595 на этой частоте и ещё использовал аппаратный NSS — завел его на строб записи в выходной регистр — он как раз формирует нарастающий фронт по окончании передачи.

    • Олег:

      CPOL=Low — правильно, вроде. В связке с битом CPOL нужно учесть бит CPHA.
      Где CPHA = 1 Edge — данные с линий МOSI и MISO считываются по первому (переднему) фронту импульсов SCK.
      Где CPHA = 2 Edge — данные с линий МOSI и MISO считываются по второму (заднему) фронту импульсов SCK.
      А при CPOL=Low передним фронтом у нас как раз и будет переход от 0 к 1.

  2. мне тут вылезло сообщение:
    «Нельзя обращаться к сайту чаще, чем один раз в три секунды!»
    … а что сайт на КР580ВМ1 сделан?

    • Нет, не сделал. Это борьба с атаками. Причём очень сильно помогло. Также это борьба со скачиванием контента большими порциями. А если не секрет, зачем Вам обращаться чаще чем через 3 секунды? Вы успеваете за 3 секунды всю страницу прочитать?

      • просто что-то листал и такое вылезло — такое ограничение показалось странным. А от скачиваний это не поможет. Могу по собственному опыту сказать, что любые уловки по ограничению скачиваний не являются препятствием для опытных специалистов.

  3. Андрей:

    Доброго дня!
    В настройках SPI в Кубе есть вариант работы 16 бит. Как считаете, можно ли включить его, и в качестве содержимого буфера передавать два байта за один раз?

  4. Андрей:

    Жаль, нет возможности редактировать комментарии. Выше я написал о том случае, который рассматривается Вами дальше — два 595 чипа и четыре сегмента, для динамической индикации

  5. Игорь:

    Приветствую Вас.
    Рассмотрели сдвиговый регистр последовательный-паралельный типа 74hc595,
    но хотелось бы и обратную задачу паралельный-последовательный 74hc165, а особенно 2*8бит.
    Подключение кнопок тоже дело нужное, особенно если дребезг устранить аппаратно.

  6. Dmitriy:

    Я так понимаю, буфер представляет из себя массив из одного элемента. Это требование функции в HAL? Если да, то в случае передачи массива из n- элементов, как на обеспечить «стробирование»?

  7. Евгений Черкашин:

    1. На схеме нет ошибки подключения 11 (CLK) ноги регистра к PC11, которая SPI3_MISO? Она не должна идти к PC10 (SPI3_CLK)?
    2. То, что Вами реализовано — это не SPI из-за «строба». По идее можно реализовать в точности SPI.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*