STM Урок 157. HAL. SPI. Interrupt

 

 

 

Продолжаем подробное изучение шины SPI в контроллере STM32. И на данном уроке мы попробуем воспользоваться механизмом прерываний, организованным в периферии SPI в данном контроллере.

Использовать сегодня мы будем возможности библиотеки HAL, которые позволят нам также легко отследить передачу большой порции данных по шине SPI.

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

Схема будет использоваться та же, что и в уроке 153

 

 

С битами, отвечающими за включение прерываний в SPI, а также с битами флагов этих прерываний, мы уже знакомились в уроке 152, когда начинали работать с шиной SPI с использованием библиотеки LL. Поэтому мы сразу смело можем приступить к нашим проектам.

Проект для ведущего устройства сделан был из проекта уроке 153 с именем SPI_MASTER и имя ему было присвоено SPI_MASTER_INT.

Откроем проект в Cube MX и включим прерывания в SPI1

 

Сгенерируем проект и откроем его в Keil.

Настроим программатор на автоперезагрузку, отключим оптимизацию и подключим файл работы с индикатором max7219.c.

Откроем файл main.c и удалим вот этот глобальный массив

 

uint8_t RxBuf[2] = {0};

 

Вместо него добавим два больших буфера, один для приёма, другой для передачи, а также переменную для флага. Ещё добавим переменную для счётчика, вернее она у нас уже была в функции main(), теперь мы её сделаем глобальной. И добавим переменную ещё для одного счётчика

 

 

А в функции main() мы в локальной переменной изменим имя

 

uint8_t n;

 

До вывода большого числа заполним буфер источника числами от 1 до 1024

 

 

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

Сначала там сбросим счётчик, если его значение достигло порога

 

 

Опустим ножку выбора и передадим порцию данных в количестве 128 слов, а также примем порцию данных в таком же количестве и поместим в приёмный буфер. Если быть более точными, то мы здесь только дадим команду на передачу. Программа не будет здесь ждать, пока данные передадутся, поэтому здесь нет таймаута. И поэтому нам надо будет затем как-то отследить тот момент, когда все данные передадутся

 

Отобразим принятые данные на индикаторе, подождём секунду и добавим к нашему счётчику сразу 128.

 

 

Ножку обратно мы здесь поднимать не будем, это всё будет в другом месте — в обработчике переывания.

Теперь нам надо отследить окончание передачи всех данных, причём обработчик прерываний не позволяет этого делать

Добавим функцию для обработки прерываний, в которой узнаем, что у нас передан именно последний элемент данных, для этого есть специальный счётчик обратного отчсёта, реализованный в библиотеке HAL

 

 

Также в бесконечном цикле функции main() дождёмся установки нашего флага и сбросим его

 

 

Соберём проект, прошьём контроллер ведущей платы и пока ничего не проверяем.

Отключим пока контроллер Мастера и займёмся проектом ведомого устройства, который был сделан из проекта ведомого устройства урока 153 с именем SPI_SLAVE и присвоим ему имя SPI_SLAVE_INT.

Откроем проект в Cube MX и также включим прерывания в SPI1

 

Сгенерируем проект и откроем его в Keil.

 

 

Настроим программатор на автоперезагрузку, отключим оптимизацию и подключим файл работы с индикатором max7219.c.

Откроем файл main.c и тоже удалим вот этот глобальный массив

 

uint8_t RxBuf[2] = {0};

 

Вместо него добавим массивы приёмника и источника, также глобальный счётчик и флаг

 

 

В функции main() также исправим имя локальной переменной

 

uint8_t n;

 

Удалим вот эту задержку

 

HAL_Delay(2000);

 

До вывода на индикатор большого числа наполним наш буфер декрементированными данными от 1024 до 1

 

 

И тут же мы вызываем функцию приёма и отправки данных

 

 

Пока данные не придут с ведущего устройства, приём на SLAVE не начнётся по определению, так как тактируется шина с ведущего.

В бесконечном цикле пока всё удалим.

Давайте, наоборот сначала займёмся обработкой прерываний.

Добавим для этого функцию, в которой по полному окончанию приёма и передачи всех данных установим наш флаг

 

 

Вернёмся в бесконечный цикл функции main() и дождёмся взведенного флага, который будет гласить о том, что мы полностью обменялись порцией всех данных

 

 

Сохраним значение самой первой ячейки приёмного буфера

 

 

Это и будет значение счётчика, чтобы шло всё синхронно с ведущим устройством.

Отобразим данные из приёмника и источника на индикаторе

 

 

Сбросим флаг, добавим к счётчику 128, обнулим его, если превышение, и дадим команду на приём новых данных

 

 

Соберём код, прошьём контроллер ведомого устройства, подключим ведущий от отдельного устройства, и наши устройства, если всё правильно мы написали начнут обмен данными

 

 

Посмотрим также наш обмен в программе логического анализа

 

 

Посмотрим начало обмена порциями данных

 

 

 

Также посмотрим окончание обмена

 

 

Таким образом, мы сегодня смогли обменяться информацией между двумя контроллерами STM32 по шине SPI, используя при этом механизм обработки прерываний от шины и возможности библиотеки HAL.

Всем спасибо за внимание!

 

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

 

Исходный код для ведущего устройства (MASTER)

Исходный код для ведомого устройства (SLAVE)

 

 

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

Программатор недорогой можно купить здесь ST-Link V2

Индикатор светодиодный семиразрядный с драйвером MAX7219

Логический анализатор 16 каналов можно приобрести здесь

 

 

Смотреть ВИДЕОУРОК (нажмите на картинку)

 

STM HAL. SPI. Interrupt

Один комментарий на “STM Урок 157. HAL. SPI. Interrupt
  1. Николай:

    Спасибо

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

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

*