STM Урок 3. Библиотека SPL. Подключаем кнопку



Урок 3

Библиотека SPL. Подключаем кнопку

 

Сегодня мы с вами продолжим работу с библиотекой SPL, которую мы подключили на прошлом занятии. Хотя это прошло слегка нестандартным способом, но тем не менее нам это удалось. Вообщем, библиотеку мы подключили, но практически с её функциями мы пока не работали.

Проект для сегодняшнего занятия был сделан из предыдущего занятия. Как это делается, мы все уже видели. Назван проект был TEST003.

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

Теперь можно начинать написание нового кода.

Подключим к плате светодиодную матрицу, состоящую из 10 светодиодов.

 

image01

 

Также мы не забываем в цепь каждого светодиода включить токоограничивающий резистор. У меня резисторы исользуются номиналом в 680 ом. Вот схема подключения (нажмите на картинку для увеличения изображения)

 

image02_0500

 

Чтобы нам работать с портом, нам. как известно, необходимо запустить его тактирование. Хотя мы это уже делали, но делали мы это не с помощью библиотеки В справочном файле, находящемся в папке со скачанной библиотекой мы попробуем найти, каким образом мы это сможем сделать.

 

image03

 

Вот так выглядит данная функция в справке.

Почему мы выбрали именно данную шину? Это объясняется и в Reference Manual на контроллер, а также есть и в справке дальше в объяснении функции. Практически все порты ввода-выводы находятся именно на этой шине

 

image04

 

У данной функции 2 аргумента. Первый — это указатель на саму периферию AHB1 и порт ввода-вывода, который мы собираемся начинать тактировать ну или заканчивать, а второй параметр — это команда, она и отвечает за включение или отключение тактирования (ENABLE или DISABLE). Давайте добавим данную функцию в наш код. Откроем файл main.h и вставим код в функцию port_ini. Пока код будем вставлять поверх старого, чтобы ничего не забыть

 

void port_ini(void)
{
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);//включим тактирование порта D
 

Теперь порт у нас тактируется. Затем нужно нам включить всё остальное.

Сначала инициализация ножек порта. Для этого нам нужна будет структура. Тут есть один нюанс. Данная структура должна быть объявлена до включения тактирования. Вот такая вот структура

 

image06

 

 

Объявим структуру. Имя может быть любое. Но надо привыкать присваивать переменным, структурам, массивам такие имена, чтобы они сами о себе говорили. Тогда у нас будет меньше шансов не понять свой код в дальнейшем и запутаться в нём. Особенно, если этот код мы хотим кому-то показать

 

void port_ini(void)
{
 GPIO_InitTypeDef InitD; //для светодиодов
 
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);//включим тактирование порта D

 

В любой структуре перед её использованием нужно заполнить поля. Давайте этим займёмся.

Первое поле будет GPIO_Pin. В том же файле справки есть варианты данного поля

 

image07

 

Данное поле говорит о том, какие именно ножки порта мы будем использовать. Перечисляются они через операцию «ИЛИ»

 

 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);//включим тактирование порта D
 
 //светодиоды
 InitD.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|
  GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;

 

Таким образом мы объявляем для инициализации в поле структуры определённые ножки порта.

Следующее поле структуры — GPIO_Mode, это также структура, и здесь у нас есть вот такие вот варианты выбора

 

image08

 

Я думаю данные варианты сами о себе прекрасно говорят.

В нашем случае потребуется конфигурация порта на выход

 

 InitD.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|
  GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
 InitD.GPIO_Mode = GPIO_Mode_OUT;
 

 

Следующее поле — GPIO_OType.

 

image09

 

Здесь тоже ничего сложного. Выбираем тип Pull Push, открытый коллектор нам не нужен

 

 InitD.GPIO_Mode = GPIO_Mode_OUT;
 InitD.GPIO_OType = GPIO_OType_PP;
 

Следующее поле — GPIO_Speed:

 

image10

 

Есть также синонимы.

 

#define  GPIO_Speed_2MHz    GPIO_Low_Speed   
#define  GPIO_Speed_25MHz   GPIO_Medium_Speed
#define  GPIO_Speed_50MHz   GPIO_Fast_Speed
#define  GPIO_Speed_100MHz  GPIO_High_Speed

 

Выбираем 2 МГц. Нам спешить некуда

 

 InitD.GPIO_OType = GPIO_OType_PP;
 InitD.GPIO_Speed = GPIO_Speed_2MHz;
 

И последний параметр (поле) структуры — это GPIO_PuPd, который отвечает за подтягивание резистора к ондой из шины питания.

 

image11

 

Мы никуда подтягиваться не будем

 

 InitD.GPIO_Speed = GPIO_Speed_2MHz;
 InitD.GPIO_PuPd = GPIO_PuPd_NOPULL;
 

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

Вот функция. Файл справки тот же

 

image05

 

Первый параметр — это порт, а второй — указатель на нашу только что заполненную структуру, причем именно указатель.

 

 InitD.GPIO_PuPd = GPIO_PuPd_NOPULL;
 GPIO_Init(GPIOD,&InitD); //инициализация ножек порта
 

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

 

image12

