Easyelectronics.ru • Просмотр темы - Помощь новичку STM32L476VG зажечь светодиод

Easyelectronics.ru

Электроника для всех
Текущее время: 15 авг 2018, 05:58

Часовой пояс: UTC + 5 часов



    • JLCPCB - Прототипы 10 PCBs всего за 2$ (100*100mm, 2-layer)
    • Как мы делаем платы, смотрите на YouTube
    • Крупнейшая китайская фабрика прототипов. 300000+ заказчиков и 10000+ заказов в день!
    • LCSC - Крупнейший китайский онлайн магазин комплектующих.

Начать новую тему Ответить на тему  [ Сообщений: 78 ]  На страницу 1, 2, 3, 4  След.
Автор Сообщение
 Заголовок сообщения: Помощь новичку STM32L476VG зажечь светодиод
СообщениеДобавлено: 03 июн 2018, 02:53 
Только пришел

Зарегистрирован: 03 июн 2018, 02:32
Сообщения: 10
Откуда: Беларусь
Доброго времени суток!
Заранее прошу прощения за пустяковый вопрос, но не в силу мне пока разобраться с этим "Хелоу, ворлд!".
Не у кого спросить, хочу освоить отладочную плату STM32L476VG. Не получается сообразить с ошибками в коде по работе с регистром.
Подскажите пожалуйста, как поправить код и почему именно так необходимо сделать. Хочу зажечь зеленый светодиод (PE8) на отладочной плате STM32L476VG.
Благодарю за помощь!


Вложения:
Безымянный23.jpg
Безымянный23.jpg [ 200.96 Кб | Просмотров: 2577 ]
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помощь новичку STM32L476VG зажечь светодиод
СообщениеДобавлено: 03 июн 2018, 04:23 
Старожил
Аватара пользователя

Зарегистрирован: 17 дек 2014, 23:08
Сообщения: 588
Откуда: Nowhere
По первой ошибке: GPIOE->AFR - это массив, который указывает на два регистра: AFRL (GPIOx->AFR[0]) и AFRH (GPIOx->AFR[1])
По второй ошибке: компилятору неизвестна фраза 'GPIO_AFRH_MODE8_0' (такого нет в файле stm32l4xx.h)

hint: для действий над определенным регистром надо юзать соответствующие этому константы, обычно в их имени есть название регистра, например, для AFRH надо юзать GPIO_AFRH_xxx...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помощь новичку STM32L476VG зажечь светодиод
СообщениеДобавлено: 03 июн 2018, 07:01 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2098
...и для зажигания вручную светодиода операции с AFR не нужны. AFR - это Alternate Function Register, управляет назначением на пин альтернативных функций, таких как SPI, UART и пр. По умолчанию после сброса он = 0х00000000, то есть выбрана базовая функция пина - непосредственное управление.
Зато нам нужен регистр MODER - port MODE Register. Согласно таблице:
Вложение:
Без-имени-1.png
Без-имени-1.png [ 8.91 Кб | Просмотров: 2549 ]


причем, MODER имеет вот такую структуру и вот такое состояние после сброса (выбран режим аналогового входа, в отличие от многих МК F-серии):
Вложение:
Без-имени-2.png
Без-имени-2.png [ 12.81 Кб | Просмотров: 2547 ]


Поэтому, чтобы включить режим general purpose output на PE8, надо сбросить бит 17 в регистре, записать это можно вот так:
GPIOE->MODER &= ~GPIO_MODER_MODER8_1;
это означает "в регистр запишется число, равное операции AND с текущим значением регистра и числом, равным инвертированному значению дефайна, которое = 0x00020000".

Далее, выставить определенный уровень на пине можно двумя способами - либо через регистр ODR - Output Data Register, в котором каждый бит от 0 до 15 отвечает за соответствующий пин Px0 - Px15, но регистр записывается целиком шириной 16 бит или по половинке 8 бит. Операции с отдельными битами (OR, AND, XOR) считаются неатомарными, поэтому для этого рекомендован специальный регистр BSRR - Bit Set/Reset Register, его структура такова:
Вложение:
Без-имени-12.png
Без-имени-12.png [ 12.15 Кб | Просмотров: 2545 ]

для установки выхода в 1 используются биты BS с номерами 0 - 15, а для сброса выхода в 0 - биты BR с номерами 16 - 31. Причем, переключает порт только запись 1, а запись 0 не влияет. Значит, можно смело использовать одну операцию записи вместо операций AND или OR.

По схеме Дискавери для зажигания светодиода нужно на выход подать 1, значит, надо записать:
GPIOE->BSRR = GPIO_BSRR_BS_8;

