Easyelectronics.ru

Электроника для всех
Текущее время: 19 сен 2018, 20:08

Часовой пояс: 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 Кб | Просмотров: 2648 ]
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: 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
Сообщения: 2247
...и для зажигания вручную светодиода операции с AFR не нужны. AFR - это Alternate Function Register, управляет назначением на пин альтернативных функций, таких как SPI, UART и пр. По умолчанию после сброса он = 0х00000000, то есть выбрана базовая функция пина - непосредственное управление.
Зато нам нужен регистр MODER - port MODE Register. Согласно таблице:
Вложение:
Без-имени-1.png
Без-имени-1.png [ 8.91 Кб | Просмотров: 2620 ]


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


Поэтому, чтобы включить режим 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 Кб | Просмотров: 2616 ]

для установки выхода в 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
Сообщения: 963
http://easyelectronics.ru/arm-uchebnyj- ... -gpio.html


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

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


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

Зарегистрирован: 08 авг 2013, 09:43
Сообщения: 963
Это понятно, вы же расписали как надо на 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 Кб | Просмотров: 2155 ]
2.jpg
2.jpg [ 202.23 Кб | Просмотров: 2155 ]
3.jpg
3.jpg [ 181.69 Кб | Просмотров: 2155 ]
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: 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
Сообщения: 2247
Как записывать биты? Я же объяснял выше, как биты описаны в заголовочнике. Они там прямо текстом прописаны - название бита состоит из названия структуры, названия регистра, названия бита и его вариации: 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 Кб | Просмотров: 1998 ]

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


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

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2247
Это вы наполовину фигню, извиняюсь, нашли :))) Вернее, это не фигня, но сделана некошерно она.
Все эти "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 Кб | Просмотров: 1955 ]


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: 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 Кб | Просмотров: 1665 ]


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

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

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

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


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

Зарегистрирован: 05 дек 2017, 18:17
Сообщения: 32
[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
Сообщения: 4977
Цитата:
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
Сообщения: 32
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
Сообщения: 2674
Откуда: КЧР, поселок Нижний Архыз
Не, ну можно и ODR XOR'ить...


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

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2247
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 Кб]
Скачиваний: 13


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


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

Зарегистрирован: 23 сен 2012, 20:35
Сообщения: 2172
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
Сообщения: 3592
Откуда: Кемеровская область, Киселевск
--

_________________
RADIOWOLF.RU


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

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

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


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

Сейчас этот форум просматривают: hd44780, vasiliuz


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

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

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