Освоение азов программирования, на архитектуре Stm32 Cortex

Всё о ЧПУ (CNC). Компоненты, станки, программы.
Малорос
Реальное имя: Владимир
Откуда: Москва

Освоение азов программирования, на архитектуре Stm32 Cortex

Сообщение Малорос » 25 дек 2016, 20:19

++ - означает увеличить значение переменной на 1. пример: index = 0; потом пишем ++index. И в этой переменной будет уже 1.
-- - тоже самое только уменьшить на 1. пример: index = 0; --index; Теперь в index будет число -1.
А вот ! используется обычно в связке !=. Это означает НЕ РАВНО. Т.е. что-то НЕ РАВНО чему-то.

Аватара пользователя
chkmatulla
Реальное имя: Walter
Откуда: Schwedt

Освоение азов программирования, на архитектуре Stm32 Cortex

Сообщение chkmatulla » 25 дек 2016, 20:23

Например, GPIOG->ODR |= GPIO_Pin_14; Понимаю что, 14 ножка назначается выводом но, не понимаю, почему так сложно ?

Отправлено спустя 49 секунд:
Ладно, на сегодня хватит ! Крыша уже дымится.
Секс не предлагать. Могу согласиться.

Малорос
Реальное имя: Владимир
Откуда: Москва

Освоение азов программирования, на архитектуре Stm32 Cortex

Сообщение Малорос » 25 дек 2016, 20:28

Это вариант кстате один из самых коротких. Так вы указывает действительно конкретную ногу. Есть вариант с использованием библиотечной функции, ну например: GPIO_SetBits( GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin ).
Где GPIOx - имя порта, например GPIOA, а в GPIO_Pin указан номер ноги или ног. Эта функция для установки "1" на указанных ножках. Есть и обратная функция - GPIO_ResetBits. У неё параметры те же, только устанавливает лог. "0".

Отправлено спустя 34 секунды:
Ок. До скорых встреч. :hi:

Аватара пользователя
Автор темы
T-Duke

Освоение азов программирования, на архитектуре Stm32 Cortex

Сообщение T-Duke » 25 дек 2016, 21:02

Когда мы работаем с портами, и записываем что-то в регистр данных порта, то данные сначала попадают в теневой регистр. Непосредственно на ножки порта, данные попадают строго по такту дирижера. Не раньше и не позже. Если данные попали в теневой регистр, например между тактами, то они ждут в теневом регистре, пока не произойдет новый такт и после этого переносятся на ножки порта. Частота этих тактов и задает максимальную частоту дергания ножками порта. В библиотеках определены разные константы - 2МГц, 25МГц, 50МГц, 100МГц. Но на самом деле 100МГц не точно соответствует реальной частоте. Точно, это число равно половине частоты тактирования ядра. Если частота ядра 168 МГц, то максимальная частота дергания ножками 84МГц. И только если ядро разогнать до 200МГц, только тогда частота будет точно 100МГц. Кстати 407-е кортексы разгоняются со штатных 168МГц до 250МГц.