PS. У этого МК есть еще отдельный регистр BRR для сброса битов ног. Он похож на BSRR, но используется только для сброса в 0 и биты BR находятся на позициях 0 - 15.

PS2. Обратите внимание на способ записи названий регистров и битов в регистре.
Обращаясь к регистрам, вы сначала записываете название структуры (GPIOE), затем название регистра в этой структуре (MODER). Затем в правой части выражения вы пишите названия битов. Названия битов составлены таким образом, что содержат в себе название структуры и название регистра, и затем название бита и его вариацию: GPIO_MODER_MODER8_1. Причем, название структуры имеет общий для всех портов шаблон: GPIO.
Все это описано дефайнами в заголовочном файле stm32l486xx.h, можете в него смотреть и искать названия битов. А если расшифровать всю эту кучу дефайнов-передефайнов, то в конечном итоге получим обычную запись в цифрах, где слева будет стоять указатель на адрес регистра, а справа - число, записываемое в регистр.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помощь новичку STM32L476VG зажечь светодиод
СообщениеДобавлено: 03 июн 2018, 11:57 
Старожил

Зарегистрирован: 08 авг 2013, 09:43
Сообщения: 847
http://easyelectronics.ru/arm-uchebnyj- ... -gpio.html


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помощь новичку STM32L476VG зажечь светодиод
СообщениеДобавлено: 03 июн 2018, 12:10 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2098
NStorm, у F1 конфигурирование портов очень сильно отличается от L4!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помощь новичку STM32L476VG зажечь светодиод
СообщениеДобавлено: 03 июн 2018, 13:42 
Старожил

Зарегистрирован: 08 авг 2013, 09:43
Сообщения: 847
Это понятно, вы же расписали как надо на L4, я просто в дополнение кинул, там чуть по-больше про BSRR/BRR/ODR расписано. Они то есть везде. Конфигурация да, по-другому.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помощь новичку STM32L476VG зажечь светодиод
СообщениеДобавлено: 03 июн 2018, 15:36 
Только пришел

Зарегистрирован: 03 июн 2018, 02:32
Сообщения: 10
Откуда: Беларусь
Доброго дня! Очень рад, что столько форумчан откликнулись на просьбу помочь - спасибо! Нужно сейчас внимательно вникнуть в написанное!
Я по-видимому неверно в документации смотрел, что нужно.
Отдельные слова благодарности LonelyWolf -у и BusMaster-у за столь подробный ответ!
Постараюсь в ближайшее время опубликовать в теме, что вышло у меня :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помощь новичку STM32L476VG зажечь светодиод
СообщениеДобавлено: 04 июн 2018, 02:06 
Только пришел

Зарегистрирован: 03 июн 2018, 02:32
Сообщения: 10
Откуда: Беларусь
Доброго времени суток!
Сейчас начал смотреть примеры с stm32f4. По Reference manual, кажется, подходя к к stm32l4.
Немного другой подход еже ли в начале темы. На данном этапе имею следующий код в Кейле.
Не понятно как записывать биты. В калькуляторе выдает значение, а как вписывать... (тут тоже пробелы). Нужно учить матчасть.
Поправьте меня пожалуйста.
Как правильно записать биты, получится ли, в парильном направлении движусь?
Прикрепляю скриншоты. Заранее благодарен за помощь!


Вложения:
1.jpg
1.jpg [ 86.5 Кб | Просмотров: 2084 ]
2.jpg
2.jpg [ 202.23 Кб | Просмотров: 2084 ]
3.jpg
3.jpg [ 181.69 Кб | Просмотров: 2084 ]
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помощь новичку STM32L476VG зажечь светодиод
СообщениеДобавлено: 04 июн 2018, 04:53 
Старожил
Аватара пользователя

Зарегистрирован: 17 дек 2014, 23:08
Сообщения: 588
Откуда: Nowhere
Еще один hint: код лучше давать не скриншотами, а текстом (используя тег code), так проще копипастить для ответа и вообще, так оно лучше читается.

В приведенном коде запись конкретных значений в регистр - неправильный подход.
Пример: хотим записать биты касаемо ноги PE9 в регистре MODER (как на картинке). Пишем конкретное значение 0x40000... да, нужное значение для PE9 есть, но сброшены все остальные, а это врятли нужно.
Еще одно: писать конкретные числа (т.н. magic numbers) - тоже некрасиво, т.к. потом сходу не вспомнишь, что же оно означает. Тут надо использовать те самые дефайны из .h файла.
А делают это обычно так:
Код:
GPIOE->MODER &= ~GPIO_MODER_MODE9; // сбрасываем оба бита MODER9[0:1]
GPIOE->MODER |= GPIO_MODER_MODE9_0; // устанавливаем бит 0 для MODER9
либо второй вариант:
Код:
uint32_t tmp = GPIOE->MODER; // читаем значение регистра во временную переменную
tmp &= ~GPIO_MODER_MODE9; // все манипуляции делаем с переменной
tmp |= GPIO_MODER_MODE9_0;
GPIOE->MODER = tmp; // пишем подифицированное значение в регистр

