В уроке 144 мы с вами познакомились, какие основные режимы пониженного энергопотребления существуют у контроллеров stm32 и поглубже познакомились с одним из них — с режимом SLEEP.
И, прежде чем приступить к изучению остальных режимов, давайте познакомимся с библиотекой low-layer drivers или, попросту говоря, LL.
Данная библиотека, равно как и библиотека HAL, может спокойно использоваться в интерфейсе проектогенератора Cube MX, и позволяет более гибко работать с контроллером и его регистрами, чем HAL. Также были многочисленные просьбы сделать несколько уроков с использованием данной библиотеки. А также это будет ещё один шаг к программированию контроллеров на более низком уровне. Возможно, так мы постепенно доберёмся и до ассемблера. Я уже давно до него добрался и, в принципе, готов поделиться с вами своими наработками, если будет желание. А оно, как я подозреваю, уже есть, так как тоже был ряд просьб и пожеланий по этому поводу.
Думаю, рассказывать голословно (без практического использования) о библиотеке LL смысла нет и мы сразу приступим к созданию простейшего проекта. В нём мы попробуем по очереди помигать светодиодами, используя определённые ножки портов, а также попробуем поработать с портом и на вход, отслеживая нажатие кнопки, тем самым определяя, низкий или высокий в данный момент у нас на данной ножке уровень.
Контроллер будем по-прежнему использовать самый простой и дешёвый — STM32F103, расположенный на недорогой отладочной плате. Мало того, схему мы тоже не трогаем. Оставим ту же светодиодную планку, подключенную к тем же ножкам, как и при использовании со сторожевыми таймерами.
Создадим новый проект в Cube MX, выбрав наш контроллер
Включим RCC HSE с использованием кварцевого резонатора
Затем включим отладчик
Далее включим на выход ножки, отвечающие за наши подключенные светодиоды на планке
А ножку P1 включим на вход
Подтянем к ней резистор с ножки питания
И перед тем, как перейти к настройке тактирования, зайдём в раздел Project Manager, слева затем выбрав пункт Advanced Settings, и в настройках RCC и GPIO выберем там вместо HAL нашу библиотеку LL
В Clock Configuration настроим тактирование контроллера
Присвоим проекту имя и выберем среду разработки, в первых уроках, как обычно, мы будем использовать KEIL
Сохраним проект и откроем его в KEIL.
Настроим, как всегда, программатор на автоматическую перезагрузку контроллера и выставим уровень оптимизации в 0.
Перейдём в файл main.c и для наших светодиодов добавим удобные макросы, ясное дело используя уже функции LL, которые все описаны в документации STM32F1 HAL and Low-layer drivers, доступной для скачивания на официальном сайте ST Microelectronics
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
/* USER CODE BEGIN PV */ #define LED1_ON() LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_2) #define LED1_OFF() LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_2) #define LED2_ON() LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_3) #define LED2_OFF() LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_3) #define LED3_ON() LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_4) #define LED3_OFF() LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_4) #define LED4_ON() LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_5) #define LED4_OFF() LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_5) #define LED5_ON() LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_6) #define LED5_OFF() LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_6) #define LED6_ON() LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_7) #define LED6_OFF() LL_GPIO_ResetOutputPin(GPIOA, LL_GPIO_PIN_7) #define LED7_ON() LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_0) #define LED7_OFF() LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_0) #define LED8_ON() LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_1) #define LED8_OFF() LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_1) #define LED9_ON() LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_10) #define LED9_OFF() LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_10) #define LED10_ON() LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_11) #define LED10_OFF() LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_11) |
В функции main() погасим все светодиоды
1 2 3 |
/* USER CODE BEGIN 2 */ LED1_OFF();LED2_OFF();LED3_OFF();LED4_OFF();LED5_OFF(); LED6_OFF();LED7_OFF();LED8_OFF();LED9_OFF();LED10_OFF(); |
Пока просто попробуем помигать нашими светодиодами без участия кнопки в бесконечном цикле
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
/* USER CODE BEGIN 3 */ LED1_ON(); LL_mDelay(100); LED1_OFF(); LED2_ON(); LL_mDelay(100); LED2_OFF(); LED3_ON(); LL_mDelay(100); LED3_OFF(); LED4_ON(); LL_mDelay(100); LED4_OFF(); LED5_ON(); LL_mDelay(100); LED5_OFF(); LED6_ON(); LL_mDelay(100); LED6_OFF(); LED7_ON(); LL_mDelay(100); LED7_OFF(); LED8_ON(); LL_mDelay(100); LED8_OFF(); LED9_ON(); LL_mDelay(100); LED9_OFF(); LED10_ON(); LL_mDelay(100); LED10_OFF(); |
Соберём код, прошьём контроллер, и, если всё нормально, то наши светодиоды побегут с периодом 100 милисекунд
Теперь попробуем задействовать нашу кнопку. Для этого есть ещё одна функция.
Код наш будет работать аналогично коду из урока для библиотеки HAL. Если кнопка будет не нажата, то светодиоды не побегут и будут погашены.
Как только мы нажмём кнопку, светодиоды начнут мигать поочерёдно. Если мы отпустим кнопку, то светодиоды сразу не погаснут, а цикл дойдёт до последнего.
В бесконечном цикле добавим условие
1 2 3 4 |
/* USER CODE BEGIN 3 */ if (!(LL_GPIO_ReadInputPort(GPIOA)&GPIO_IDR_IDR1)) { LED1_ON(); |
Также не забываем закрыть нашу фигурную скобку в конце цикла
1 2 3 |
LED10_OFF(); } } |
Соберём код, прошьём контроллер и посмотрим результат работы нашего кода. Светодиоды теперь бегут только когда мы нажмём кнопку
Итак, в данном занятии мы начали изучение новой для нас более низкоуровневой библиотеки — LL. Пока мы только поработали с портами ввода вывода. В дальнейшем, надеюсь, мы продолжим эту тему, что позволит нам более гибко настраивать наши проекты.
Всем спасибо за внимание!
Предыдущий урок Программирование МК STM32 Следующий урок
Отладочную плату STM32F103C8T6 можно приобрести здесь STM32F103C8T6
Программатор недорогой можно купить здесь ST-Link V2
Смотреть ВИДЕОУРОК (нажмите на картинку)
Спасибо за урок. Хочется больше уроков по LL
Спасибо за уроки по LL..
у меня так Keil не понимает
LL_GPIO_ReadInputPort(GPIOA)&GPIO_IDR_IDR1
понимает так
LL_GPIO_ReadInputPort(GPIOA)&LL_GPIO_PIN_1
и можно так
LL_GPIO_IsInputPinSet(GPIOA,LL_GPIO_PIN_1)
по Вашим урокам подключил FM24CL64B и LM75(пока только считываю тем-ру)
Привет.Тебе нужно в кубе выбрать LL вместо HAL
Мне кажется там ошибка. Надо вместо GPIO_IDR_IDR1 писать GPIO_IDR_1. Тогда все работает.