chkmatulla писал(а):Источник цитаты Попробовал сейчас, правой кнопкой... Ничего не открыла, переместила на {GPIO_InitTypeDef GPIO_InitStructure; //пустая структура настройки порта
Значит что-то не так сделал. Нужно щелкнуть на на константу GPIO_Speed_100MHz, так чтобы на ней замигал курсор. И не обязательно потом правой кнопкой, нажимаем F12 и переходим к определению.

Малорос писал(а):Источник цитаты пример: index = 0; потом пишем ++index

Тут есть подводные камни и процедурально есть разница между ++index и index++. Я рекомендую пользоваться вариантом index++. Иначе в сложных программах можно потом долго чесать репу выискивая блоху.

chkmatulla писал(а):Источник цитаты Например, GPIOG->ODR |= GPIO_Pin_14; Понимаю что, 14 ножка назначается выводом но, не понимаю, почему так сложно ?

А что ты хотел? Там вообще работа с битовой маской. Использована функция поразрядной операции ИЛИ со содержимым порта и битовой маской. Содержимое регистра данных порта объединяется по функции ИЛИ с битовой маской хранящейся в GPIO_Pin_14 и записывается обратно в регистр данных порта.

Операцию можно более полно расписать как:
GPIOG->ODR = GPIOG->ODR | GPIO_Pin_14;

Где символ | обозначает операцию поразрядного ИЛИ.

Но сокращенная форма записи позволяет не использовать дважды имя одной и той же переменной. Поэтому все сокращается до:
GPIOG->ODR |= GPIO_Pin_14;

Кстати в одной команде можно объединять несколько битовых масок. Можно сразу два диода включить таким кодом:

GPIOG->ODR |= (GPIO_Pin_13 | GPIO_Pin_14);
Technology is insignificant comparing to the power of the Force.

Аватара пользователя
Автор темы
T-Duke

Освоение азов программирования, на архитектуре Stm32 Cortex

Сообщение T-Duke » 25 дек 2016, 21:14

Малорос писал(а):Источник цитаты Отличный девайс вы выбрали для экспериментов. Там есть где развернуться. STM классные процы.
Если честно немного слабоват. Я предпочитаю плату на которой экран побольше, разрешением 480х272 и SDRAM на 32Мб. Но у Вальтера такой нет, поэтому пришлось пока штатную дискавери пробовать. А вообще думаю под Рождество перейти на плату со седьмым кортексом. Он в 2 раза шустрее по производительности, чем четвертые кортексы.
Technology is insignificant comparing to the power of the Force.

User_612

Освоение азов программирования, на архитектуре Stm32 Cortex

Сообщение User_612 » 25 дек 2016, 22:12

= неравно, == равно

Аватара пользователя
Автор темы
T-Duke

Освоение азов программирования, на архитектуре Stm32 Cortex

Сообщение T-Duke » 25 дек 2016, 22:34

Алекс50 писал(а):Источник цитаты = неравно, == равно

Неверно. Это присваивание и сравнение.

Неравно !=, равно ==
Technology is insignificant comparing to the power of the Force.

User_612

Освоение азов программирования, на архитектуре Stm32 Cortex

Сообщение User_612 » 26 дек 2016, 03:07

Забыл про восклицательный знак.......

Отправлено спустя 4 минуты 57 секунд:
a=b=c=d=100;

Аватара пользователя
chkmatulla
Реальное имя: Walter
Откуда: Schwedt

Освоение азов программирования, на архитектуре Stm32 Cortex

Сообщение chkmatulla » 26 дек 2016, 18:59

T-Duke писал(а):Источник цитаты Использована функция поразрядной операции ИЛИ со содержимым порта и битовой маской. Содержимое регистра данных порта объединяется по функции ИЛИ с битовой маской хранящейся в GPIO_Pin_14 и записывается обратно в регистр данных порта.

А можно разжевать это ? GPIO, если я правильно понял, порт ввода-вывода, общего назначения ? А вот что входит в понятие порт ? Все 32 бита ? Или только один бит ? По логике, на 14 ножке может быть только один бит или одна линия ( электрическая ). И как тут применять маску ? С одним битом- то ? Регистр данных порта... Это что- то отдельное от самого порта ? Как всё сложно...
Секс не предлагать. Могу согласиться.

Аватара пользователя
Автор темы
T-Duke

Освоение азов программирования, на архитектуре Stm32 Cortex

Сообщение T-Duke » 27 дек 2016, 12:14

Порты в стм32 16битные. Если выведешь в порт 32битное число, то только первая половина имеет значение.

А вот маски это же самая основа. Блин, Вальтер ты совсем нулевый :crazy:

Ладно. Порт с точки зрения программиста это регистр на который завязаны 16 ножек. Выдав в порт некоторое число, можно зажечь группу ножек, вернее диодов, например все, или несколько или потушить все.

Если ты выведешь в порт двоичное число в котором во всех разрядах единицы 0b1111111111111111, ты включишь одновременно все 16 ножек. Если выдашь 0b0000000000000000 то на всех ножках будут нули, то есть отключили все 16 ножек порта. Двоичных чисел в СИ нет, моя форма записи может быть в принципе реализована через макросы, но это геморр. Поэтому двоичные числа переводим или в десятичные, или в 16-ричные.

Двоичное число 0b1111111111111111 в десятичном представлении 65535, в шестнадцатеричном 0xFFFF. Если хочешь управлять только одной конкретной ножкой, для нее нужно создать битовую маску - число, которое в двоичном представлении имеет единицу в нужной нам позиции.

Например для нулевой ножки порта битовая маска: 0b0000000000000001 или 1 в десятичном представлении, или 0x0001 в шестнадцатеричном.
Для первой ножки порта битовая маска уже такая: 0b0000000000000010 или 2 в десятичном представлении, или 0x0002 в шестнадцатеричном.
Для второй ножки порта битовая маска составляет: 0b0000000000000100 или 4 в десятичном представлении, или 0x0004 в шестнадцатеричном.
И так далее:

Код: Выделить всё

3  - 0b0000000000001000 - 08 - 0x0008
4  - 0b0000000000010000 - 16 - 0x0010
5  - 0b0000000000100000 - 32 - 0x0020
6  - 0b0000000001000000 - 64 - 0x0030
.
.
14 - 0b0100000000000000 - 16384 - 0x4000
15 - 0b1000000000000000 - 32768 - 0x8000


Такие маски определены в библиотеках под именами GPIO_Pin_XX.

Как пользоваться маской.

Если мы хотим включить только выбранную ножку и погасить принудительно все остальные, то выводим прямо в порт эту маску. Например команда GPIOG->ODR = 0x0008, включит третью ножку порта и принудительно выключит все остальные.

Если же нужно оперировать именно выделенной ножкой не затрагивая остальные, тогда нельзя прямо в порт выводить маску. Нужно провести поразрядное или, содержимого порта и нужной нам битовой маски.

Например у нас в порту уже включены ножки скажем 7-я и 14-я. Мы же дополнительно хотим включить 3-ю ножку. Состояние порта в двоичном виде 0b0100000010000000. Чтобы не стереть состояние порта и включить третью ножку, нужно не записывать маску в порт напрямую, а объединять ее операцией ИЛИ со содержимым порта: GPIOG->ODR |= 0x0008. В этом случае произойдет объединения содержимого порта и маски.

Код: Выделить всё

0b0100000010000000  ;содержимое порта порязрядно с помощью операции
0b0000000000001000  ;ИЛИ объединяется с этой маской.
------------------
0b0100000010001000  ;и получаем в результате включенными все нужные биты порта


Операция ИЛИ хороша тем, что изменяет только те биты в которых в маске стоят единицы. Если в маске в каких-то позициях стоят нули, то в результате операции ИЛИ нули не обнулят биты результата. Операция ИЛИ может изменить значение бита с 0 в 1-цу. А вот из 1-цы в ноль не может. Поэтому операцией ИЛИ можно легко оперировать конкретными ножками (включать их) не затрагивая остальные.


А вот выключать ножки нужно наоборот операцией И и инвертированной маской. Но пусть об этом кто-то другой напишет, утомляют меня банальные вещи. Советчиков здесь много бродило, могли бы и поработать чуток :crazy:
Technology is insignificant comparing to the power of the Force.


Вернуться в «Системы ЧПУ»