Ну и помигать светиком, если хочется дойти самому, то лучше не смотреть :)
Show L4-Disco, PE8


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помощь новичку STM32L476VG зажечь светодиод
СообщениеДобавлено: 04 июн 2018, 06:43 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2098
Как записывать биты? Я же объяснял выше, как биты описаны в заголовочнике. Они там прямо текстом прописаны - название бита состоит из названия структуры, названия регистра, названия бита и его вариации: GPIO_MODER_MODER9_1.
Числовые же значения в шестнадцатеричной системе записываются с префиксом 0х , это тоже есть в заголовочнике. Виндовый калькулятор выдал HEX-число 4000? записываем его как 0x4000, либо 0х00040000 с добавлением впереди нулей, чисто визуально означающих 4-байтную ширину, у 4-бйтного числа 8 цифр после префикса.

Еще один вариант: использовать запись вида 1 << 5, означающую сдвиг 1 влево на 5 позиций от правой, нулевой позиции бита. Численно равно установленному биту в 5 позиции бита, или числу 0х20.
Например, если надо установить биты 17 и 13, то записать можно вот так:
GPIOE->BSRR = (1<<17) | (1<<13); // это число 0х00022000
а если надо сбросить биты 18 и 19, то можно так:
GPIOE->MODER &= ~(3<<18); // число 3 в двоичной записи = 11, и сдвигаем его на 18 позиций влево от правого края, затем инвертируем его побитово и проводим операцию AND с содержимым регистра. эквивалентно записи GPIOE->MODER &= 0xFFF3FFFF;
Для регистра MODER можно использовать более понятную числовую запись:
GPIOE->MODER &=~(3<<(2 * 9)); // таким образом видно, что число 9 является номером пина. Его можно вывести в #define GREENLED_Pin 9 и далее использовать в подобных формулах.

можно даже дальше пойти:
#define GREENLED_ON GPIOE->BSRR = 1 << GREENLED_Pin
#define GREENLED_OFF GPIOE->BRR = 1 << GREENLED_Pin
и после этого у нас появляется макрос для включения и выключения светодиода, мы его в тексте можем использовать напрямую

while(1)
{
GREENLED_ON;
Delay(1000);
GREENLED_OFF;
Delay(1000);
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помощь новичку STM32L476VG зажечь светодиод
СообщениеДобавлено: 04 июн 2018, 12:08 
Только пришел

Зарегистрирован: 03 июн 2018, 02:32
Сообщения: 10
Откуда: Беларусь
Доброе утро!
Благодарю за ответы и поправки! Вчера был выходной день, рассеивалось внимание, отвлекался, не удалось внимательно прочесть написанные сообщения BusMaster-ом и LonelyWolf-ом .
Сегодня с утра около трех часов провозился, чтобы зажечь светодиод перечисленными выше способами, но то ли я не так записываю, то ли еще что-то. Уже подумал, что что-то не так с отладочной платой. Поискал пример в интернете с STM32L476 и вот что нашел:
Код:
#include "stm32l476xx.h"

int main(void){
   
   // Enable High Speed Internal Clock (HSI = 16 MHz)
  RCC->CR |= ((uint32_t)RCC_CR_HSION);
   
  // wait until HSI is ready
  while ( (RCC->CR & (uint32_t) RCC_CR_HSIRDY) == 0 ) {;}
   
  // Select HSI as system clock source
  RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
  RCC->CFGR |= (uint32_t)RCC_CFGR_SW_HSI;  //01: HSI16 oscillator used as system clock

  // Wait till HSI is used as system clock source
  while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) == 0 ) {;}
 
  // Enable the clock to GPIO Port B   
  RCC->AHB2ENR |= RCC_AHB2ENR_GPIOBEN;   

   // MODE: 00: Input mode, 01: General purpose output mode
  //       10: Alternate function mode, 11: Analog mode (reset state)
  GPIOB->MODER &= ~(0x03<<(2*2)) ;   // Clear bit 13 and bit 12
  GPIOB->MODER |= (1<<4);
      
   GPIOB->ODR |= GPIO_ODR_ODR_2;
  // Dead loop & program hangs here
   while(1);
}