image13

 

Давайте теперь перейдём в main() и в бесконечном цикле исправим код следующим образом

 

 while(1)
 {
   GPIO_SetBits(GPIOD, GPIO_Pin_0);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_0);
   GPIO_SetBits(GPIOD, GPIO_Pin_1);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_1);
   GPIO_SetBits(GPIOD, GPIO_Pin_2);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_2);
   GPIO_SetBits(GPIOD, GPIO_Pin_3);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_3);
   GPIO_SetBits(GPIOD, GPIO_Pin_4);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_4);
   GPIO_SetBits(GPIOD, GPIO_Pin_5);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_5);
   GPIO_SetBits(GPIOD, GPIO_Pin_6);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_6);
   GPIO_SetBits(GPIOD, GPIO_Pin_7);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_7);
   GPIO_SetBits(GPIOD, GPIO_Pin_8);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_8);
   GPIO_SetBits(GPIOD, GPIO_Pin_9);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_9);

  }

 

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

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

 

  {
   GPIO_SetBits(GPIOD, GPIO_Pin_0);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_9);
   GPIO_SetBits(GPIOD, GPIO_Pin_1);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_0);
   GPIO_SetBits(GPIOD, GPIO_Pin_2);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_1);
   GPIO_SetBits(GPIOD, GPIO_Pin_3);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_2);
   GPIO_SetBits(GPIOD, GPIO_Pin_4);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_3);
   GPIO_SetBits(GPIOD, GPIO_Pin_5);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_4);
   GPIO_SetBits(GPIOD, GPIO_Pin_6);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_5);
   GPIO_SetBits(GPIOD, GPIO_Pin_7);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_6);
   GPIO_SetBits(GPIOD, GPIO_Pin_8);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_7);
   GPIO_SetBits(GPIOD, GPIO_Pin_9);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_8);
  }

 

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

Вообщем, научились мы управлять ножками портов на выход. Теперь попробуем отследить состояние порта, которое будет зависеть от подключенной на плате синей кноки. Данная кнопка подключена к ножке 0 порта A, то есть к PA0

 

image14

 

Но так как кнопка подключена уже не к порту D, то порт A мы должны также инициализировать, сначала включим для него тактирование, так как тактирование портов у нас отключено из соображений энергоэффективности. Сначала создадим структуру

 

 GPIO_InitTypeDef InitA0; //для кнопки
 GPIO_InitTypeDef InitD; //для светодиодов
 

Запустим тактирование порта, таким же образом проинициализируем поля структуры, соответственно используюя там инициализацию на вход (GPIO_Mode_IN) и в конце вызовем функцию инициализации ножки 0 порта

 

 GPIO_Init(GPIOD,&InitD); //инициализация ножек порта

 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//включим тактирование порта A

 //кнопка
 InitA0.GPIO_Pin = GPIO_Pin_0;
 InitA0.GPIO_Mode = GPIO_Mode_IN;
 InitA0.GPIO_OType = GPIO_OType_OD;
 InitA0.GPIO_Speed = GPIO_Speed_2MHz;
 InitA0.GPIO_PuPd = GPIO_PuPd_NOPULL;
 GPIO_Init(GPIOA,&InitA0); //инициализация ножек порта

}

 

А отслеживать состояние ножки мы будем при помощи вот такой функции, похожей также и на ту, с помощью которой мы управляем портами, включенными на выход

 

image15

 

Вернёмся в main() в бесконечный цикл и обернём наш код в бесконечном цикле в условие

 

 while(1)
 {
  if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==1) //кнопка нажата
  {

   GPIO_SetBits(GPIOD, GPIO_Pin_0);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_9);
   GPIO_SetBits(GPIOD, GPIO_Pin_1);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_0);
   GPIO_SetBits(GPIOD, GPIO_Pin_2);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_1);
   GPIO_SetBits(GPIOD, GPIO_Pin_3);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_2);
   GPIO_SetBits(GPIOD, GPIO_Pin_4);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_3);
   GPIO_SetBits(GPIOD, GPIO_Pin_5);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_4);
   GPIO_SetBits(GPIOD, GPIO_Pin_6);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_5);
   GPIO_SetBits(GPIOD, GPIO_Pin_7);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_6);
   GPIO_SetBits(GPIOD, GPIO_Pin_8);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_7);
   GPIO_SetBits(GPIOD, GPIO_Pin_9);
   delay(1000000);
   GPIO_ResetBits(GPIOD, GPIO_Pin_8);
  }
  else GPIO_ResetBits(GPIOD,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|
  GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9);
 }

 

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

 

 

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

 

Исходный код

 

 

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

STM32F4-DISCOVERY

 

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

 

STM32 Библиотека SPL. Подключаем кнопку

 

2 комментария на “STM Урок 3. Библиотека SPL. Подключаем кнопку
  1. віталій:

    хотелось бы урок по созданию синуса и 3 фазного синуса

    • у меня есть наработки трёхфазного синуса правда на atmege128.ты хочешь сделать частотник ?принып на двух таймерах.один работает в прерывании а второй таймер реализует шим принцип такойже и у стм.Я не програмист я амматор.\

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

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

*