Оказывается с отладочной платой все в порядке. Руки у меня кривые и в голове пусто. Вот фотография платы с рабочим кодом.
Вложение:
0-02-04-894f9d256b3886c633157f8de489b86af572cf94eabb2b02db330e200b927c44_d2287db2.jpg
0-02-04-894f9d256b3886c633157f8de489b86af572cf94eabb2b02db330e200b927c44_d2287db2.jpg [ 76.27 Кб | Просмотров: 1927 ]

Глядя на все написанное в коде, что-то сомневаюсь, что у меня с 4-5 строчками кода что-то бы получилось...
Буду дальше копать, надеюсь, выйдет самостоятельно выполнить задачу.
Большое спасибо за помощь BusMaster и LonelyWolf, возьму во внимание и буду двигаться по вашим подсказкам.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помощь новичку STM32L476VG зажечь светодиод
СообщениеДобавлено: 04 июн 2018, 12:40 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2098
Это вы наполовину фигню, извиняюсь, нашли :))) Вернее, это не фигня, но сделана некошерно она.
Все эти "Enable High Speed Internal Clock (HSI = 16 MHz)" и прочее - на первых порах они и нахрен не нужны. Во-первых, МК всегда стартует на внутреннем осцилляторе, и вам этого хватит. У L476 экономичный осциллятор MSI на 4 МГц. За это отвечают биты SWS в регистре RCC->CFGR, и они после запуска = 0, означая выбранный MSI-осциллятор. МК работать будет хоть и медленно, но верно.
А во-вторых, есть файл system_stm32l4xx.c, он у вас должен уже лежать в папке исходников. Там первым делом запускается ф-ция SystemInit, она обынчно не видна, поскольку запускается до брекпоинта на main(). И вот все эти настройки включения HSE или HSI и переключения на него желательно делать именно там, в функции SystemInit(), дописав в ней вызов ф-ции SetSysClock(), в которой уже и писать переключалки. Просто чтобы эта второстепенная фигня не висела в main и не отвлекала. Ну это так, на будущее.

Чтобы зажечь светодиод, нужно действительно 3 строчки, вот, смотрите (зеленый светодиод слева):
Вложение:
sketch-1528098872848.png
sketch-1528098872848.png [ 185.03 Кб | Просмотров: 1884 ]


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помощь новичку STM32L476VG зажечь светодиод
СообщениеДобавлено: 04 июн 2018, 13:26 
Только пришел

Зарегистрирован: 03 июн 2018, 02:32
Сообщения: 10
Откуда: Беларусь
BusMaster писал(а):
Чтобы зажечь светодиод, нужно действительно 3 строчки, вот, смотрите (зеленый светодиод слева):

Фух-х-х, уже страху навели те непонятные строчки примера из интернета :)
Сегодня посвободнее будет сяду еще поковыряться - спасибо большое за правильно направление!

P.S.: А так,чтобы не доставать с глупыми вопросами самым верным будет мне сесть за изучения с основ, языка Си и документации. Возьмусь за учебники.
Спасибо всем за отзывчивость!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помощь новичку STM32L476VG зажечь светодиод
СообщениеДобавлено: 10 июн 2018, 23:45 
Только пришел

Зарегистрирован: 03 июн 2018, 02:32
Сообщения: 10
Откуда: Беларусь
Доброго времени суток, форумчане!
Сегодня утром ездил к другу со своим миниПК и отладочной платой, чтобы проверить все ли в порядке с тем, что я делаю.
Объяснил как устанавливать биты и по регистрам GPIO. Во время написания программы объяснил мне некоторые моменты. Светодиоды загорались, мигали поочередно и с разной частотой.
Уже вечером по полученным знаниям решил закрепить и написал программу. Вот что получилось в итоге:
Код:
#include "stm32l476xx.h"
int main (void){
     RCC->AHB2ENR |= RCC_AHB2ENR_GPIOBEN; // Включаем тактирование шины порт PB2
     RCC->AHB2ENR |= RCC_AHB2ENR_GPIOEEN; // Включаем тактирование шины порт PE8
     GPIOB->MODER &= 0xFFFFFFCF; // Сброс бита MODER2
     GPIOB->MODER |=0x10; // Установка битов 01 для MODER2
     GPIOE->MODER &= 0xFFFCFFFF; // Сброс бита MODER8
     GPIOE->MODER |= 0x10000; // Установка битов 01 для MODER8
          GPIOB->ODR |= 0x4; // Установка 1 выход GPIOB
     GPIOE->ODR |= 0x100; // Установка 1 выход GPIOE
         while(1)
      {
      }
}

Зажег оба светодиода (красный и зеленый). Изначально был верным подход, но из-за неточностей и неправильности установки бита в регистры, не выходило ничего.
Можно сказать, что "Хеллоу, Ворлд!" написан :)
Благодарю всех кто откликнулся по моей теме! Буду далее изучать и продвигаться. Всем успехов в своих проектах!
Вложение:
0-02-04-545dff6e9e1cba55ab4aaa02069af0369f8731b7b17f66b68c2c29b896759e03_3a88a1df.jpg
0-02-04-545dff6e9e1cba55ab4aaa02069af0369f8731b7b17f66b68c2c29b896759e03_3a88a1df.jpg [ 76.02 Кб | Просмотров: 1594 ]


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помощь новичку STM32L476VG зажечь светодиод
СообщениеДобавлено: 12 июн 2018, 18:23 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2098
Во как... нуууу... мы конечно все рады, раз что-то получается уже.. :))
Кстати, вчера я у себя в столе наткнулся на эту плату STM32F476 Discovery, до которой руки так и не доходили. Она в то время мне не понравилась по своей конструкции. Ну а раз тут топикстартер поднял эту темку, я чето тоже решил, мол типа чем я то хуже, думаю, хватит уже этой плате без дела лежать.

Вопсчем, накидал небольшой тестовый проектик. Сильно не усложнял, чтобы топикстартеру с первых разов мозг не порвать, старался попонятнее... Кароче что есть:
- LCD с 14-сегментными шрифтами (цифры, англ.буквы, несколько символов),
- RTC с простым выводом текущего времени и даты,
- джойстик с простым опросом,
- минимальный SystemInit для MSI 4 МГц или PLL от MSI

Для начала топикстартеру хватит.
Файл startup_stm32l476xx.s нужно использовать тот, который предлагает ваша IDE. Например, в Кейле он выглядит по-другому.


Вложения:
L476Discovery_TestLCD.zip [214.88 Кб]
Скачиваний: 15
DSC_1119.jpg
DSC_1119.jpg [ 188.11 Кб | Просмотров: 1398 ]
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помощь новичку STM32L476VG зажечь светодиод
СообщениеДобавлено: 12 июн 2018, 20:29 
Только пришел

Зарегистрирован: 05 дек 2017, 18:17
Сообщения: 28
[quote="Mack-L"]
Доброго времени суток, форумчане!
Код:
#include "stm32l476xx.h"
int main (void){
     RCC->AHB2ENR |= RCC_AHB2ENR_GPIOBEN; // Включаем тактирование шины порт PB2
     RCC->AHB2ENR |= RCC_AHB2ENR_GPIOEEN; // Включаем тактирование шины порт PE8
     GPIOB->MODER &= 0xFFFFFFCF; // Сброс бита MODER2
     GPIOB->MODER |=0x10; // Установка битов 01 для MODER2
     GPIOE->MODER &= 0xFFFCFFFF; // Сброс бита MODER8
     GPIOE->MODER |= 0x10000; // Установка битов 01 для MODER8
          GPIOB->ODR |= 0x4; // Установка 1 выход GPIOB
     GPIOE->ODR |= 0x100; // Установка 1 выход GPIOE
         while(1)
      {
      }
}

[/qoute]
Так лучше не делать. Уже через пол часа не вспомнить, что такое 0xFFFFFFCF.
В stm32l476xx.h есть специальные дефайны для этого.
скажем ваш случай, сброс бита MODER2 порта GPOIB

GPIOB->MODER &= ~GPIO_MODER_MODE2; // Сброс бита MODER2
GPIOB->MODER |= GPIO_MODER_MODE2_0; // Установка битов 01 для MODER2
GPIOE->MODER &= ~GPIO_MODER_MODE8; // Сброс бита MODER8
GPIOE->MODER |= GPIO_MODER_MODE8_0; // Установка битов 01 для MODER8
GPIOB->ODR |= GPIO_ODR_OD2; // Установка 1 выход GPIOB
GPIOE->ODR |= GPIO_ODR_OD8; // Установка 1 выход GPIOE

Что такое GPIO_MODER_MODE2 вы можете посмотреть нажав правой кнопкой на этом дефайне и выбрав "Go To Definition of GPIO_MODER_MODE2". Там видно, что для MODE2, т.е. для второго пина порта, есть следующие дефайны:
Код:
#define GPIO_MODER_MODE2_Pos             (4U)                                 
#define GPIO_MODER_MODE2_Msk             (0x3U << GPIO_MODER_MODE2_Pos)        /*!< 0x00000030 */
#define GPIO_MODER_MODE2                 GPIO_MODER_MODE2_Msk                 
#define GPIO_MODER_MODE2_0               (0x1U << GPIO_MODER_MODE2_Pos)        /*!< 0x00000010 */
#define GPIO_MODER_MODE2_1               (0x2U << GPIO_MODER_MODE2_Pos)        /*!< 0x00000020 */


GPIO_MODER_MODE2 это на самом деле GPIO_MODER_MODE2_Msk, а GPIO_MODER_MODE2_Msk это 0x3U, т.е. "11" сдвинутые на 4.
Логика этих дефайнов (да и остальных тоже) такая:
GPIO_MODER_MODE2 - установлены все биты
GPIO_MODER_MODE2_0 - установлен 0-вой бит
GPIO_MODER_MODE2_1 - установлен 1-ый бит.

Соответственно если вам надо установить 1-вый бит выделаете:
GPIOB->MODER |= GPIO_MODER_MODE2_1;

*_Pos дефайны удобно использовать при назначении альтернативной функции пину.
Скажем назначение альтернативной функции 12 на PC8:
GPIOC->AFR[1] |= (12 << GPIO_AFRH_AFSEL8_Pos);

Использование дефайнов делает код более наглядным и понятным.

Keil кстати подсказывает вам варианты, когда вы набираете. Если тормозит и не подсказывает, то, например набрав "GPIO" можно нажать ctrl+space и посмотреть варианты продолжения.
Какие-то регистры там сделаны не совсем очевидно (а какие-то даже совсем не очевидно :), но обычно можно разобраться. Набираете начало дефайна, потом выбираете какой-нибудь, из нужного вам регистра, и делаете "Go to definition". Дефайны кучно лежат, по назначению сгруппированы, поэтому можно сразу понять логику и назначение.

Ну и уже в качестве оптимизации, лучше не в ODR писать, а BSRR использовать. Просто быстрее работает.

GPIOB->BSRR |= GPIO_BSRR_BS2; // Установка 1 выход GPIOB
GPIOE->BSRR |= GPIO_BSRR_BS8; // Установка 1 выход GPIOE

Для снятия соответственно:
GPIOB->BSRR |= GPIO_BSRR_BR2; // Установка 0 выход GPIOB
GPIOE->BSRR |= GPIO_BSRR_BR8; // Установка 0 выход GPIOE

Логика:
GPIO_BSRR_BS2 Set
GPIO_BSRR_BR2 Reset


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помощь новичку STM32L476VG зажечь светодиод
СообщениеДобавлено: 13 июн 2018, 12:59 
Только пришел

Зарегистрирован: 03 июн 2018, 02:32
Сообщения: 10
Откуда: Беларусь
Sergey_spb писал(а):
Так лучше не делать. Уже через пол часа не вспомнить, что такое 0xFFFFFFCF.

Спасибо, все получилось! Для меня было раньше за гранью моего понимания установка битов именно дефайнами. В голове каша, код неправильный, соответственно не так биты установлены. Теперь потихоньку дошел и все получается со светодиодами. Благодарю за полное и доходчивое объяснение! Думаю, любой друго новичок наткнувшись на данную тему сможет так же разобраться с этим! :)
Код:
#include "stm32l476xx.h"
void Delay(uint32_t pause)
{
    uint32_t i;
    for (i=0; i< pause; i++) {};
}
int main(void){

    RCC->AHB2ENR |= RCC_AHB2ENR_GPIOBEN;
    RCC->AHB2ENR |= RCC_AHB2ENR_GPIOEEN;

    GPIOB->MODER &= ~GPIO_MODER_MODE2;
    GPIOB->MODER |= GPIO_MODER_MODE2_0;
    GPIOE->MODER &= ~GPIO_MODER_MODE8;
    GPIOE->MODER |= GPIO_MODER_MODE8_0;
   
    GPIOB->ODR |= GPIO_ODR_OD2;
    GPIOE->ODR |= GPIO_ODR_OD8;
      while(1)
      {   
      GPIOB->BSRR |= GPIO_BSRR_BS2;
      Delay(1000000);
      GPIOB->BRR |= GPIO_BRR_BR2;
      Delay (1000000);
      GPIOE->BSRR |= GPIO_BSRR_BS8;
      Delay(1000000);
      GPIOE->BRR |= GPIO_BRR_BR8;
      Delay (1000000);

      }
}


Последний раз редактировалось Mack-L 26 июн 2018, 20:00, всего редактировалось 2 раз(а).

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помощь новичку STM32L476VG зажечь светодиод
СообщениеДобавлено: 13 июн 2018, 13:04 
Старожил

Зарегистрирован: 11 сен 2012, 11:19
Сообщения: 4804
Цитата:
GPIOB->BSRR |= GPIO_BSRR_BS2; // Установка 1 выход GPIOB
GPIOE->BSRR |= GPIO_BSRR_BS8; // Установка 1 выход GPIOE

Для снятия соответственно:
GPIOB->BSRR |= GPIO_BSRR_BR2; // Установка 0 выход GPIOB
GPIOE->BSRR |= GPIO_BSRR_BR8; // Установка 0 выход GPIOE


И все же:
Код:
GPIOB->BSRR = GPIO_BSRR_BS2; // Установка 1 выход GPIOB
GPIOE->BSRR = GPIO_BSRR_BS8; // Установка 1 выход GPIOE



GPIOB->BSRR = GPIO_BSRR_BR2; // Установка 0 выход GPIOB
GPIOE->BSRR = GPIO_BSRR_BR8; // Установка 0 выход GPIOE


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помощь новичку STM32L476VG зажечь светодиод
СообщениеДобавлено: 13 июн 2018, 13:23 
Только пришел

Зарегистрирован: 03 июн 2018, 02:32
Сообщения: 10
Откуда: Беларусь
BusMaster писал(а):
Во как... нуууу... мы конечно все рады, раз что-то получается уже.. :)) Вопсчем, накидал небольшой тестовый проектик

Ничего ж себе у Вас там просто так что-то валяется :) Тут вожделенным было хоть какая-то отладочная плата)))
Спасибо большое за труды, что поделились своим проектом. Насчет того, что щадите мой мозг, тут Вы правы. Не сказжу, что я сильно смышленый, дохожу понемногу, уложить в голову нужно и понять, так что на перспективу очень полезный архив!
Часы хотелось бы очень сделать, а сейчас хочу заняться назначением кнопок (задействовать джостик) по режимам работы светодиодов.
Вы очень помогли с этим!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помощь новичку STM32L476VG зажечь светодиод
СообщениеДобавлено: 13 июн 2018, 14:33 
Только пришел

Зарегистрирован: 05 дек 2017, 18:17
Сообщения: 28
dosikus_2 писал(а):
Цитата:
GPIOB->BSRR |= GPIO_BSRR_BS2; // Установка 1 выход GPIOB
GPIOE->BSRR |= GPIO_BSRR_BS8; // Установка 1 выход GPIOE

Для снятия соответственно:
GPIOB->BSRR |= GPIO_BSRR_BR2; // Установка 0 выход GPIOB
GPIOE->BSRR |= GPIO_BSRR_BR8; // Установка 0 выход GPIOE


И все же:
Код:
GPIOB->BSRR = GPIO_BSRR_BS2; // Установка 1 выход GPIOB
GPIOE->BSRR = GPIO_BSRR_BS8; // Установка 1 выход GPIOE

GPIOB->BSRR = GPIO_BSRR_BR2; // Установка 0 выход GPIOB
GPIOE->BSRR = GPIO_BSRR_BR8; // Установка 0 выход GPIOE


Да, конечно. Иначе весь смысл теряется.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помощь новичку STM32L476VG зажечь светодиод
СообщениеДобавлено: 13 июн 2018, 15:14 
Старожил

Зарегистрирован: 26 ноя 2012, 10:28
Сообщения: 2527
Откуда: КЧР, поселок Нижний Архыз
Не, ну можно и ODR XOR'ить...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помощь новичку STM32L476VG зажечь светодиод
СообщениеДобавлено: 14 июн 2018, 21:36 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2098
Mack-L писал(а):
, а сейчас хочу заняться назначением кнопок (задействовать джостик) по режимам работы светодиодов.

Окей. Давайте тогда сделаем кнопки джойстика. Допустим, будем делать простой опрос входов от джойстика через заданные промежутки времени и распознавание действий. Чтобы отсчитывать интервалы, возьмем системный таймер SysTick, как самый простой. Он обычно используется для задания системных интервалов времени, подробно описан в программинг-мануале (документ PM0214). У этого таймера есть прерывание по обновлению цикла счета - особый режим работы МК, когда основное выполнение программы прерывается запросом от какого-либо модуля (в данном случае от SysTick) и начинает выполняться программа, описанная в обработчике прерывания. Обработчик прерывания в Си-шной записи представляет собой обычную сишную функцию с жестко фиксированным именем (в случае системного таймера - имя SysTick_Handler), не имеющую параметров и возвращаемых значени - void SysTick_Handler(void). По окончании работы кода обработчика возобновляется выполнение программы ровно с того места, на котором оно было прервано.
Запросы прерывания от Systick идут каждый раз, когда возобновляется цикл счета таймера, то есть когда его счетчик переходит через 0. Таймер имеет 24-битный счетчик с регистром перезагрузки. Счет ведется от значения регистра перезагрузки вниз до 0.
Системный таймер настраивается и запускается ф-цией SysTick_Config, она уже написана в CMSIS. Аргумент ф-ции - число, записываемое в регистр перезагрузки, определяет период полного цикла счета таймера, то есть, период (частоту) прерываний от SysTick.
В данном случае опрос джойстика будет происходить с частотой 100 Гц.

Для лучшего понимания написанного кода надо прочесть главу "Структуры, объединения и определяемые пользователем типы" языка Си: http://www.c-cpp.ru/books/struktury-obe ... telem-tipy
а так же раздел "Битовые поля" - http://www.c-cpp.ru/books/bitovye-polya
Так же в коде используются макросы REDLED_ON, GREENLED_ON, GREENLED_OFF, GREENLED_CHECK и т.п., представляющие собой простые текстовые замены:
#define REDLED_ON GPIOB->BSRR = 1<<2
#define REDLED_OFF GPIOB->BRR = 1<<2
#define REDLED_CHECK (READ_BIT(GPIOB->ODR, 1<<2))

Для понимания - прочесть http://www.c-cpp.ru/books/define

Вложение:
L476Discovery_Joystick_LED.zip [237.39 Кб]
Скачиваний: 12


Ну или то же самое, только без наворотов в виде структур и макросов, и в одном файле:
Вложение:
L476Discovery_Joystick_LED_simple.zip [232.53 Кб]
Скачиваний: 11


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помощь новичку STM32L476VG зажечь светодиод
СообщениеДобавлено: 15 июн 2018, 12:36 
Старожил
Аватара пользователя

Зарегистрирован: 23 сен 2012, 20:35
Сообщения: 1897
BusMaster писал(а):
Обработчик прерывания в Си-шной записи представляет собой обычную сишную функцию с жестко фиксированным именем (в случае системного таймера - имя SysTick_Handler), не имеющую параметров и возвращаемых значени - void SysTick_Handler(void).

Тут, пожалуй, полезно будет заметить, что имя этого обработчика просто должно совпадать с именем точки входа описанной в таблице векторов (которая, в свою очередь, описана в коде стартапа и является частью кода прошивки). А то формулировка "жестко фиксированное имя" предполагает, что это какая-то секретная магия с участием компилятора и/или системных библиотек и что ни в коем случае его менять нельзя. Хотя на самом деле это не так и имя изменить можно, если понимать взаимосвязи.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помощь новичку STM32L476VG зажечь светодиод
СообщениеДобавлено: 03 июл 2018, 00:23 
Только пришел

Зарегистрирован: 03 июн 2018, 02:32
Сообщения: 10
Откуда: Беларусь
Здравствуйте, форумчане!
На днях удалось с нескольких попыток реализовать обработку нажатия кнопки. При нажатии загорается светодиод, отпускаешь - тухнет.
По примерам из интернета набросал код, но он не работал. Крутил-вертел применительно к своей отладочной платe - не получалось.
Обратился за помощью к BusMaster-у и общими усилиями нашли несколько ошибок (еще раз спасибо за помощь!).
Выкладываю простую реализацию обработки кнопки с загоранием светодиода:
Код:
#include "stm32l476xx.h"

int main(void){
   RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN; //Включение тактирования порта A
   RCC->AHB2ENR |= RCC_AHB2ENR_GPIOBEN; //Включение тактирования порта В
   
   GPIOA->MODER &= ~GPIO_MODER_MODE1; //Инициализация порта PA1 на ввод
   GPIOB->MODER &= ~GPIO_MODER_MODE2; //сброс бита светодиод PB2
   GPIOB->MODER |= GPIO_MODER_MODE2_0; // установка на выход PB2
   GPIOA->PUPDR |= GPIO_PUPDR_PUPD1_1; // для устранения наводок на высокоомные входы включаем pull-down
   
  while(1){   
  if (GPIOA->IDR & GPIO_IDR_IDR_1)  //Условие - если кнопка нажата то
{
  GPIOB->BSRR = GPIO_BSRR_BS2; //включить светодиод PB2
}
  else // если кнопка не нажата то
{
  GPIOB->BSRR = GPIO_BSRR_BR2; //выключить светодиод PB2
}   
}
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Помощь новичку STM32L476VG зажечь светодиод
СообщениеДобавлено: 03 июл 2018, 00:49 
Старожил
Аватара пользователя

Зарегистрирован: 18 май 2013, 20:43
Сообщения: 3480
Откуда: Кемеровская область, Киселевск
--

_________________
RADIOWOLF.RU


Последний раз редактировалось Oxford 03 июл 2018, 14:48, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 78 ]  На страницу 1, 2, 3, 4  След.

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB